File indexing completed on 2025-08-05 08:12:44
0001 #include "HFMLTriggerInterface.h"
0002
0003 #include <fun4all/Fun4AllReturnCodes.h>
0004 #include <pdbcalbase/PdbParameterMap.h>
0005 #include <phool/PHCompositeNode.h>
0006 #include <phool/PHTimeServer.h>
0007 #include <phool/PHTimer.h>
0008 #include <phool/getClass.h>
0009
0010 #include <phool/PHCompositeNode.h>
0011
0012 #include <g4main/PHG4Hit.h>
0013 #include <g4main/PHG4Particle.h>
0014 #include <g4main/PHG4TruthInfoContainer.h>
0015
0016
0017 #include <g4mvtx/PHG4CylinderGeom_MVTX.h>
0018
0019 #include <g4detectors/PHG4Cell.h>
0020 #include <g4detectors/PHG4CellContainer.h>
0021 #include <g4detectors/PHG4CylinderCellGeom.h>
0022 #include <g4detectors/PHG4CylinderCellGeomContainer.h>
0023 #include <g4detectors/PHG4CylinderGeom.h>
0024 #include <g4detectors/PHG4CylinderGeomContainer.h>
0025
0026 #include <trackbase_historic/SvtxCluster.h>
0027 #include <trackbase_historic/SvtxClusterMap.h>
0028 #include <trackbase_historic/SvtxHit.h>
0029 #include <trackbase_historic/SvtxHitMap.h>
0030 #include <trackbase_historic/SvtxTrack.h>
0031 #include <trackbase_historic/SvtxTrackMap.h>
0032 #include <trackbase_historic/SvtxVertex.h>
0033 #include <trackbase_historic/SvtxVertexMap.h>
0034
0035 #include <g4eval/SvtxEvalStack.h>
0036
0037 #include <HepMC/GenEvent.h>
0038 #include <HepMC/GenVertex.h>
0039 #include <phhepmc/PHHepMCGenEvent.h>
0040 #include <phhepmc/PHHepMCGenEventMap.h>
0041
0042 #include <TDatabasePDG.h>
0043 #include <TFile.h>
0044 #include <TH2F.h>
0045 #include <TH3F.h>
0046 #include <TLorentzVector.h>
0047 #include <TString.h>
0048 #include <TTree.h>
0049
0050 #include <rapidjson/document.h>
0051 #include <rapidjson/ostreamwrapper.h>
0052 #include <rapidjson/prettywriter.h>
0053
0054 #include <boost/format.hpp>
0055 #include <boost/property_tree/json_parser.hpp>
0056 #include <boost/property_tree/ptree.hpp>
0057 #include <boost/property_tree/xml_parser.hpp>
0058
0059
0060 #include <cassert>
0061 #include <cmath>
0062 #include <cstddef>
0063 #include <iostream>
0064
0065
0066 using namespace std;
0067
0068 HFMLTriggerInterface::HFMLTriggerInterface(std::string filename)
0069 : SubsysReco("HFMLTriggerInterface")
0070 , _ievent(0)
0071 , _f(nullptr)
0072 , _eta_min(-1)
0073 , _eta_max(1)
0074 , _embedding_id(1)
0075 , _nlayers_maps(3)
0076 , _svtxevalstack(nullptr)
0077 , m_hitMap(nullptr)
0078 , m_Geoms(nullptr)
0079 , m_truthInfo(nullptr)
0080 , m_Flags(nullptr)
0081 , m_hitStaveLayer(nullptr)
0082 , m_hitModuleHalfStave(nullptr)
0083 , m_hitChipModule(nullptr)
0084 , m_hitLayerMap(nullptr)
0085 , m_hitPixelPhiMap(nullptr)
0086 , m_hitPixelPhiMapHL(nullptr)
0087 , m_hitPixelZMap(nullptr)
0088 {
0089 _foutname = filename;
0090 }
0091
0092 int HFMLTriggerInterface::Init(PHCompositeNode* topNode)
0093 {
0094 _ievent = 0;
0095
0096 _f = new TFile((_foutname + string(".root")).c_str(), "RECREATE");
0097
0098 m_jsonOut.open((_foutname + string(".json")).c_str(), fstream::out);
0099
0100 m_jsonOut << "{" << endl;
0101 m_jsonOut << "\"Events\" : [" << endl;
0102
0103
0104
0105
0106
0107
0108 m_hitLayerMap = new TH3F("hitLayerMap", "hitLayerMap", 600, -10, 10, 600, -10, 10, 10, -.5, 9.5);
0109 m_hitLayerMap->SetTitle("hitLayerMap;x [mm];y [mm];Half Layers");
0110
0111 m_hitPixelPhiMap = new TH3F("hitPixelPhiMap", "hitPixelPhiMap", 16000, -.5, 16000 - .5, 600, -M_PI, M_PI, 10, -.5, 9.5);
0112 m_hitPixelPhiMap->SetTitle("hitPixelPhiMap;PixelPhiIndex in layer;phi [rad];Half Layers Index");
0113 m_hitPixelPhiMapHL = new TH3F("hitPixelPhiMapHL", "hitPixelPhiMapHL", 16000, -.5, 16000 - .5, 600, -M_PI, M_PI, 10, -.5, 9.5);
0114 m_hitPixelPhiMapHL->SetTitle("hitPixelPhiMap;PixelPhiIndex in half layer;phi [rad];Half Layers Index");
0115 m_hitPixelZMap = new TH3F("hitPixelZMap", "hitPixelZMap", 16000, -.5, 16000 - .5, 600, 15, 15, 10, -.5, 9.5);
0116 m_hitPixelZMap->SetTitle("hitPixelZMap;hitPixelZMap;z [cm];Half Layers");
0117
0118 m_hitStaveLayer = new TH2F("hitStaveLayer", "hitStaveLayer", 100, -.5, 100 - .5, 10, -.5, 9.5);
0119 m_hitStaveLayer->SetTitle("hitStaveLayer;Stave index;Half Layers");
0120 m_hitModuleHalfStave = new TH2F("hitModuleHalfStave", "hitModuleHalfStave", 100, -.5, 100 - .5, 10, -.5, 9.5);
0121 m_hitModuleHalfStave->SetTitle("hitModuleHalfStave;Module index;Half Stave");
0122 m_hitChipModule = new TH2F("hitChipModule", "hitChipModule", 100, -.5, 100 - .5, 10, -.5, 9.5);
0123 m_hitChipModule->SetTitle("hitChipModule;Chip;Module");
0124
0125 return Fun4AllReturnCodes::EVENT_OK;
0126 }
0127
0128 int HFMLTriggerInterface::InitRun(PHCompositeNode* topNode)
0129 {
0130 m_hitMap = findNode::getClass<SvtxHitMap>(topNode, "SvtxHitMap");
0131 if (!m_hitMap)
0132 {
0133 std::cout << PHWHERE << "ERROR: Can't find node SvtxHitMap" << std::endl;
0134 return Fun4AllReturnCodes::ABORTRUN;
0135 }
0136 m_Geoms =
0137 findNode::getClass<PHG4CylinderGeomContainer>(topNode, "CYLINDERGEOM_MAPS");
0138 if (!m_Geoms)
0139 {
0140 std::cout << PHWHERE << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl;
0141 return Fun4AllReturnCodes::ABORTRUN;
0142 }
0143
0144 m_truthInfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0145 if (!m_truthInfo)
0146 {
0147 std::cout << PHWHERE << "ERROR: Can't find node G4TruthInfo" << std::endl;
0148 return Fun4AllReturnCodes::ABORTRUN;
0149 }
0150
0151 m_Flags = findNode::getClass<PdbParameterMap>(topNode, "HFMLTrigger_HepMCTriggerFlags");
0152 if (!m_Flags)
0153 {
0154 cout << "HFMLTriggerInterface::InitRun - WARNING - missing HFMLTrigger_HepMCTriggerFlags" << endl;
0155 }
0156
0157 return Fun4AllReturnCodes::EVENT_OK;
0158 }
0159
0160 int HFMLTriggerInterface::process_event(PHCompositeNode* topNode)
0161 {
0162 if (!_svtxevalstack)
0163 {
0164 _svtxevalstack = new SvtxEvalStack(topNode);
0165 _svtxevalstack->set_strict(0);
0166 _svtxevalstack->set_verbosity(Verbosity() + 1);
0167 }
0168 else
0169 {
0170 _svtxevalstack->next_event(topNode);
0171 }
0172
0173
0174
0175 SvtxClusterEval* clustereval = _svtxevalstack->get_cluster_eval();
0176 SvtxHitEval* hiteval = _svtxevalstack->get_hit_eval();
0177
0178
0179 PHHepMCGenEventMap* geneventmap = findNode::getClass<PHHepMCGenEventMap>(topNode, "PHHepMCGenEventMap");
0180 if (!geneventmap)
0181 {
0182 std::cout << PHWHERE << " - Fatal error - missing node PHHepMCGenEventMap" << std::endl;
0183 return Fun4AllReturnCodes::ABORTRUN;
0184 }
0185
0186 PHHepMCGenEvent* genevt = geneventmap->get(_embedding_id);
0187 if (!genevt)
0188 {
0189 std::cout << PHWHERE << " - Fatal error - node PHHepMCGenEventMap missing subevent with embedding ID " << _embedding_id;
0190 std::cout << ". Print PHHepMCGenEventMap:";
0191 geneventmap->identify();
0192 return Fun4AllReturnCodes::ABORTRUN;
0193 }
0194
0195 HepMC::GenEvent* theEvent = genevt->getEvent();
0196 assert(theEvent);
0197 if (Verbosity())
0198 {
0199 cout << "HFMLTriggerInterface::process_event - process HepMC::GenEvent with signal_process_id = "
0200 << theEvent->signal_process_id();
0201 if (theEvent->signal_process_vertex())
0202 {
0203 cout << " and signal_process_vertex : ";
0204 theEvent->signal_process_vertex()->print();
0205 }
0206 cout << " - Event record:" << endl;
0207 theEvent->print();
0208 }
0209
0210
0211
0212
0213
0214 rapidjson::Document d;
0215 d.SetObject();
0216 rapidjson::Document::AllocatorType& alloc = d.GetAllocator();
0217
0218 auto loadCoordinate = [&](double x, double y, double z) {
0219
0220 rapidjson::Value vertexTree(rapidjson::kArrayType);
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 vertexTree.PushBack(x, alloc).PushBack(y, alloc).PushBack(z, alloc);
0235
0236 return vertexTree;
0237 };
0238
0239
0240
0241
0242
0243
0244 rapidjson::Value metaTree(rapidjson::kObjectType);
0245
0246 metaTree.AddMember("Description", "These are meta data for this event. Not intended to use in ML algorithm", alloc);
0247 metaTree.AddMember("EventID", _ievent, alloc);
0248 metaTree.AddMember("Unit", "cm", alloc);
0249 metaTree.AddMember("CollisionVertex",
0250 loadCoordinate(genevt->get_collision_vertex().x(),
0251 genevt->get_collision_vertex().y(),
0252 genevt->get_collision_vertex().z()),
0253 alloc);
0254
0255 metaTree.AddMember("Layer_Count", _nlayers_maps, alloc);
0256 metaTree.AddMember("PixelHalfLayerIndex_Count", _nlayers_maps * 2, alloc);
0257
0258 for (unsigned int layer = 0; layer < _nlayers_maps; ++layer)
0259 {
0260 PHG4CylinderGeom_MVTX* geom = dynamic_cast<PHG4CylinderGeom_MVTX*>(m_Geoms->GetLayerGeom(layer));
0261 assert(geom);
0262
0263
0264 rapidjson::Value layerDescTree(rapidjson::kObjectType);
0265
0266 static const unsigned int nChip(9);
0267
0268 layerDescTree.AddMember("PixelPhiIndexInLayer_Count", geom->get_N_staves() * geom->get_NX(), alloc);
0269 layerDescTree.AddMember("PixelPhiIndexInHalfLayer_Count", geom->get_N_staves() * geom->get_NX() / 2, alloc);
0270 layerDescTree.AddMember("PixelZIndex_Count", nChip * geom->get_NZ(), alloc);
0271 layerDescTree.AddMember("HalfLayer_Count", 2, alloc);
0272 layerDescTree.AddMember("Stave_Count", geom->get_N_staves(), alloc);
0273 layerDescTree.AddMember("Chip_Count", nChip, alloc);
0274 layerDescTree.AddMember("Pixel_Count", geom->get_NX() * geom->get_NZ(), alloc);
0275
0276
0277
0278
0279 rapidjson::Value keyName(str(boost::format{"Layer%1%"} % layer).c_str(), alloc);
0280 metaTree.AddMember(keyName,
0281 layerDescTree, alloc);
0282 }
0283
0284
0285 rapidjson::Value truthTriggerFlagTree(rapidjson::kObjectType);
0286
0287 truthTriggerFlagTree.AddMember("Description",
0288 "These are categorical true/false MonteCalo truth tags for the event. These are only known in training sample. This would be trigger output in real data processing.",
0289 alloc);
0290
0291
0292 rapidjson::Value flagsTree(rapidjson::kObjectType);
0293 if (m_Flags)
0294 {
0295 auto range = m_Flags->get_iparam_iters();
0296
0297 for (auto flagIter = range.first; flagIter != range.second; ++flagIter)
0298 {
0299
0300
0301 const string& name = flagIter->first;
0302 rapidjson::Value keyName(name.c_str(), alloc);
0303 const bool flag = flagIter->second > 0 ? true : false;
0304
0305 flagsTree.AddMember(keyName, flag, alloc);
0306
0307 }
0308 }
0309 truthTriggerFlagTree.AddMember("Flags", flagsTree, alloc);
0310
0311
0312
0313 rapidjson::Value rawHitTree(rapidjson::kObjectType);
0314 rawHitTree.AddMember("Description",
0315 "Raw data in the event in an unordered set of hit ID. To help in visualization stage, the coordinate of the hit is also appended. These would be input in real data.",
0316 alloc);
0317
0318
0319
0320
0321 rapidjson::Value rawHitsTree(rapidjson::kArrayType);
0322
0323 set<unsigned int> mapsHits;
0324 assert(m_hitMap);
0325 for (SvtxHitMap::Iter iter = m_hitMap->begin();
0326 iter != m_hitMap->end();
0327 ++iter)
0328 {
0329 SvtxHit* hit = iter->second;
0330 assert(hit);
0331 unsigned int layer = hit->get_layer();
0332 if (layer < _nlayers_maps)
0333 {
0334 unsigned int hitID = hit->get_id();
0335 mapsHits.insert(hitID);
0336
0337 PHG4Cell* cell = hiteval->get_cell(hit);
0338 assert(cell);
0339 PHG4CylinderGeom_MVTX* geom = dynamic_cast<PHG4CylinderGeom_MVTX*>(m_Geoms->GetLayerGeom(layer));
0340 assert(geom);
0341
0342 TVector3 local_coords = geom->get_local_coords_from_pixel(cell->get_pixel_index());
0343 TVector3 world_coords = geom->get_world_from_local_coords(cell->get_stave_index(), cell->get_half_stave_index(), cell->get_module_index(), cell->get_chip_index(), local_coords);
0344
0345 unsigned int pixel_x(cell->get_pixel_index() % geom->get_NX());
0346 unsigned int pixel_z(cell->get_pixel_index() / geom->get_NX());
0347 unsigned int halflayer = (int) pixel_x >= geom->get_NX() / 2 ? 0 : 1;
0348
0349 assert((int) pixel_x < geom->get_NX());
0350 assert((int) pixel_z < geom->get_NZ());
0351
0352 unsigned int halfLayerIndex(layer * 2 + halflayer);
0353 unsigned int pixelPhiIndex(
0354 cell->get_stave_index() * geom->get_NX() + pixel_x);
0355 unsigned int pixelPhiIndexHL(
0356 cell->get_stave_index() * geom->get_NX() / 2 + pixel_x % (geom->get_NX() / 2));
0357 unsigned int pixelZIndex(cell->get_chip_index() * geom->get_NZ() + pixel_z);
0358
0359
0360 rapidjson::Value hitTree(rapidjson::kObjectType);
0361
0362
0363 rapidjson::Value hitIDTree(rapidjson::kObjectType);
0364 hitIDTree.AddMember("HitSequenceInEvent", hitID, alloc);
0365
0366 hitIDTree.AddMember("PixelHalfLayerIndex", halfLayerIndex, alloc);
0367 hitIDTree.AddMember("PixelPhiIndexInLayer", pixelPhiIndex, alloc);
0368 hitIDTree.AddMember("PixelPhiIndexInHalfLayer", pixelPhiIndexHL, alloc);
0369 hitIDTree.AddMember("PixelZIndex", pixelZIndex, alloc);
0370
0371 hitIDTree.AddMember("Layer", layer, alloc);
0372 hitIDTree.AddMember("HalfLayer", halflayer, alloc);
0373 hitIDTree.AddMember("Stave", cell->get_stave_index(), alloc);
0374
0375
0376 hitIDTree.AddMember("Chip", cell->get_chip_index(), alloc);
0377 hitIDTree.AddMember("Pixel", cell->get_pixel_index(), alloc);
0378 hitTree.AddMember("ID", hitIDTree, alloc);
0379
0380 hitTree.AddMember("Coordinate",
0381 loadCoordinate(world_coords.x(),
0382 world_coords.y(),
0383 world_coords.z()),
0384 alloc);
0385
0386
0387 rawHitsTree.PushBack(hitTree, alloc);
0388
0389 m_hitStaveLayer->Fill(cell->get_stave_index(), halfLayerIndex);
0390 m_hitModuleHalfStave->Fill(cell->get_module_index(), cell->get_half_stave_index());
0391 m_hitChipModule->Fill(cell->get_chip_index(), cell->get_module_index());
0392
0393 m_hitLayerMap->Fill(world_coords.x(), world_coords.y(), halfLayerIndex);
0394 m_hitPixelPhiMap->Fill(pixelPhiIndex, atan2(world_coords.y(), world_coords.x()), halfLayerIndex);
0395 m_hitPixelPhiMapHL->Fill(pixelPhiIndexHL, atan2(world_coords.y(), world_coords.x()), halfLayerIndex);
0396 m_hitPixelZMap->Fill(pixelZIndex, world_coords.z(), halfLayerIndex);
0397 }
0398
0399 }
0400 rawHitTree.AddMember("MVTXHits", rawHitsTree, alloc);
0401
0402
0403
0404 rapidjson::Value truthHitTree(rapidjson::kObjectType);
0405 truthHitTree.AddMember("Description", "From the MonteCalo truth information, pairs of track ID and subset of RawHit that belong to the track. These are not presented in real data. The track ID is arbitary.",
0406 alloc);
0407
0408 assert(m_truthInfo);
0409
0410
0411 rapidjson::Value truthTracksTree(rapidjson::kArrayType);
0412
0413 PHG4TruthInfoContainer::ConstRange range = m_truthInfo->GetPrimaryParticleRange();
0414 for (PHG4TruthInfoContainer::ConstIterator iter = range.first;
0415 iter != range.second;
0416 ++iter)
0417 {
0418 PHG4Particle* g4particle = iter->second;
0419 assert(g4particle);
0420
0421 std::set<SvtxCluster*> g4clusters = clustereval->all_clusters_from(g4particle);
0422
0423
0424 rapidjson::Value trackHitTree(rapidjson::kArrayType);
0425 unsigned int nMAPS(0);
0426
0427 for (const SvtxCluster* cluster : g4clusters)
0428 {
0429 assert(cluster);
0430 unsigned int layer = cluster->get_layer();
0431 if (layer < _nlayers_maps)
0432 {
0433 ++nMAPS;
0434
0435 for (SvtxCluster::ConstHitIter hiter = cluster->begin_hits();
0436 hiter != cluster->end_hits();
0437 ++hiter)
0438 {
0439
0440 unsigned int hitID = *hiter;
0441 assert(mapsHits.find(hitID) != mapsHits.end());
0442
0443
0444
0445 trackHitTree.PushBack(hitID, alloc);
0446 }
0447 }
0448
0449 }
0450
0451 if (nMAPS > 1)
0452 {
0453
0454 rapidjson::Value trackTree(rapidjson::kObjectType);
0455 trackTree.AddMember("TrackSequenceInEvent", g4particle->get_track_id(), alloc);
0456 trackTree.AddMember("HitSequenceInEvent", trackHitTree, alloc);
0457
0458 trackTree.AddMember("ParticleTypeID", g4particle->get_pid(), alloc);
0459 trackTree.AddMember("TrackMomentum",
0460 loadCoordinate(g4particle->get_px(),
0461 g4particle->get_py(),
0462 g4particle->get_pz()),
0463 alloc);
0464
0465
0466
0467
0468
0469
0470 truthTracksTree.PushBack(trackTree, alloc);
0471 }
0472
0473 }
0474 truthHitTree.AddMember("TruthTracks", truthTracksTree, alloc);
0475
0476
0477 d.AddMember("MetaData", metaTree, alloc);
0478 d.AddMember("TruthTriggerFlag", truthTriggerFlagTree, alloc);
0479 d.AddMember("RawHit", rawHitTree, alloc);
0480 d.AddMember("TruthHit", truthHitTree, alloc);
0481
0482 assert(m_jsonOut.is_open());
0483
0484 if (_ievent > 0)
0485 {
0486 m_jsonOut << "," << endl;
0487 }
0488
0489
0490
0491
0492
0493
0494 rapidjson::OStreamWrapper osw(m_jsonOut);
0495 rapidjson::PrettyWriter<rapidjson::OStreamWrapper> writer(osw);
0496
0497 d.Accept(writer);
0498
0499 ++_ievent;
0500
0501 return Fun4AllReturnCodes::EVENT_OK;
0502 }
0503
0504 int HFMLTriggerInterface::End(PHCompositeNode* topNode)
0505 {
0506 if (_f)
0507 {
0508 _f->cd();
0509 _f->Write();
0510
0511
0512
0513 }
0514
0515 if (m_jsonOut.is_open())
0516 {
0517 m_jsonOut << "]" << endl;
0518 m_jsonOut << "}" << endl;
0519
0520 m_jsonOut.close();
0521 }
0522
0523 cout << "HFMLTriggerInterface::End - output to " << _foutname << ".*" << endl;
0524
0525 return Fun4AllReturnCodes::EVENT_OK;
0526 }