Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:10:35

0001 #include "event_display_maker.h"
0002 
0003 #include <fun4all/Fun4AllReturnCodes.h>
0004 
0005 #include <trackbase/InttDefs.h>              // for getLadderPhiId, getLad...
0006 #include <trackbase/MvtxDefs.h>              // for getChipId, getStaveId
0007 #include <trackbase/TpcDefs.h>               // for getSectorId, getSide
0008 #include <trackbase/TrkrDefs.h>              // for getLayer, getTrkrId
0009 
0010 #include <phool/getClass.h>
0011 #include <phool/PHCompositeNode.h>
0012 #include <phool/recoConsts.h>
0013 
0014 #include <TDatabasePDG.h>
0015 
0016 #include <nlohmann/json.hpp>
0017 
0018 using json = nlohmann::json;
0019 
0020 float vertex[3];
0021 
0022 //____________________________________________________________________________..
0023 event_display_maker::event_display_maker(const std::string &name)
0024  : SubsysReco(name)
0025  , m_kfparticleContainerName("reconstructedParticles")
0026 {
0027 }
0028 
0029 //____________________________________________________________________________..
0030 event_display_maker::~event_display_maker()
0031 {
0032 }
0033 
0034 //____________________________________________________________________________..
0035 int event_display_maker::Init(PHCompositeNode *topNode)
0036 {
0037   load_nodes(topNode);
0038 
0039   triggeranalyzer = new TriggerAnalyzer();
0040 
0041   recoConsts *rc = recoConsts::instance();
0042   m_runNumber = rc->get_IntFlag("RUNNUMBER");
0043 
0044   m_run_date = getDate();
0045 
0046   return Fun4AllReturnCodes::EVENT_OK;
0047 }
0048 
0049 //____________________________________________________________________________..
0050 int event_display_maker::process_event(PHCompositeNode *topNode)
0051 {
0052   if (counter >= m_max_displays) return Fun4AllReturnCodes::EVENT_OK; //Made the max number of displays
0053 
0054   load_nodes(topNode);
0055   std::string trackableParticles[] = {"e-", "mu-", "pi+", "K+", "proton"};
0056 
0057   for (auto &vtx_iter : *m_vertexMap)
0058   {
0059     if (counter >= m_max_displays) break; //Made the max number of displays
0060 
0061     kfp_daughters.clear();
0062     intermediates.clear();
0063     trigger_tracks.clear();
0064     all_tracks.clear();
0065   
0066     m_vertex = vtx_iter.second;
0067 
0068     for (KFParticle_Container::Iter kfp_iter = m_kfp_container->begin(); kfp_iter != m_kfp_container->end(); ++kfp_iter)
0069     {
0070       KFParticle *myParticle = kfp_iter->second;
0071       std::string thisParticle = getParticleName(abs(myParticle->GetPDG())); //Only care about trackable particles
0072 
0073       if (thisParticle == m_mother_name)
0074       {
0075         mother = myParticle;
0076         vertex[0] = mother->GetX();
0077         vertex[1] = mother->GetY();
0078         vertex[2] = mother->GetZ();
0079 
0080         if (!isInRange(m_min_mass, mother->GetMass(), m_max_mass))
0081         {
0082           return Fun4AllReturnCodes::EVENT_OK;
0083         }
0084       }
0085 
0086       if (std::find(std::begin(m_intermerdiate_names), std::end(m_intermerdiate_names), thisParticle) != std::end(m_intermerdiate_names))
0087       {
0088         intermediates.push_back(myParticle);
0089       }
0090 
0091       if (std::find(std::begin(trackableParticles), std::end(trackableParticles), thisParticle) != std::end(trackableParticles))
0092       {
0093         m_track = getTrack(myParticle->Id(), m_trackMap);
0094 
0095         //If we want calo information then we can only use bunch crossing 0 candidates
0096         //if (loadCalos && (hasEMCal || hasIHCal || hasOHCal) && m_track->get_crossing() != 0) continue;
0097 
0098         if (m_track->get_crossing() != m_vertex->get_beam_crossing()) continue; //Track isnt from same crossing (need continue to account for mother)
0099 
0100         kfp_daughters.push_back(myParticle);
0101         trigger_tracks.push_back(m_track);
0102       }
0103     }
0104 
0105     if (kfp_daughters.size() < m_number_of_daughters) continue; //This could be risky
0106     //Get all tracks associated to this vertex
0107     for (SvtxVertex::TrackIter all_track_iter =  m_vertex->begin_tracks(); all_track_iter != m_vertex->end_tracks(); ++all_track_iter)
0108     {
0109       m_track = m_trackMap->get(*all_track_iter);
0110       all_tracks.push_back(m_track);
0111     }
0112 
0113     triggeranalyzer->decodeTriggers(topNode);
0114 
0115     //Now fill the json file
0116     json data;
0117 
0118     uint64_t m_bco = gl1packet->lValue(0, "BCO") + trigger_tracks[0]->get_crossing();
0119 
0120     //Check if we have a list of BCOs we want a plot for, and this is one of them
0121     if (m_bco_list.size() != 0 && std::find(std::begin(m_bco_list), std::end(m_bco_list), m_bco) == std::end(m_bco_list)) continue;
0122 
0123     std::string date_run_stamp = m_run_date + ", Run " + std::to_string(m_runNumber);
0124     std::string bco_stamp = "BCO: " + std::to_string(m_bco);
0125 
0126     data[eventName]["evtid"] = 1;
0127     data[eventName]["runid"] = m_runNumber;
0128     data[eventName]["type"] = "Collision";
0129     data[eventName]["s_nn"] = 0;
0130     data[eventName]["B"] = 1.38;
0131     data[eventName]["pv"] = {m_vertex->get_x(), m_vertex->get_y(), m_vertex->get_z()};
0132 
0133     if (m_approved)
0134     {
0135       data[eventName]["runstats"] = {"sPHENIX Tracking", date_run_stamp, m_decay_tag};
0136     }
0137     else
0138     {
0139       data[eventName]["runstats"] = {"sPHENIX Internal", date_run_stamp, bco_stamp, m_decay_tag};
0140     }
0141 
0142     for (auto& hitsMetaSetup : hitsNameVector)
0143     {      
0144       data[metadataName][hitsName][hitsMetaSetup]["type"] = "3D";
0145       data[metadataName][hitsName][hitsMetaSetup]["options"]["size"] = 1;
0146       data[metadataName][hitsName][hitsMetaSetup]["options"]["color"] = pidToColourMap[hitsMetaSetup];
0147     }
0148 
0149     data[metadataName][trackName][triggerTrackName]["width"] = 0.3;
0150 
0151     data[trackName]["B"] = 0.000014;
0152 
0153     getJSONdata(trigger_tracks, kfp_daughters, data, triggerTrackName);
0154     getJSONdata(all_tracks, kfp_daughters, data, allTrackName);
0155 
0156     if (loadCalos)
0157     {
0158       data[metadataName][hitsName][emcalName] = caloMetadata(emcalName);
0159       data[metadataName][hitsName][ihcalName] = caloMetadata(ihcalName);
0160       data[metadataName][hitsName][ohcalName] = caloMetadata(ohcalName);
0161 
0162       if (hasEMCal) getJSONcalo(data, emcalName, towersEM, geomEMCal);
0163       if (hasIHCal) getJSONcalo(data, ihcalName, towersIH, geoIHCal);
0164       if (hasOHCal) getJSONcalo(data, ohcalName, towersOH, geoOHCal);
0165     }
0166 
0167     std::string m_output_file = m_evt_display_path + "/EvtDisplay_" + m_mother_name + "_" + std::to_string(m_runNumber) + "_" + std::to_string(m_bco) + ".json";
0168 
0169     json_output.open(m_output_file);
0170     json_output << data.dump(2);
0171     json_output.close();
0172 
0173     ++counter;
0174   }
0175 
0176   return Fun4AllReturnCodes::EVENT_OK;
0177 }
0178 
0179 //____________________________________________________________________________..
0180 int event_display_maker::End(PHCompositeNode *topNode)
0181 {
0182   return Fun4AllReturnCodes::EVENT_OK;
0183 }
0184 
0185 int event_display_maker::load_nodes(PHCompositeNode *topNode)
0186 {
0187   m_vertexMap = findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap");
0188   if (!m_vertexMap)
0189   {
0190     std::cout << __PRETTY_FUNCTION__ << " Fatal Error : missing SvtxVertexMap" << std::endl;
0191     return Fun4AllReturnCodes::ABORTRUN;
0192   }
0193 
0194   m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap");
0195   if (!m_trackMap)
0196   {
0197     std::cout << __PRETTY_FUNCTION__ << " Fatal Error : missing SvtxTrackMap" << std::endl;
0198     return Fun4AllReturnCodes::ABORTRUN;
0199   }
0200 
0201   m_kfparticleContainerName_container = m_kfparticleContainerName + "_KFParticle_Container";
0202 
0203   m_kfp_container = findNode::getClass<KFParticle_Container>(topNode, m_kfparticleContainerName_container);
0204   if (!m_kfp_container)
0205   {
0206     std::cout << __PRETTY_FUNCTION__ << " Fatal Error : missing " << m_kfparticleContainerName_container << std::endl;
0207     return Fun4AllReturnCodes::ABORTRUN;
0208   }
0209 
0210   gl1packet = findNode::getClass<Gl1Packet>(topNode, "GL1RAWHIT");
0211   if (!gl1packet)
0212   {
0213     gl1packet = findNode::getClass<Gl1Packet>(topNode, "GL1Packet");
0214     if (!gl1packet)
0215     {
0216       std::cout << __PRETTY_FUNCTION__ << " Fatal Error : missing Gl1Packet" << std::endl;
0217       return Fun4AllReturnCodes::ABORTRUN;
0218     }
0219   }
0220 
0221   triggerruninfo = findNode::getClass<TriggerRunInfo>(topNode, "TriggerRunInfo");
0222   if (!triggerruninfo)
0223   {
0224     std::cout << __PRETTY_FUNCTION__ << " Fatal Error : missing TriggerRunInfo" << std::endl;
0225     return Fun4AllReturnCodes::ABORTRUN;
0226   }
0227 
0228   dst_clustermap = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
0229   if (!dst_clustermap)
0230   {
0231     std::cout << __PRETTY_FUNCTION__ << " Fatal Error : missing TRKR_CLUSTER" << std::endl;
0232     return Fun4AllReturnCodes::ABORTRUN;
0233   }
0234 
0235   geometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0236   if (!geometry)
0237   {
0238     std::cout << __PRETTY_FUNCTION__ << " Fatal Error : missing ActsGeometry" << std::endl;
0239     return Fun4AllReturnCodes::ABORTRUN;
0240   }
0241 
0242   if (loadCalos)
0243   {
0244     if (!towersEM) towersEM = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_CEMC");
0245     if (!towersEM) towersEM = findNode::getClass<TowerInfoContainer>(topNode, "TOWERS_CEMC");
0246     if (!geomEMCal) geomEMCal = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_CEMC");
0247 
0248     if (!towersIH) towersIH = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_HCALIN");
0249     if (!towersIH) towersIH = findNode::getClass<TowerInfoContainer>(topNode, "TOWERS_HCALIN");
0250     if (!geoIHCal) geoIHCal = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALIN");
0251 
0252     if (!towersOH) towersOH = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_HCALOUT");
0253     if (!towersOH) towersOH = findNode::getClass<TowerInfoContainer>(topNode, "TOWERS_HCALOUT");
0254     if (!geoOHCal) geoOHCal = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALOUT");
0255 
0256     if (!towersEM || !geomEMCal) hasEMCal = false;
0257     if (!towersIH || !geoIHCal) hasIHCal = false;
0258     if (!towersOH || !geoOHCal) hasOHCal = false;
0259   }
0260 
0261   return Fun4AllReturnCodes::EVENT_OK;
0262 }
0263 
0264 std::string event_display_maker::getParticleName(int ID)
0265 {
0266   return TDatabasePDG::Instance()->GetParticle(ID)->GetName();
0267 }
0268 
0269 SvtxTrack *event_display_maker::getTrack(unsigned int track_id, SvtxTrackMap *trackmap)
0270 {
0271   SvtxTrack *matched_track = nullptr;
0272 
0273   for (auto &iter : *trackmap)
0274   {
0275     if (iter.first == track_id)
0276     {
0277       matched_track = iter.second;
0278     }
0279   }
0280 
0281   return matched_track;
0282 }
0283 
0284 void event_display_maker::getJSONcalo(json &jsonData, std::string calo, TowerInfoContainer *towerCont, RawTowerGeomContainer *geom)
0285 {
0286   json calos;
0287 
0288   for (size_t channel = 0; channel < towerCont->size(); channel++)
0289   {
0290     TowerInfo* tower = towerCont->get_tower_at_channel(channel);
0291     float raw_energy = tower->get_energy();
0292     if (raw_energy < m_e_low_cut)
0293     {
0294       continue;
0295     } 
0296 
0297     unsigned int towerkey = towerCont->encode_key(channel);
0298     int ieta = towerCont->getTowerEtaBin(towerkey);
0299     int iphi = towerCont->getTowerPhiBin(towerkey);
0300     calos["e"] = raw_energy;
0301     calos["phi"] = geom->get_phicenter(iphi);
0302     calos["eta"] = geom->get_etacenter(ieta);
0303     calos["event"] = 42;
0304 
0305     jsonData[hitsName][calo] += calos;
0306   }
0307 }
0308 
0309 void event_display_maker::getJSONdata(std::vector<SvtxTrack*> tracks, std::vector<KFParticle*> particles, json &jsonData, std::string jsonEntryName)
0310 {
0311   json tracksJson, clustersJson;
0312 
0313   int trackCounter = 0; //Needed for getting KFP objects
0314 
0315   for (auto track : tracks)
0316   {
0317     //Skip drawing of trigger tracks in all tracks
0318     if (jsonEntryName == allTrackName)
0319     {
0320       bool continueOn = false;
0321       for (unsigned int i = 0; i < particles.size(); ++i)
0322       {
0323         if (track->get_id() == (unsigned) particles[i]->Id())
0324         {
0325           continueOn = true;
0326           break;
0327         }
0328       }
0329       if (continueOn) continue;
0330     }
0331 
0332     float length = 0;
0333 
0334     std::string hitType = jsonEntryName == allTrackName ? allTrackName : pidToHitMap[particles[trackCounter]->GetPDG()]; //Figure out if this is background or a triggered track
0335 
0336     TrackSeed *silseed = track->get_silicon_seed();
0337     if (silseed)
0338     {
0339       for (auto cluster_iter = silseed->begin_cluster_keys(); cluster_iter != silseed->end_cluster_keys(); ++cluster_iter)
0340       {
0341         uint64_t clusterKey = *cluster_iter;
0342     
0343         TrkrCluster *cluster = dst_clustermap->findCluster(clusterKey);
0344         auto global = geometry->getGlobalPosition(clusterKey, cluster);
0345 
0346         clustersJson["x"] = (float) global.x();
0347         clustersJson["y"] = (float) global.y();
0348         clustersJson["z"] = (float) global.z();
0349         clustersJson["e"] = 0;
0350 
0351         jsonData[hitsName][hitType] += clustersJson;
0352       }
0353     }
0354 
0355     for (auto state_iter = track->begin_states();
0356          state_iter != track->end_states();
0357          ++state_iter)
0358     {
0359       SvtxTrackState* tstate = state_iter->second;
0360       if (tstate->get_pathlength() == 0) continue; //The first track state is an extrapolation so has no cluster
0361 
0362       uint64_t clusterKey = tstate->get_cluskey();
0363 
0364       TrkrCluster *cluster = dst_clustermap->findCluster(clusterKey);
0365       auto global = geometry->getGlobalPosition(clusterKey, cluster);
0366 
0367       uint8_t id = TrkrDefs::getTrkrId(clusterKey);
0368 
0369       if (id == TrkrDefs::mvtxId || id == TrkrDefs::inttId) continue; //Due to track state issue, use seeds to populate silicon clusters
0370 
0371       clustersJson["x"] = id == TrkrDefs::tpcId ? tstate->get_x() : (float) global.x();
0372       clustersJson["y"] = id == TrkrDefs::tpcId ? tstate->get_y() : (float) global.y();
0373       clustersJson["z"] = id == TrkrDefs::tpcId ? tstate->get_z() : (float) global.z();
0374       clustersJson["e"] = 0;
0375 
0376       jsonData[hitsName][hitType] += clustersJson;
0377 
0378       length = std::max(tstate->get_pathlength(), length);
0379 
0380     } //End of state loop
0381 
0382     std::vector<float> trackPosition;
0383     std::vector<float> trackMomentum;
0384 
0385     if (jsonEntryName == triggerTrackName)
0386     {
0387       trackPosition = {particles[trackCounter]->GetX(), particles[trackCounter]->GetY(), particles[trackCounter]->GetZ()};
0388       trackMomentum = {particles[trackCounter]->GetPx(), particles[trackCounter]->GetPy(), particles[trackCounter]->GetPz()};
0389     }
0390     else
0391     {
0392       trackPosition = {track->get_x(), track->get_y(), track->get_z()};
0393       trackMomentum = {track->get_px(), track->get_py(), track->get_pz()};
0394     }
0395 
0396     tracksJson["pxyz"] = trackMomentum;
0397     tracksJson["xyz"] = trackPosition;
0398     tracksJson["trk_color"] = jsonEntryName == triggerTrackName ? pidMap[particles[trackCounter]->GetPDG()] : allColour;
0399     tracksJson["nh"] = 60;
0400     tracksJson["l"] = length;
0401     tracksJson["q"] = jsonEntryName == triggerTrackName ? particles[trackCounter]->Q() : track->get_charge();
0402 
0403     jsonData[trackName][jsonEntryName] += tracksJson;    
0404 
0405     ++trackCounter;
0406 
0407   } //End of track loop
0408 
0409   //Now add mother
0410   if (jsonEntryName == triggerTrackName)
0411   {
0412     tracksJson["pxyz"] = {mother->GetPx(), mother->GetPy(), mother->GetPz()};
0413     tracksJson["xyz"] = {mother->GetX(), mother->GetY(), mother->GetZ()};
0414     tracksJson["trk_color"] = motherColour;
0415     tracksJson["nh"] = 60;
0416     tracksJson["l"] = mother->GetDecayLength();
0417     tracksJson["q"] = mother->Q();
0418 
0419     jsonData[trackName][jsonEntryName] += tracksJson;
0420 
0421     for (auto& intermediate : intermediates)
0422     {
0423       tracksJson["pxyz"] = {intermediate->GetPx(), intermediate->GetPy(), intermediate->GetPz()};
0424       tracksJson["xyz"] = {intermediate->GetX(), intermediate->GetY(), intermediate->GetZ()};
0425       tracksJson["trk_color"] = intermediateColour;
0426       tracksJson["nh"] = 60;
0427       tracksJson["l"] = intermediate->GetDecayLength();
0428       tracksJson["q"] = intermediate->Q();
0429 
0430       jsonData[trackName][jsonEntryName] += tracksJson;
0431     } 
0432      
0433   }
0434 }
0435 
0436 //https://stackoverflow.com/questions/997946/how-to-get-current-time-and-date-in-c
0437 std::string event_display_maker::getDate()
0438 {
0439     std::time_t t = std::time(0);   // get time now
0440     std::tm* now = std::localtime(&t);
0441 
0442     std::stringstream date;
0443     date << (now->tm_year + 1900) << '-'
0444          << (now->tm_mon + 1) << '-'
0445          <<  now->tm_mday;
0446     return date.str();
0447 }
0448 
0449 bool event_display_maker::isInRange(float min, float value, float max)
0450 {
0451   return min <= value && value <= max;
0452 }
0453 
0454 json event_display_maker::caloMetadata(std::string type)
0455 {
0456   json metaData, options, minmax;
0457 
0458   //Default for EMCal
0459   float rMin = 90;
0460   float rMax = 136.1;
0461   int color = emcalColor;
0462   float scaleMax = 2.71998;
0463 
0464   if (type != emcalName)
0465   {
0466     rMin = type == ihcalName ? 147.27 : 183.3;
0467     rMax = type == ihcalName ? 175.0 : 348.634;
0468     color = type == ihcalName ? ihcalColor : ohcalColor;
0469     scaleMax = type == ihcalName ? 0.569264 : 2.57763;   
0470   }
0471 
0472   metaData["type"] = "PROJECTIVE";
0473 
0474   options["rmin"] = rMin;
0475   options["rmax"] = rMax;
0476   options["deta"] = 0.025;
0477   options["dphi"] = 0.025;
0478   options["color"] = color;
0479   options["transparent"] = 0.6;
0480   minmax["min"] = 0.05;
0481   minmax["max"] = scaleMax;
0482   options["scaleminmax"] = minmax;
0483 
0484   metaData["options"] = options;
0485 
0486   return metaData;
0487 }