Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MicromegasRawDataEvaluation.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MicromegasRawDataEvaluation.cc
1 
7 #include "MicromegasDefs.h"
8 
9 #include <Event/Event.h>
10 #include <Event/EventTypes.h>
11 #include <Event/packet.h>
12 
14 
15 #include <phool/getClass.h>
16 #include <phool/PHCompositeNode.h>
17 
18 #include <TFile.h>
19 #include <TH1.h>
20 #include <TH2.h>
21 #include <TProfile.h>
22 
23 #include <cassert>
24 #include <fstream>
25 #include <list>
26 #include <memory>
27 #include <set>
28 
29 namespace
30 {
31  // streamer for lists
32  template< class T >
33  std::ostream& operator << ( std::ostream& out, const std::list<T>& list )
34  {
35  if( list.empty() ) out << "{}";
36  else
37  {
38  out << "{ ";
39  bool first = true;
40  for( const auto& value:list )
41  {
42  if( !first ) out << ", ";
43  out << value;
44  first = false;
45  }
46  out << " }";
47  }
48  return out;
49  }
50 }
51 
52 //_________________________________________________________
54 {
55  packet_id = sample.packet_id;
56  lvl1_bco = sample.lvl1_bco;
57  fee_bco = sample.fee_bco;
58  checksum = sample.checksum;
60  fee_id = sample.fee_id;
61  layer = sample.layer;
62  tile = sample.tile;
65  channel = sample.channel;
66  strip = sample.strip;
67  sample_max = sample.sample;
68  adc_max = sample.adc;
69  pedestal = sample.pedestal;
70  rms = sample.rms;
71 }
72 
73 //_________________________________________________________
75 {
76  n_tagger.clear();
77  n_waveform.clear();
78  samples.clear();
79  waveforms.clear();
80  lvl1_bco_list.clear();
81  lvl1_count_list.clear();
82 }
83 
84 //_________________________________________________________
86  SubsysReco( name )
87 {}
88 
89 //_____________________________________________________________________
91 {
92  // read calibrations
94 
95  m_evaluation_file.reset( new TFile( m_evaluation_filename.c_str(), "RECREATE" ) );
96  m_evaluation_tree = new TTree( "T", "T" );
97  m_container = new Container;
98  m_evaluation_tree->Branch( "Event", &m_container );
100 }
101 
102 //____________________________________________________________________________..
105 
106 //___________________________________________________________________________
108 {
109  // load relevant nodes
110  // PRDF node
111  auto event = findNode::getClass<Event>(topNode, "PRDF");
112  assert( event );
113 
114  // check event type
115  if(event->getEvtType() >= 8)
117 
118  m_container->Reset();
119 
120  // temporary storage for samples and waveforms, sorted by lvl1 bco
121  std::multimap<uint64_t, Sample> sample_map;
122  std::multimap<uint64_t, Waveform> waveform_map;
123 
124  // loop over TPOT packets
125  for( const auto& packet_id:MicromegasDefs::m_packet_ids )
126  {
127  std::unique_ptr<Packet> packet( event->getPacket(packet_id) );
128  if( !packet )
129  {
130  // no data
131  if( Verbosity() > 1 )
132  { std::cout << "MicromegasRawDataEvaluation::process_event - packet " << packet_id << " not found." << std::endl; }
133  continue;
134  }
135 
136  // taggers
137  int n_tagger = packet->lValue(0, "N_TAGGER");
138  m_container->n_tagger.push_back(n_tagger);
139 
140  // get number of datasets (also call waveforms)
141  const auto n_waveform = packet->iValue(0, "NR_WF" );
142  m_container->n_waveform.push_back(n_waveform);
143 
144  // store tagged lvl1 bcos into a vector
145  using bco_list_t = std::list<uint64_t>;
146  bco_list_t main_bco_list;
147  for (int t = 0; t < n_tagger; t++)
148  {
149  const auto is_lvl1 = static_cast<uint8_t>(packet->lValue(t, "IS_LEVEL1_TRIGGER"));
150  const auto bco = static_cast<uint64_t>(packet->lValue(t, "BCO"));
151  const auto lvl1_count = static_cast<uint32_t>(packet->lValue(t, "LEVEL1_COUNT"));
152  if( is_lvl1 )
153  {
154  main_bco_list.push_back( bco );
155 
156  // also store in evaluation container
157  m_container->lvl1_bco_list.push_back(bco);
158  m_container->lvl1_count_list.push_back(lvl1_count);
159  }
160  }
161 
162  if( Verbosity() )
163  {
164  std::cout << "MicromegasRawDataEvaluation::process_event -"
165  << " packet: " << packet_id
166  << " n_lvl1_bco: " << main_bco_list.size()
167  << " n_waveform: " << n_waveform
168  << std::endl;
169 
170  std::cout << "MicromegasRawDataEvaluation::process_event -"
171  << " packet: " << packet_id
172  << " bco: " << std::hex << main_bco_list << std::dec
173  << std::endl;
174 
175  }
176 
177  // store available bco list for each fee
178  std::map<unsigned short, bco_list_t> bco_list_map;
179 
180  // keep track of orphans
181  using fee_pair_t = std::pair< unsigned int, unsigned int>;
182  std::set<fee_pair_t> orphans;
183 
184  for( int iwf=0; iwf<n_waveform; ++iwf )
185  {
186  // create running sample, assign packet, fee, layer and tile id
187  Sample sample;
188  sample.packet_id = packet_id;
189  sample.fee_id = packet->iValue(iwf, "FEE" );
190  const auto hitsetkey = m_mapping.get_hitsetkey(sample.fee_id);
191  sample.layer = TrkrDefs::getLayer( hitsetkey );
193 
194  // beam crossing, checksum, checksum error
195  sample.fee_bco = packet->iValue(iwf, "BCO");
196  sample.lvl1_bco = 0;
197 
198  // find bco matching map corresponding to fee
199  auto& bco_matching_pair = m_fee_bco_matching_map[sample.fee_id];
200 
201  // find matching lvl1 bco
202  if( bco_matching_pair.first == sample.fee_bco )
203  {
204 
205  sample.lvl1_bco = bco_matching_pair.second;
206 
207  } else {
208 
209  // find bco list corresponding to fee, insert main list if not found
210  auto bco_list_iter = bco_list_map.lower_bound( sample.fee_id );
211  if( bco_list_iter == bco_list_map.end() || sample.fee_id < bco_list_iter->first )
212  { bco_list_iter = bco_list_map.insert( bco_list_iter, std::make_pair( sample.fee_id, main_bco_list ) ); }
213 
214  // get local reference to fee's bco list
215  auto& bco_list = bco_list_iter->second;
216  if( !bco_list.empty() )
217  {
218 
219  if( Verbosity() )
220  {
221  std::cout << "MicromegasRawDataEvaluation::process_event -"
222  << " fee_id: " << sample.fee_id
223  << " fee_bco: 0x" << std::hex << sample.fee_bco
224  << " gtm_bco: 0x" << bco_list.front()
225  << std::dec
226  << std::endl;
227  }
228 
229  // fee_bco is new. Assume it corresponds to the first available lvl1 bco
230  // update running fee_bco and lvl1_bco pair accordingly
231  const auto lvl1_bco = bco_list.front();
232  bco_matching_pair.first = sample.fee_bco;
233  bco_matching_pair.second = lvl1_bco;
234  sample.lvl1_bco = lvl1_bco;
235 
236  // remove bco from running list
237  bco_list.pop_front();
238 
239  } else {
240 
241  if( Verbosity() && orphans.insert( std::make_pair( sample.fee_id, sample.fee_bco ) ).second )
242  {
243  std::cout << "MicromegasRawDataEvaluation::process_event -"
244  << " fee_id: " << sample.fee_id
245  << " fee_bco: 0x" << std::hex << sample.fee_bco << std::dec
246  << " gtm_bco: none"
247  << std::endl;
248  }
249  }
250  }
251 
252  sample.checksum = packet->iValue(iwf, "CHECKSUM");
253  sample.checksum_error = packet->iValue(iwf, "CHECKSUMERROR");
254 
255  // increment bco map
256  ++m_bco_map[sample.lvl1_bco];
257 
258  // channel, sampa_channel, sampa address and strip
259  sample.sampa_address = packet->iValue( iwf, "SAMPAADDRESS" );
260  sample.sampa_channel = packet->iValue( iwf, "SAMPACHANNEL" );
261  sample.channel = packet->iValue( iwf, "CHANNEL" );
262  sample.strip = m_mapping.get_physical_strip(sample.fee_id, sample.channel);
263 
264  // get channel rms and pedestal from calibration data
265  const double pedestal = m_calibration_data.get_pedestal( sample.fee_id, sample.channel );
266  const double rms = m_calibration_data.get_rms( sample.fee_id, sample.channel );
267  sample.pedestal = pedestal;
268  sample.rms = rms;
269 
270  // get number of samples and loop
271  const unsigned short samples = packet->iValue( iwf, "SAMPLES" );
272  if( Verbosity() > 1 )
273  {
274  std::cout << "MicromegasRawDataEvaluation::process_event -"
275  << " fee: " << sample.fee_id
276  << " tile: " << sample.tile
277  << " layer: " << sample.layer
278  << " tile: " << sample.tile
279  << " lvl1_bco: " << sample.lvl1_bco
280  << " fee_bco: " << sample.fee_bco
281  << " error: " << sample.checksum_error
282  << " channel: " << sample.channel
283  << " strip: " << sample.strip
284  << " samples: " << samples
285  << std::endl;
286  }
287 
288  Sample sample_max;
289  for( unsigned short is = 0; is < std::min<unsigned short>( samples, 100 ); ++is )
290  {
291  // assign sample id and corresponding adc, save copy in container
292  unsigned short adc = packet->iValue(iwf,is);
293  sample.sample = is;
294  sample.adc = adc;
295  sample_map.emplace( sample.lvl1_bco, sample );
296 
297  if( sample.adc > sample_max.adc )
298  { sample_max = sample; }
299 
300  }
301 
302  Waveform waveform( sample_max );
303 
304  waveform.is_signal =
305  rms > 0 &&
306  waveform.adc_max >= m_min_adc &&
307  waveform.sample_max >= m_sample_min &&
308  waveform.sample_max < m_sample_max &&
309  waveform.adc_max > pedestal+m_n_sigma * rms;
310 
311  waveform_map.emplace( waveform.lvl1_bco, waveform );
312  }
313  }
314 
315  // copy all samples and waveform to container
316  for( auto&& [lvl_bco, sample]:sample_map )
317  { m_container->samples.push_back(std::move(sample)); }
318 
319  for( auto&& [lvl1_bco, waveform]:waveform_map )
320  { m_container->waveforms.push_back(std::move(waveform)); }
321 
322  // fill evaluation tree
323  m_evaluation_tree->Fill();
324 
326 }
327 
328 //_____________________________________________________________________
330 {
332  {
333  m_evaluation_file->cd();
334  m_evaluation_tree->Write();
335  m_evaluation_file->Close();
336  }
337 
338  // print bco map
339  if( Verbosity() )
340  for( const auto& [bco,nwaveforms]:m_bco_map )
341  { std::cout << "MicromegasRawDataEvaluation::End - bco: 0x" << std::hex << bco << std::dec << ", nwaveforms: " << nwaveforms << std::endl; }
342 
343  // print bco list, for offline processing
344  {
345  std::cout << "const std::vector<uint64_t> lvl1_bco_list = {" << std::endl;
346  bool first = true;
347  int count = 0;
348  for( const auto& [bco,nwaveforms]:m_bco_map )
349  {
350  if( !first ) std::cout << ", ";
351  first = false;
352  if( count == 10 )
353  {
354  count = 0;
355  std::cout << std::endl;
356  }
357  std::cout << " 0x" << std::hex << bco << std::dec;
358  ++count;
359  }
360  std::cout << std::endl << "};" << std::endl;
361  }
362 
364 }