Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HFMLTriggerInterface.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file HFMLTriggerInterface.C
1 #include "HFMLTriggerInterface.h"
2 
4 #include <pdbcalbase/PdbParameterMap.h>
6 #include <phool/PHTimeServer.h>
7 #include <phool/PHTimer.h>
8 #include <phool/getClass.h>
9 
10 #include <phool/PHCompositeNode.h>
11 
12 #include <g4main/PHG4Hit.h>
13 #include <g4main/PHG4Particle.h>
15 
16 
17 #include <g4mvtx/PHG4CylinderGeom_MVTX.h>
18 
19 #include <g4detectors/PHG4Cell.h>
25 
26 #include <trackbase_historic/SvtxCluster.h>
27 #include <trackbase_historic/SvtxClusterMap.h>
28 #include <trackbase_historic/SvtxHit.h>
29 #include <trackbase_historic/SvtxHitMap.h>
32 #include <trackbase_historic/SvtxVertex.h>
33 #include <trackbase_historic/SvtxVertexMap.h>
34 
35 #include <g4eval/SvtxEvalStack.h>
36 
37 #include <HepMC/GenEvent.h>
38 #include <HepMC/GenVertex.h>
41 
42 #include <TDatabasePDG.h>
43 #include <TFile.h>
44 #include <TH2F.h>
45 #include <TH3F.h>
46 #include <TLorentzVector.h>
47 #include <TString.h>
48 #include <TTree.h>
49 
50 #include <rapidjson/document.h>
51 #include <rapidjson/ostreamwrapper.h>
52 #include <rapidjson/prettywriter.h>
53 
54 #include <boost/format.hpp>
55 #include <boost/property_tree/json_parser.hpp>
56 #include <boost/property_tree/ptree.hpp>
57 #include <boost/property_tree/xml_parser.hpp>
58 
59 
60 #include <cassert>
61 #include <cmath>
62 #include <cstddef>
63 #include <iostream>
64 
65 
66 using namespace std;
67 
69  : SubsysReco("HFMLTriggerInterface")
70  , _ievent(0)
71  , _f(nullptr)
72  , _eta_min(-1)
73  , _eta_max(1)
74  , _embedding_id(1)
75  , _nlayers_maps(3)
76  , _svtxevalstack(nullptr)
77  , m_hitMap(nullptr)
78  , m_Geoms(nullptr)
79  , m_truthInfo(nullptr)
80  , m_Flags(nullptr)
81  , m_hitStaveLayer(nullptr)
82  , m_hitModuleHalfStave(nullptr)
83  , m_hitChipModule(nullptr)
84  , m_hitLayerMap(nullptr)
85  , m_hitPixelPhiMap(nullptr)
86  , m_hitPixelPhiMapHL(nullptr)
87  , m_hitPixelZMap(nullptr)
88 {
90 }
91 
93 {
94  _ievent = 0;
95 
96  _f = new TFile((_foutname + string(".root")).c_str(), "RECREATE");
97 
98  m_jsonOut.open((_foutname + string(".json")).c_str(), fstream::out);
99 
100  m_jsonOut << "{" << endl;
101  m_jsonOut << "\"Events\" : [" << endl;
102 
103  // _h2 = new TH2D("h2", "", 100, 0, 100.0, 40, -2, +2);
104  // _h2_b = new TH2D("h2_b", "", 100, 0, 100.0, 40, -2, +2);
105  // _h2_c = new TH2D("h2_c", "", 100, 0, 100.0, 40, -2, +2);
106  // _h2all = new TH2D("h2all", "", 100, 0, 100.0, 40, -2, +2);
107 
108  m_hitLayerMap = new TH3F("hitLayerMap", "hitLayerMap", 600, -10, 10, 600, -10, 10, 10, -.5, 9.5);
109  m_hitLayerMap->SetTitle("hitLayerMap;x [mm];y [mm];Half Layers");
110 
111  m_hitPixelPhiMap = new TH3F("hitPixelPhiMap", "hitPixelPhiMap", 16000, -.5, 16000 - .5, 600, -M_PI, M_PI, 10, -.5, 9.5);
112  m_hitPixelPhiMap->SetTitle("hitPixelPhiMap;PixelPhiIndex in layer;phi [rad];Half Layers Index");
113  m_hitPixelPhiMapHL = new TH3F("hitPixelPhiMapHL", "hitPixelPhiMapHL", 16000, -.5, 16000 - .5, 600, -M_PI, M_PI, 10, -.5, 9.5);
114  m_hitPixelPhiMapHL->SetTitle("hitPixelPhiMap;PixelPhiIndex in half layer;phi [rad];Half Layers Index");
115  m_hitPixelZMap = new TH3F("hitPixelZMap", "hitPixelZMap", 16000, -.5, 16000 - .5, 600, 15, 15, 10, -.5, 9.5);
116  m_hitPixelZMap->SetTitle("hitPixelZMap;hitPixelZMap;z [cm];Half Layers");
117 
118  m_hitStaveLayer = new TH2F("hitStaveLayer", "hitStaveLayer", 100, -.5, 100 - .5, 10, -.5, 9.5);
119  m_hitStaveLayer->SetTitle("hitStaveLayer;Stave index;Half Layers");
120  m_hitModuleHalfStave = new TH2F("hitModuleHalfStave", "hitModuleHalfStave", 100, -.5, 100 - .5, 10, -.5, 9.5);
121  m_hitModuleHalfStave->SetTitle("hitModuleHalfStave;Module index;Half Stave");
122  m_hitChipModule = new TH2F("hitChipModule", "hitChipModule", 100, -.5, 100 - .5, 10, -.5, 9.5);
123  m_hitChipModule->SetTitle("hitChipModule;Chip;Module");
124 
126 }
127 
129 {
130  m_hitMap = findNode::getClass<SvtxHitMap>(topNode, "SvtxHitMap");
131  if (!m_hitMap)
132  {
133  std::cout << PHWHERE << "ERROR: Can't find node SvtxHitMap" << std::endl;
135  }
136  m_Geoms =
137  findNode::getClass<PHG4CylinderGeomContainer>(topNode, "CYLINDERGEOM_MAPS");
138  if (!m_Geoms)
139  {
140  std::cout << PHWHERE << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl;
142  }
143 
144  m_truthInfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
145  if (!m_truthInfo)
146  {
147  std::cout << PHWHERE << "ERROR: Can't find node G4TruthInfo" << std::endl;
149  }
150 
151  m_Flags = findNode::getClass<PdbParameterMap>(topNode, "HFMLTrigger_HepMCTriggerFlags");
152  if (!m_Flags)
153  {
154  cout << "HFMLTriggerInterface::InitRun - WARNING - missing HFMLTrigger_HepMCTriggerFlags" << endl;
155  }
156 
158 }
159 
161 {
162  if (!_svtxevalstack)
163  {
164  _svtxevalstack = new SvtxEvalStack(topNode);
167  }
168  else
169  {
170  _svtxevalstack->next_event(topNode);
171  }
172 
173  // SvtxVertexEval* vertexeval = _svtxevalstack->get_vertex_eval();
174  // SvtxTrackEval* trackeval = _svtxevalstack->get_track_eval();
177  // SvtxTruthEval* trutheval = _svtxevalstack->get_truth_eval();
178 
179  PHHepMCGenEventMap* geneventmap = findNode::getClass<PHHepMCGenEventMap>(topNode, "PHHepMCGenEventMap");
180  if (!geneventmap)
181  {
182  std::cout << PHWHERE << " - Fatal error - missing node PHHepMCGenEventMap" << std::endl;
184  }
185 
186  PHHepMCGenEvent* genevt = geneventmap->get(_embedding_id);
187  if (!genevt)
188  {
189  std::cout << PHWHERE << " - Fatal error - node PHHepMCGenEventMap missing subevent with embedding ID " << _embedding_id;
190  std::cout << ". Print PHHepMCGenEventMap:";
191  geneventmap->identify();
193  }
194 
195  HepMC::GenEvent* theEvent = genevt->getEvent();
196  assert(theEvent);
197  if (Verbosity())
198  {
199  cout << "HFMLTriggerInterface::process_event - process HepMC::GenEvent with signal_process_id = "
200  << theEvent->signal_process_id();
201  if (theEvent->signal_process_vertex())
202  {
203  cout << " and signal_process_vertex : ";
204  theEvent->signal_process_vertex()->print();
205  }
206  cout << " - Event record:" << endl;
207  theEvent->print();
208  }
209 
210  // property tree preparation
211  // using boost::property_tree::ptree;
212  // ptree pt;
213 
214  rapidjson::Document d;
215  d.SetObject();
216  rapidjson::Document::AllocatorType& alloc = d.GetAllocator();
217 
218  auto loadCoordinate = [&](double x, double y, double z) {
219  // ptree vertexTree;
220  rapidjson::Value vertexTree(rapidjson::kArrayType);
221 
222  // ptree vertexX;
223  // vertexX.put("", x);
224  // vertexTree.push_back(make_pair("", vertexX));
225 
226  // ptree vertexY;
227  // vertexY.put("", y);
228  // vertexTree.push_back(make_pair("", vertexY));
229 
230  // ptree vertexZ;
231  // vertexZ.put("", z);
232  // vertexTree.push_back(make_pair("", vertexZ));
233 
234  vertexTree.PushBack(x, alloc).PushBack(y, alloc).PushBack(z, alloc);
235 
236  return vertexTree;
237  };
238 
239  // Create a root
240  // ptree pTree;
241 
242  // meta data
243  // ptree metaTree;
244  rapidjson::Value metaTree(rapidjson::kObjectType);
245 
246  metaTree.AddMember("Description", "These are meta data for this event. Not intended to use in ML algorithm", alloc);
247  metaTree.AddMember("EventID", _ievent, alloc);
248  metaTree.AddMember("Unit", "cm", alloc);
249  metaTree.AddMember("CollisionVertex",
250  loadCoordinate(genevt->get_collision_vertex().x(),
251  genevt->get_collision_vertex().y(),
252  genevt->get_collision_vertex().z()),
253  alloc);
254 
255  metaTree.AddMember("Layer_Count", _nlayers_maps, alloc);
256  metaTree.AddMember("PixelHalfLayerIndex_Count", _nlayers_maps * 2, alloc);
257 
258  for (unsigned int layer = 0; layer < _nlayers_maps; ++layer)
259  {
260  PHG4CylinderGeom_MVTX* geom = dynamic_cast<PHG4CylinderGeom_MVTX*>(m_Geoms->GetLayerGeom(layer));
261  assert(geom);
262 
263  // ptree layerDescTree;
264  rapidjson::Value layerDescTree(rapidjson::kObjectType);
265 
266  static const unsigned int nChip(9);
267 
268  layerDescTree.AddMember("PixelPhiIndexInLayer_Count", geom->get_N_staves() * geom->get_NX(), alloc);
269  layerDescTree.AddMember("PixelPhiIndexInHalfLayer_Count", geom->get_N_staves() * geom->get_NX() / 2, alloc);
270  layerDescTree.AddMember("PixelZIndex_Count", nChip * geom->get_NZ(), alloc);
271  layerDescTree.AddMember("HalfLayer_Count", 2, alloc);
272  layerDescTree.AddMember("Stave_Count", geom->get_N_staves(), alloc);
273  layerDescTree.AddMember("Chip_Count", nChip, alloc);
274  layerDescTree.AddMember("Pixel_Count", geom->get_NX() * geom->get_NZ(), alloc);
275 
276  // metaTree.AddMember(
277  // str(boost::format{"Layer%1%"} % layer).c_str(),
278  // layerDescTree, alloc);
279  rapidjson::Value keyName(str(boost::format{"Layer%1%"} % layer).c_str(), alloc);
280  metaTree.AddMember(keyName,
281  layerDescTree, alloc);
282  }
283 
284  // ptree truthTriggerFlagTree;
285  rapidjson::Value truthTriggerFlagTree(rapidjson::kObjectType);
286 
287  truthTriggerFlagTree.AddMember("Description",
288  "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.",
289  alloc);
290  // truthTriggerFlagTree.AddMember("ExampleSignal1", true, alloc);
291  // truthTriggerFlagTree.AddMember("ExampleSignal2", false, alloc);
292  rapidjson::Value flagsTree(rapidjson::kObjectType);
293  if (m_Flags)
294  {
295  auto range = m_Flags->get_iparam_iters();
296 
297  for (auto flagIter = range.first; flagIter != range.second; ++flagIter)
298  {
299 // rapidjson::Value aFlag(rapidjson::kObjectType);
300 
301  const string& name = flagIter->first;
302  rapidjson::Value keyName(name.c_str(), alloc);
303  const bool flag = flagIter->second > 0 ? true : false;
304 
305  flagsTree.AddMember(keyName, flag, alloc);
306 // flagsTree.PushBack(aFlag, alloc);
307  }
308  }
309  truthTriggerFlagTree.AddMember("Flags", flagsTree, alloc);
310 
311  // Raw hits
312  // ptree rawHitTree;
313  rapidjson::Value rawHitTree(rapidjson::kObjectType);
314  rawHitTree.AddMember("Description",
315  "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.",
316  alloc);
317 
318  // rawHitTree.put("LayerRage", "0-2");
319 
320  // ptree rawHitsTree;
321  rapidjson::Value rawHitsTree(rapidjson::kArrayType);
322 
323  set<unsigned int> mapsHits; //internal consistency check for later stages of truth tracks
324  assert(m_hitMap);
325  for (SvtxHitMap::Iter iter = m_hitMap->begin();
326  iter != m_hitMap->end();
327  ++iter)
328  {
329  SvtxHit* hit = iter->second;
330  assert(hit);
331  unsigned int layer = hit->get_layer();
332  if (layer < _nlayers_maps)
333  {
334  unsigned int hitID = hit->get_id();
335  mapsHits.insert(hitID);
336 
337  PHG4Cell* cell = hiteval->get_cell(hit);
338  assert(cell);
339  PHG4CylinderGeom_MVTX* geom = dynamic_cast<PHG4CylinderGeom_MVTX*>(m_Geoms->GetLayerGeom(layer));
340  assert(geom);
341 
342  TVector3 local_coords = geom->get_local_coords_from_pixel(cell->get_pixel_index());
343  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);
344 
345  unsigned int pixel_x(cell->get_pixel_index() % geom->get_NX());
346  unsigned int pixel_z(cell->get_pixel_index() / geom->get_NX());
347  unsigned int halflayer = (int) pixel_x >= geom->get_NX() / 2 ? 0 : 1;
348 
349  assert((int) pixel_x < geom->get_NX());
350  assert((int) pixel_z < geom->get_NZ());
351 
352  unsigned int halfLayerIndex(layer * 2 + halflayer);
353  unsigned int pixelPhiIndex(
354  cell->get_stave_index() * geom->get_NX() + pixel_x);
355  unsigned int pixelPhiIndexHL(
356  cell->get_stave_index() * geom->get_NX() / 2 + pixel_x % (geom->get_NX() / 2));
357  unsigned int pixelZIndex(cell->get_chip_index() * geom->get_NZ() + pixel_z);
358 
359  // ptree hitTree;
360  rapidjson::Value hitTree(rapidjson::kObjectType);
361 
362  // ptree hitIDTree;
363  rapidjson::Value hitIDTree(rapidjson::kObjectType);
364  hitIDTree.AddMember("HitSequenceInEvent", hitID, alloc);
365 
366  hitIDTree.AddMember("PixelHalfLayerIndex", halfLayerIndex, alloc);
367  hitIDTree.AddMember("PixelPhiIndexInLayer", pixelPhiIndex, alloc);
368  hitIDTree.AddMember("PixelPhiIndexInHalfLayer", pixelPhiIndexHL, alloc);
369  hitIDTree.AddMember("PixelZIndex", pixelZIndex, alloc);
370 
371  hitIDTree.AddMember("Layer", layer, alloc);
372  hitIDTree.AddMember("HalfLayer", halflayer, alloc);
373  hitIDTree.AddMember("Stave", cell->get_stave_index(), alloc);
374  // hitIDTree.put("HalfStave", cell->get_half_stave_index());
375  // hitIDTree.put("Module", cell->get_module_index());
376  hitIDTree.AddMember("Chip", cell->get_chip_index(), alloc);
377  hitIDTree.AddMember("Pixel", cell->get_pixel_index(), alloc);
378  hitTree.AddMember("ID", hitIDTree, alloc);
379 
380  hitTree.AddMember("Coordinate",
381  loadCoordinate(world_coords.x(),
382  world_coords.y(),
383  world_coords.z()),
384  alloc);
385 
386  // rawHitsTree.add_child("MVTXHit", hitTree);
387  rawHitsTree.PushBack(hitTree, alloc);
388 
389  m_hitStaveLayer->Fill(cell->get_stave_index(), halfLayerIndex);
391  m_hitChipModule->Fill(cell->get_chip_index(), cell->get_module_index());
392 
393  m_hitLayerMap->Fill(world_coords.x(), world_coords.y(), halfLayerIndex);
394  m_hitPixelPhiMap->Fill(pixelPhiIndex, atan2(world_coords.y(), world_coords.x()), halfLayerIndex);
395  m_hitPixelPhiMapHL->Fill(pixelPhiIndexHL, atan2(world_coords.y(), world_coords.x()), halfLayerIndex);
396  m_hitPixelZMap->Fill(pixelZIndex, world_coords.z(), halfLayerIndex);
397  } // if (layer < _nlayers_maps)
398 
399  } // for (SvtxHitMap::Iter iter = m_hitMap->begin();
400  rawHitTree.AddMember("MVTXHits", rawHitsTree, alloc);
401 
402  // Truth hits
403  // ptree truthHitTree;
404  rapidjson::Value truthHitTree(rapidjson::kObjectType);
405  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.",
406  alloc);
407 
409 
410  // ptree truthTracksTree;
411  rapidjson::Value truthTracksTree(rapidjson::kArrayType);
412 
414  for (PHG4TruthInfoContainer::ConstIterator iter = range.first;
415  iter != range.second;
416  ++iter)
417  {
418  PHG4Particle* g4particle = iter->second;
419  assert(g4particle);
420 
421  std::set<SvtxCluster*> g4clusters = clustereval->all_clusters_from(g4particle);
422 
423  // ptree trackHitTree;
424  rapidjson::Value trackHitTree(rapidjson::kArrayType);
425  unsigned int nMAPS(0);
426 
427  for (const SvtxCluster* cluster : g4clusters)
428  {
429  assert(cluster);
430  unsigned int layer = cluster->get_layer();
431  if (layer < _nlayers_maps)
432  {
433  ++nMAPS;
434 
435  for (SvtxCluster::ConstHitIter hiter = cluster->begin_hits();
436  hiter != cluster->end_hits();
437  ++hiter)
438  {
439  // SvtxHit* hit = _hitmap->get(*hiter);
440  unsigned int hitID = *hiter;
441  assert(mapsHits.find(hitID) != mapsHits.end());
442 
443  // ptree hitIDTree;
444  // hitIDTree.put("", hitID);
445  trackHitTree.PushBack(hitID, alloc);
446  }
447  }
448 
449  } // for (const SvtxCluster* cluster : g4clusters)
450 
451  if (nMAPS > 1)
452  {
453  // ptree trackTree;
454  rapidjson::Value trackTree(rapidjson::kObjectType);
455  trackTree.AddMember("TrackSequenceInEvent", g4particle->get_track_id(), alloc);
456  trackTree.AddMember("HitSequenceInEvent", trackHitTree, alloc);
457 
458  trackTree.AddMember("ParticleTypeID", g4particle->get_pid(), alloc);
459  trackTree.AddMember("TrackMomentum",
460  loadCoordinate(g4particle->get_px(),
461  g4particle->get_py(),
462  g4particle->get_pz()),
463  alloc);
464  // trackTree.put("TrackDCA3DXY", track->get_dca3d_xy());
465  // trackTree.put("TrackDCA3DZ", track->get_dca3d_z());
466 
467  // trackTree.add_child("TruthHit", trackHitTree);
468 
469  // truthTracksTree.add_child("TruthTrack", trackTree);
470  truthTracksTree.PushBack(trackTree, alloc);
471  } // if (nMAPS > 1)
472 
473  } // for (PHG4TruthInfoContainer::ConstIterator iter = range.first;
474  truthHitTree.AddMember("TruthTracks", truthTracksTree, alloc);
475 
476  //output
477  d.AddMember("MetaData", metaTree, alloc);
478  d.AddMember("TruthTriggerFlag", truthTriggerFlagTree, alloc);
479  d.AddMember("RawHit", rawHitTree, alloc);
480  d.AddMember("TruthHit", truthHitTree, alloc);
481 
482  assert(m_jsonOut.is_open());
483 
484  if (_ievent > 0)
485  {
486  m_jsonOut << "," << endl;
487  }
488 
489  // write_json(m_jsonOut, pTree);
490  // write_xml(m_jsonOut, jsonTree);
491 
492  // d.AddMember("Test", 1, d.GetAllocator());
493 
494  rapidjson::OStreamWrapper osw(m_jsonOut);
495  rapidjson::PrettyWriter<rapidjson::OStreamWrapper> writer(osw);
496 
497  d.Accept(writer);
498 
499  ++_ievent;
500 
502 }
503 
505 {
506  if (_f)
507  {
508  _f->cd();
509  _f->Write();
510  //_f->Close();
511 
512  // m_hitLayerMap->Write();
513  }
514 
515  if (m_jsonOut.is_open())
516  {
517  m_jsonOut << "]" << endl;
518  m_jsonOut << "}" << endl;
519 
520  m_jsonOut.close();
521  }
522 
523  cout << "HFMLTriggerInterface::End - output to " << _foutname << ".*" << endl;
524 
526 }