Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SingleMicromegasPoolInput.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SingleMicromegasPoolInput.cc
2 
4 
7 
8 #include <frog/FROG.h>
9 
10 #include <phool/PHCompositeNode.h>
11 #include <phool/PHNodeIterator.h> // for PHNodeIterator
12 #include <phool/getClass.h>
13 #include <phool/phool.h>
14 
15 #include <Event/Event.h>
16 #include <Event/EventTypes.h>
17 #include <Event/Eventiterator.h>
18 #include <Event/fileEventiterator.h>
19 
20 #include <memory>
21 #include <set>
22 
23 namespace
24 {
25  // streamer for lists
26  template <class T>
27  std::ostream& operator<<(std::ostream& out, const std::list<T>& list)
28  {
29  if (list.empty())
30  {
31  out << "{}";
32  }
33  else
34  {
35  out << "{ ";
36  bool first = true;
37  for (const auto& value : list)
38  {
39  if (!first)
40  {
41  out << ", ";
42  }
43  out << value;
44  first = false;
45  }
46  out << " }";
47  }
48  return out;
49  }
50 
51  // minimum number of requested samples
52  static constexpr int m_min_req_samples = 5;
53 
54 } // namespace
55 
56 //______________________________________________________________
58  : SingleStreamingInput(name)
59 {
61  plist = new Packet*[10];
62 }
63 
64 //______________________________________________________________
66 {
67  delete[] plist;
68 }
69 
70 //______________________________________________________________
71 void SingleMicromegasPoolInput::FillPool(const unsigned int /*nbclks*/)
72 {
73  if (AllDone()) // no more files and all events read
74  {
75  return;
76  }
77 
78  while (!GetEventiterator()) // at startup this is a null pointer
79  {
80  if (!OpenNextFile())
81  {
82  AllDone(1);
83  return;
84  }
85  }
86 
87  while (GetSomeMoreEvents())
88  {
89  std::unique_ptr<Event> evt(GetEventiterator()->getNextEvent());
90  while (!evt)
91  {
92  fileclose();
93  if (!OpenNextFile())
94  {
95  AllDone(1);
96  return;
97  }
98 
99  // get next event
100  evt.reset(GetEventiterator()->getNextEvent());
101  }
102 
103  if (Verbosity() > 2)
104  {
105  std::cout << "Fetching next Event" << evt->getEvtSequence() << std::endl;
106  }
107 
108  RunNumber(evt->getRunNumber());
109  if (Verbosity() > 1)
110  {
111  evt->identify();
112  }
113 
114  if (evt->getEvtType() != DATAEVENT)
115  {
117  continue;
118  }
119 
120  const int EventSequence = evt->getEvtSequence();
121  const int npackets = evt->getPacketList(plist, 10);
122 
123  if (npackets == 10)
124  {
125  std::cout << "SingleMicromegasPoolInput::FillPool - too many packets" << std::endl;
126  exit(1);
127  }
128 
129  for (int i = 0; i < npackets; i++)
130  {
131  // keep pointer to local packet
132  auto& packet = plist[i];
133 
134  // get packet id
135  const auto packet_id = packet->getIdentifier();
136 
137  if (Verbosity() > 1)
138  {
139  packet->identify();
140  }
141 
142  // loop over taggers
143  const int ntagger = packet->lValue(0, "N_TAGGER");
144  for (int t = 0; t < ntagger; t++)
145  {
146  // only store gtm_bco for level1 type of taggers (not ENDDAT)
147  const auto is_lvl1 = static_cast<uint8_t>(packet->lValue(t, "IS_LEVEL1_TRIGGER"));
148  if (is_lvl1)
149  {
150  // get gtm_bco
151  const auto gtm_bco = static_cast<uint64_t>(packet->lValue(t, "BCO"));
152 
153  // store as available bco for all FEE's bco alignment objects
154  for (auto&& bco_alignment : m_bco_alignment_list)
155  {
156  bco_alignment.gtm_bco_list.push_back(gtm_bco);
157  }
158  }
159  }
160 
161  // loop over waveforms
162  const int nwf = packet->iValue(0, "NR_WF");
163 
164  if (Verbosity())
165  {
166  std::cout << "SingleMicromegasPoolInput::FillPool -"
167  << " packet: " << packet_id
168  << " n_lvl1_bco: " << m_bco_alignment_list[0].gtm_bco_list.size()
169  << " n_waveform: " << nwf
170  << std::endl;
171 
172  std::cout << "SingleMicromegasPoolInput::FillPool -"
173  << " packet: " << packet_id
174  << " bco: " << std::hex << m_bco_alignment_list[0].gtm_bco_list << std::dec
175  << std::endl;
176  }
177 
178  // keep track of orphans
179  using fee_pair_t = std::pair<unsigned int, unsigned int>;
180  std::set<fee_pair_t> orphans;
181 
182  for (int wf = 0; wf < nwf; wf++)
183  {
184  // get fee id
185  const int fee_id = packet->iValue(wf, "FEE");
186 
187  // get checksum_error and check
188  const auto checksum_error = packet->iValue(wf, "CHECKSUMERROR");
189  if (checksum_error)
190  {
191  continue;
192  }
193 
194  // get number of samples and check
195  const uint16_t samples = packet->iValue(wf, "SAMPLES");
196  if (samples < m_min_req_samples)
197  {
198  continue;
199  }
200 
201  // get fee bco
202  const unsigned int fee_bco = packet->iValue(wf, "BCO");
203 
204  // get matching gtm bco, from bco alignment object
205  uint64_t gtm_bco = 0;
206  auto&& bco_alignment = m_bco_alignment_list.at(fee_id);
207  if (bco_alignment.fee_bco == fee_bco)
208  {
209  // assign gtm bco
210  gtm_bco = bco_alignment.gtm_bco;
211  }
212  else if (!bco_alignment.gtm_bco_list.empty())
213  {
214  // get first available gtm_bco from list
215  gtm_bco = bco_alignment.gtm_bco_list.front();
216 
217  if (Verbosity())
218  {
219  std::cout << "SingleMicromegasPoolInput::FillPool -"
220  << " fee_id: " << fee_id
221  << " fee_bco: 0x" << std::hex << fee_bco
222  << " gtm_bco: 0x" << gtm_bco
223  << std::dec
224  << std::endl;
225  }
226 
227  // store as current gtm/fee bco
228  bco_alignment.fee_bco = fee_bco;
229  bco_alignment.gtm_bco = gtm_bco;
230 
231  // remove from list of availables gtm_bco
232  bco_alignment.gtm_bco_list.pop_front();
233  }
234  else
235  {
236  if (Verbosity() && orphans.insert(std::make_pair(fee_id, fee_bco)).second)
237  {
238  std::cout << "SingleMicromegasPoolInput::FillPool -"
239  << " fee_id: " << fee_id
240  << " fee_bco: 0x" << std::hex << fee_bco << std::dec
241  << " gtm_bco: none"
242  << std::endl;
243  }
244 
245  // skip the waverform
246  continue;
247  }
248 
249  // create new hit
250  auto newhit = std::make_unique<MicromegasRawHitv1>();
251  newhit->set_bco(fee_bco);
252  newhit->set_gtm_bco(gtm_bco);
253 
254  // packet id, fee id, channel, etc.
255  newhit->set_packetid(packet_id);
256  newhit->set_fee(fee_id);
257  newhit->set_channel(packet->iValue(wf, "CHANNEL"));
258  newhit->set_sampaaddress(packet->iValue(wf, "SAMPAADDRESS"));
259  newhit->set_sampachannel(packet->iValue(wf, "CHANNEL"));
260 
261  // assign samples
262  newhit->set_samples(samples);
263 
264  // adc values
265  for (uint16_t is = 0; is < samples; ++is)
266  {
267  newhit->set_adc(is, packet->iValue(wf, is));
268  }
269 
270  m_BeamClockFEE[gtm_bco].insert(fee_id);
271  m_FEEBclkMap[fee_id] = gtm_bco;
272  if (Verbosity() > 2)
273  {
274  std::cout << "evtno: " << EventSequence
275  << ", hits: " << wf
276  << ", num waveforms: " << nwf
277  << ", bco: 0x" << std::hex << gtm_bco << std::dec
278  << ", FEE: " << fee_id << std::endl;
279  }
280 
281  if (StreamingInputManager())
282  {
283  StreamingInputManager()->AddMicromegasRawHit(gtm_bco, newhit.get());
284  }
285 
286  m_MicromegasRawHitMap[gtm_bco].push_back(newhit.release());
287  m_BclkStack.insert(gtm_bco);
288  }
289 
290  // clear all stored bco list
291  for (auto&& bco_alignment : m_bco_alignment_list)
292  {
293  bco_alignment.gtm_bco_list.clear();
294  }
295 
296  delete packet;
297  }
298  }
299 }
300 
301 //______________________________________________________________
303 {
304  if (what == "ALL" || what == "FEE")
305  {
306  for (const auto& bcliter : m_BeamClockFEE)
307  {
308  std::cout << "Beam clock 0x" << std::hex << bcliter.first << std::dec << std::endl;
309  for (auto feeiter : bcliter.second)
310  {
311  std::cout << "FEM: " << feeiter << std::endl;
312  }
313  }
314  }
315 
316  if (what == "ALL" || what == "FEEBCLK")
317  {
318  for (auto bcliter : m_FEEBclkMap)
319  {
320  std::cout << "FEE" << bcliter.first << " bclk: 0x"
321  << std::hex << bcliter.second << std::dec << std::endl;
322  }
323  }
324 
325  if (what == "ALL" || what == "STORAGE")
326  {
327  for (const auto& bcliter : m_MicromegasRawHitMap)
328  {
329  std::cout << "Beam clock 0x" << std::hex << bcliter.first << std::dec << std::endl;
330  for (auto feeiter : bcliter.second)
331  {
332  std::cout
333  << "fee: " << feeiter->get_fee()
334  << " at " << std::hex << feeiter << std::dec
335  << std::endl;
336  }
337  }
338  }
339 
340  if (what == "ALL" || what == "STACK")
341  {
342  for (const auto& iter : m_BclkStack)
343  {
344  std::cout << "stacked bclk: 0x" << std::hex << iter << std::dec << std::endl;
345  }
346  }
347 }
348 
349 //____________________________________________________________________________
351 {
352  std::vector<uint64_t> toclearbclk;
353  for (const auto& iter : m_MicromegasRawHitMap)
354  {
355  if (iter.first <= bclk)
356  {
357  for (auto pktiter : iter.second)
358  {
359  delete pktiter;
360  }
361 
362  toclearbclk.push_back(iter.first);
363  }
364  else
365  {
366  break;
367  }
368  }
369 
370  for (auto iter : toclearbclk)
371  {
372  m_BclkStack.erase(iter);
373  m_BeamClockFEE.erase(iter);
374  m_MicromegasRawHitMap.erase(iter);
375  }
376 }
377 
378 //_______________________________________________________
380 {
381  uint64_t currentbclk = *m_BclkStack.begin();
382  CleanupUsedPackets(currentbclk);
383  return;
384 }
385 
386 //_______________________________________________________
388 {
389  if (AllDone())
390  {
391  return false;
392  }
393  if (m_MicromegasRawHitMap.empty())
394  {
395  return true;
396  }
397 
398  uint64_t lowest_bclk = m_MicromegasRawHitMap.begin()->first + m_BcoRange;
399  for (auto bcliter : m_FEEBclkMap)
400  {
401  if (bcliter.second <= lowest_bclk)
402  {
403  return true;
404  }
405  }
406 
407  return false;
408 }
409 
410 //_______________________________________________________
412 {
413  PHNodeIterator iter(topNode);
414  auto dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
415  if (!dstNode)
416  {
417  dstNode = new PHCompositeNode("DST");
418  topNode->addNode(dstNode);
419  }
420 
421  PHNodeIterator iterDst(dstNode);
422  auto detNode = dynamic_cast<PHCompositeNode*>(iterDst.findFirst("PHCompositeNode", "MICROMEGAS"));
423  if (!detNode)
424  {
425  detNode = new PHCompositeNode("MICROMEGAS");
426  dstNode->addNode(detNode);
427  }
428 
429  auto container = findNode::getClass<MicromegasRawHitContainer>(detNode, "MICROMEGASRAWHIT");
430  if (!container)
431  {
433  auto newNode = new PHIODataNode<PHObject>(container, "MICROMEGASRAWHIT", "PHObject");
434  detNode->addNode(newNode);
435  }
436 }
437 
438 //_______________________________________________________
440 {
441  if (StreamingInputManager())
442  {
445  }
446 }