Class Reference for E1039 Core & Analysis Software
Fun4AllRUSOutputManager.cc
Go to the documentation of this file.
1 #include <cstdlib>
2 #include <string>
3 #include <iostream>
4 #include <iomanip>
5 #include <TSystem.h>
6 #include <TFile.h>
7 #include <TTree.h>
8 #include <phool/phool.h>
9 #include <phool/getClass.h>
10 #include <phool/PHNode.h>
11 #include <phool/PHNodeIOManager.h>
12 #include <interface_main/SQEvent.h>
13 #include <interface_main/SQRun.h>
14 #include <ktracker/SRecEvent.h>
21 
22 using namespace std;
23 
25  : Fun4AllOutputManager(myname),
26  process_id(14),
27  source_flag(1),
28  mc_truth_mode(false),
29  write_sq_event_info(true),
30  m_tree_name("tree"),
31  m_file_name("output.root"),
32  m_file(0),
33  m_tree(0),
34  m_evt(0),
35  m_vec_trk(0),
36  m_sp_map(0),
37  sq_run(0),
38  m_compression_level(5),
39  m_basket_size(64000),
40  m_auto_flush(2500),
41  m_hit_vec(0),
42  runID(0),
43  spillID(0),
44  eventID(0),
45  turnID(0),
46  rfID(0)
47 {
48  ;
49 }
50 
52  CloseFile();
53 }
54 
56  std::cout << "Fun4AllRUSOutputManager::OpenFile(): Attempting to open file: "
57  << m_file_name << " with tree: " << m_tree_name << std::endl;
58  // Create output ROOT file
59  m_file = new TFile(m_file_name.c_str(), "RECREATE");
60  m_file->SetCompressionAlgorithm(ROOT::kLZMA);
61  m_file->SetCompressionLevel(m_compression_level);
62 
63  if (!m_file || m_file->IsZombie()) {
64  std::cerr << "Error: Could not create file " << m_file_name << std::endl;
65  exit(1);
66  }
67  std::cout << "File " << m_file->GetName() << " opened successfully." << std::endl;
68 
69  m_tree = new TTree(m_tree_name.c_str(), "Tree for storing events");
70  if (!m_tree) {
71  std::cerr << "Error: Could not create tree " << m_tree_name << std::endl;
72  exit(1);
73  }
74  std::cout << "Tree " << m_tree->GetName() << " created successfully." << std::endl;
75 
76  // Basic event-level branches
77  m_tree->Branch("runID", &runID, "runID/I");
78  m_tree->Branch("eventID", &eventID, "eventID/I");
79 
80  if (write_sq_event_info) {
81  m_tree->Branch("spillID", &spillID, "spillID/I");
82  m_tree->Branch("rfID", &rfID, "rfID/I");
83  m_tree->Branch("turnID", &turnID, "turnID/I");
84  m_tree->Branch("rfIntensity", rfIntensity, "rfIntensity[33]/I");
85  m_tree->Branch("fpgaTrigger", fpgaTrigger, "fpgaTrigger[5]/I");
86  m_tree->Branch("nimTrigger", nimTrigger, "nimTrigger[5]/I");
87  }
88 
89  // Always-present hit-level branches
90  m_tree->Branch("hitID", &hitID);
91  m_tree->Branch("hitTrackID", &hitTrackID);
92  m_tree->Branch("detectorID", &detectorID);
93  m_tree->Branch("elementID", &elementID);
94  m_tree->Branch("tdcTime", &tdcTime);
95  m_tree->Branch("driftDistance", &driftDistance);
96 
97  // Find nodes in the Fun4All
98  m_evt = findNode::getClass<SQEvent>(startNode, "SQEvent");
99  m_hit_vec = findNode::getClass<SQHitVector>(startNode, "SQHitVector");
100  m_vec_trk = findNode::getClass<SQTrackVector>(startNode, "SQTruthTrackVector");
101 
102  // Automatically enable MC truth mode if SQTruthTrackVector is found
103  if (m_vec_trk != nullptr) {
104  mc_truth_mode = true;
105  std::cout << "Detected SQTruthTrackVector node -enabling MC truth output." << std::endl;
106 
107  m_tree->Branch("gProcessID", &gProcessID);
108  m_tree->Branch("gCharge", &gCharge);
109  m_tree->Branch("gTrackID", &gTrackID);
110  m_tree->Branch("gvx", &gvx);
111  m_tree->Branch("gvy", &gvy);
112  m_tree->Branch("gvz", &gvz);
113  m_tree->Branch("gpx", &gpx);
114  m_tree->Branch("gpy", &gpy);
115  m_tree->Branch("gpz", &gpz);
116 
117  m_tree->Branch("gx_st1", &gx_st1);
118  m_tree->Branch("gy_st1", &gy_st1);
119  m_tree->Branch("gz_st1", &gz_st1);
120  m_tree->Branch("gpx_st1", &gpx_st1);
121  m_tree->Branch("gpy_st1", &gpy_st1);
122  m_tree->Branch("gpz_st1", &gpz_st1);
123 
124  m_tree->Branch("gx_st3", &gx_st3);
125  m_tree->Branch("gy_st3", &gy_st3);
126  m_tree->Branch("gz_st3", &gz_st3);
127  m_tree->Branch("gpx_st3", &gpx_st3);
128  m_tree->Branch("gpy_st3", &gpy_st3);
129  m_tree->Branch("gpz_st3", &gpz_st3);
130  } else {
131  mc_truth_mode = false;
132  std::cout << "No SQTruthTrackVector node found -writing data-mode output only." << std::endl;
133  }
134 
135  // Finalize tree configuration
136  m_tree->SetAutoFlush(m_auto_flush);
137  m_tree->SetBasketSize("*", m_basket_size);
138 
139  // Sanity checks
140  if (!m_evt || !m_hit_vec) {
141  std::cerr << "Error: Missing SQEvent or SQHitVector nodes in the node tree." << std::endl;
143  }
144 
146 }
147 
149  if (!m_file || !m_tree) {
150  OpenFile(startNode);
151  }
152 
153  if (write_sq_event_info){
154  runID = m_evt->get_run_id();
155  spillID = m_evt->get_spill_id();
156  eventID = m_evt->get_event_id();
157  turnID = m_evt->get_qie_turn_id();
158  rfID = m_evt->get_qie_rf_id ();
159 
160  fpgaTrigger[0] = m_evt->get_trigger(SQEvent::MATRIX1);
161  fpgaTrigger[1] = m_evt->get_trigger(SQEvent::MATRIX2);
162  fpgaTrigger[2] = m_evt->get_trigger(SQEvent::MATRIX3);
163  fpgaTrigger[3] = m_evt->get_trigger(SQEvent::MATRIX4);
164  fpgaTrigger[4] = m_evt->get_trigger(SQEvent::MATRIX5);
165 
166  nimTrigger[0] = m_evt->get_trigger(SQEvent::NIM1);
167  nimTrigger[1] = m_evt->get_trigger(SQEvent::NIM2);
168  nimTrigger[2] = m_evt->get_trigger(SQEvent::NIM3);
169  nimTrigger[3] = m_evt->get_trigger(SQEvent::NIM4);
170  nimTrigger[4] = m_evt->get_trigger(SQEvent::NIM5);
171  for (int i = -16; i <= 16; ++i) {
172  rfIntensity[i+ 16] = m_evt->get_qie_rf_intensity(i);
173  }
174  }
175  if (!mc_truth_mode) {
177  for (int ihit = 0; ihit < m_hit_vec->size(); ++ihit) {
178  SQHit* hit = m_hit_vec->at(ihit);
179  hitTrackID.push_back(hit->get_track_id());
180  hitID.push_back(hit->get_hit_id());
181  detectorID.push_back(hit->get_detector_id());
182  elementID.push_back(hit->get_element_id());
183  tdcTime.push_back(hit->get_tdc_time());
184  driftDistance.push_back(hit->get_drift_distance());
185  }
186  }
187  if(mc_truth_mode){
190  for (unsigned int ii = 0; ii < m_vec_trk->size(); ii++) {
191  SQTrack* trk = m_vec_trk->at(ii);
192 
193  gCharge.push_back(trk->get_charge());
194  gTrackID.push_back(trk->get_track_id());
195  gvx.push_back(trk->get_pos_vtx().X());
196  gvy.push_back(trk->get_pos_vtx().Y());
197  gvz.push_back(trk->get_pos_vtx().Z());
198  gpx.push_back(trk->get_mom_vtx().Px());
199  gpy.push_back(trk->get_mom_vtx().Py());
200  gpz.push_back(trk->get_mom_vtx().Pz());
201 
202  gx_st1.push_back(trk->get_pos_st1().X());
203  gy_st1.push_back(trk->get_pos_st1().Y());
204  gz_st1.push_back(trk->get_pos_st1().Z());
205  gpx_st1.push_back(trk->get_mom_st1().Px());
206  gpy_st1.push_back(trk->get_mom_st1().Py());
207  gpz_st1.push_back(trk->get_mom_st1().Pz());
208  gx_st3.push_back(trk->get_pos_st3().X());
209  gy_st3.push_back(trk->get_pos_st3().Y());
210  gz_st3.push_back(trk->get_pos_st3().Z());
211  gpx_st3.push_back(trk->get_mom_st3().Px());
212  gpy_st3.push_back(trk->get_mom_st3().Py());
213  gpz_st3.push_back(trk->get_mom_st3().Pz());
214 
215  double z = trk->get_pos_vtx().Z();
216  if (z <= -296. && z >= -304.) source_flag = 1; // target
217  else if (z >= 0. && z < 500) source_flag = 2; // dump
218  else if (z > -296. && z < 0.) source_flag = 3; // gap
219  else if (z < -304) source_flag = 0; // upstream
220 
221  for (int ihit = 0; ihit < m_hit_vec->size(); ++ihit) {
222  SQHit* hit = m_hit_vec->at(ihit);
223 
224  if(hit->get_track_id() != trk->get_track_id()) continue;
225  int process_id_ = (trk->get_charge() > 0) ? process_id : process_id + 10;
226  unsigned int encodedValue = EncodeProcess(process_id_, source_flag);
227  gProcessID.push_back(encodedValue);
228  hitID.push_back(hit->get_hit_id());
229  hitTrackID.push_back(hit->get_track_id());
230  detectorID.push_back(hit->get_detector_id());
231  elementID.push_back(hit->get_element_id());
232  tdcTime.push_back(hit->get_tdc_time());
233  driftDistance.push_back(hit->get_drift_distance());
234  }
235  }
236  }
237  m_tree->Fill();
238  return 0;
239 }
240 
242  if (!m_file) return;
243  std::cout << "Fun4AllRUSOutputManager::CloseFile(): Closing file: " << m_file_name << std::endl;
244  m_file->Write();
245  m_file->Close();
246  delete m_file;
247  m_file = nullptr;
248 }
249 
251  hitID.clear();
252  hitTrackID.clear();
253  detectorID.clear();
254  elementID.clear();
255  tdcTime.clear();
256  driftDistance.clear();
257 }
258 
260  gCharge.clear();
261  gTrackID.clear();
262  gvx.clear(); gvy.clear(); gvz.clear();
263  gpx.clear(); gpy.clear(); gpz.clear();
264  gx_st1.clear(); gy_st1.clear(); gz_st1.clear();
265  gpx_st1.clear(); gpy_st1.clear(); gpz_st1.clear();
266  gx_st3.clear(); gy_st3.clear(); gz_st3.clear();
267  gpx_st3.clear(); gpy_st3.clear(); gpz_st3.clear();
268  gProcessID.clear();
269 }
270 
271 
272 unsigned int Fun4AllRUSOutputManager::EncodeProcess(int processID, int sourceFlag) {
273  return ((sourceFlag & 0x3) << 5) | // 2 bits for sourceFlag (0-3)
274  (processID & 0x1F); // 5 bits for processID (0-31)
275 }
Fun4AllRUSOutputManager(const std::string &myname="UNIVERSALOUT")
unsigned int EncodeProcess(int processID, int sourceFlag)
int OpenFile(PHCompositeNode *startNode)
virtual int Write(PHCompositeNode *startNode)
write starting from given node
virtual int get_run_id() const =0
Return the run ID.
@ MATRIX2
Definition: SQEvent.h:28
@ NIM5
Definition: SQEvent.h:26
@ MATRIX1
Definition: SQEvent.h:27
@ NIM4
Definition: SQEvent.h:25
@ NIM2
Definition: SQEvent.h:23
@ NIM1
Definition: SQEvent.h:22
@ MATRIX3
Definition: SQEvent.h:29
@ NIM3
Definition: SQEvent.h:24
@ MATRIX4
Definition: SQEvent.h:30
@ MATRIX5
Definition: SQEvent.h:31
virtual int get_qie_rf_intensity(const short i) const =0
Return the i-th QIE RF intensity, where i=-16...+16.
virtual bool get_trigger(const SQEvent::TriggerMask i) const =0
Return the trigger bit (fired or not) of the selected trigger channel.
virtual int get_qie_turn_id() const =0
Return the QIE turn ID.
virtual int get_qie_rf_id() const =0
Return the QIE RF ID.
virtual int get_spill_id() const =0
Return the spill ID.
virtual int get_event_id() const =0
Return the event ID, which is unique per run.
virtual const SQHit * at(const size_t idkey) const =0
virtual size_t size() const =0
An SQ interface class to hold one detector hit.
Definition: SQHit.h:20
virtual float get_drift_distance() const
Return the drift distance of this hit. Probably the value is not properly set at present....
Definition: SQHit.h:57
virtual short get_element_id() const
Return the element ID of this hit.
Definition: SQHit.h:45
virtual int get_hit_id() const
Return the ID of this hit.
Definition: SQHit.h:39
virtual float get_tdc_time() const
Return the TDC time (nsec) of this hit.
Definition: SQHit.h:54
virtual short get_detector_id() const
Return the detector ID of this hit.
Definition: SQHit.h:42
virtual int get_track_id() const
Return the track ID associated with this hit. Probably the value is not properly set at present.
Definition: SQHit.h:66
virtual const SQTrack * at(const size_t id) const =0
virtual size_t size() const =0
An SQ interface class to hold one true or reconstructed track.
Definition: SQTrack.h:8
virtual int get_track_id() const =0
Return the track ID, which is unique per event(?).
virtual TVector3 get_pos_vtx() const =0
Return the track position at vertex.
virtual int get_charge() const =0
Return the charge, i.e. +1 or -1.
virtual TLorentzVector get_mom_vtx() const =0
Return the track momentum at vertex.
virtual TLorentzVector get_mom_st1() const =0
Return the track momentum at Station 1.
virtual TVector3 get_pos_st3() const =0
Return the track position at Station 3.
virtual TVector3 get_pos_st1() const =0
Return the track position at Station 1.
virtual TLorentzVector get_mom_st3() const =0
Return the track momentum at Station 3.