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;
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;
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()));
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
0096
0097
0098 if (m_track->get_crossing() != m_vertex->get_beam_crossing()) continue;
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;
0106
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
0116 json data;
0117
0118 uint64_t m_bco = gl1packet->lValue(0, "BCO") + trigger_tracks[0]->get_crossing();
0119
0120
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;
0314
0315 for (auto track : tracks)
0316 {
0317
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()];
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;
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;
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 }
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 }
0408
0409
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
0437 std::string event_display_maker::getDate()
0438 {
0439 std::time_t t = std::time(0);
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
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 }