All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ICARUSFlashAssAna_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: ICARUSFlashAssAna
3 // Plugin Type: analyzer (art v3_06_03)
4 // File: ICARUSFlashAssAna_module.cc
5 //
6 // Generated at Tue Jun 29 13:43:54 2021 by Andrea Scarpelli using cetskelgen
7 // from cetlib version v3_11_01.
8 //
9 // Module that dumps the assciation between Flashes and OpHit
10 //
11 // mailto:ascarpel@bnl.gov
12 ////////////////////////////////////////////////////////////////////////
13 
14 #include "art/Framework/Core/EDAnalyzer.h"
15 #include "art/Framework/Core/ModuleMacros.h"
16 #include "art/Framework/Principal/Event.h"
17 #include "art/Framework/Principal/Handle.h"
18 #include "art/Framework/Principal/Run.h"
19 #include "art/Framework/Principal/SubRun.h"
20 #include "canvas/Utilities/InputTag.h"
21 #include "fhiclcpp/ParameterSet.h"
22 #include "fhiclcpp/types/Atom.h"
23 #include "fhiclcpp/types/Sequence.h"
24 
25 #include "art_root_io/TFileService.h"
26 
27 #include "messagefacility/MessageLogger/MessageLogger.h"
28 
29 #include "canvas/Persistency/Common/FindMany.h"
30 #include "canvas/Persistency/Common/FindOne.h"
31 #include "canvas/Persistency/Common/FindManyP.h"
32 #include "canvas/Persistency/Common/FindOneP.h"
33 #include "canvas/Persistency/Common/Assns.h"
34 
36 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
43 
44 #include "TTree.h"
45 
46 #include <vector>
47 #include <map>
48 #include <numeric> // std::accumulate
49 
50 
51 
52 namespace opana {
53  class ICARUSFlashAssAna;
54 }
55 
56 
57 class opana::ICARUSFlashAssAna : public art::EDAnalyzer {
58 
59  public:
60 
61  struct Config {
62 
63  using Name = fhicl::Name;
64  using Comment = fhicl::Comment;
65 
66  fhicl::Atom<art::InputTag> TriggerLabel {
67  Name("TriggerLabel"),
68  Comment("Label for the Trigger fragment label")
69  };
70 
71  fhicl::Atom<bool> DumpWaveformsInfo {
72  Name("DumpWaveformsInfo"),
73  Comment("Set the option to save some aggregated waveform information")
74  };
75 
76  fhicl::Sequence<art::InputTag> OpDetWaveformLabels {
77  Name("OpDetWaveformLabels"),
78  Comment("Tags for the raw::OpDetWaveform data products")
79  };
80 
81  fhicl::Sequence<art::InputTag> OpHitLabels {
82  Name("OpHitLabels"),
83  Comment("Tags for the recob::OpHit data products")
84  };
85 
86  fhicl::Sequence<art::InputTag> FlashLabels {
87  Name("FlashLabels"),
88  Comment("Tags for the recob::Flashe data products")
89  };
90 
91  fhicl::Atom<float> PEOpHitThreshold {
92  Name("PEOpHitThreshold"),
93  Comment("Threshold in PE for an OpHit to be considered in the information calculated for a flash")
94  };
95 
96  fhicl::Atom<bool> Debug {
97  Name("Debug"),
98  Comment("Be more verbose"),
99  false
100  };
101 
102  };
103 
104  using Parameters = art::EDAnalyzer::Table<Config>;
105 
106  explicit ICARUSFlashAssAna(Parameters const& config);
107 
108  ICARUSFlashAssAna(ICARUSFlashAssAna const&) = delete;
112 
113  void analyze(art::Event const& e) override;
114 
115  void beginJob() override;
116  void endJob() override;
117 
118  template<typename T> T Median( std::vector<T> data ) const;
119 
121 
122  int getSideByChannel( const int channel );
123 
124  void processOpHits( art::Event const& e, unsigned int cryo );
125 
126  void processOpHitsFlash( std::vector<art::Ptr<recob::OpHit>> const &ophits,
127  int &multiplicity_left, int &multiplicity_right,
128  float &sum_pe_left, float &sum_pe_right,
129  float *xyz, TTree *ophittree );
130 
131  static std::string_view firstLine(std::string const& s, const char* endl = "\r");
132 
133  private:
134 
135  art::InputTag fTriggerLabel;
137  std::vector<art::InputTag> fOpDetWaveformLabels;
138  std::vector<art::InputTag> fOpHitLabels;
139  std::vector<art::InputTag> fFlashLabels;
141  bool fDebug;
142 
143 
144  TTree *fEventTree;
145  std::vector<TTree*> fOpDetWaveformTrees;
146  std::vector<TTree*> fOpFlashTrees;
147  std::vector<TTree*> fOpHitTrees;
148  std::vector<TTree*> fOpHitFlashTrees;
149 
150  int m_run;
151  int m_event;
153  //int m_nflashes;
154  //int m_nophit;
155  short m_baseline;
156  short m_chargesum;
157  int m_nticks;
158  float m_beam_gate_start=-99999;
159  float m_beam_gate_width=-99999;
160  int m_beam_type=-1;
161  unsigned int m_gate_type;
162  std::string m_gate_name;
166 
171  float m_sum_pe;
175  //float m_flash_x;
176  //float m_flash_width_x;
177  float m_flash_y;
179  float m_flash_z;
181 
183  float m_integral; // in ADC x tick
184  float m_amplitude; // in ADC
186  float m_width;
188  float m_pe;
190 
191  std::vector<float> m_pmt_x;
192  std::vector<float> m_pmt_y;
193  std::vector<float> m_pmt_z;
194 
196 
197 };
198 
199 
201  : EDAnalyzer(config)
202  , fTriggerLabel( config().TriggerLabel() )
203  , fSaveWaveformInfo( config().DumpWaveformsInfo() )
204  , fOpDetWaveformLabels( config().OpDetWaveformLabels() )
205  , fOpHitLabels( config().OpHitLabels() )
206  , fFlashLabels( config().FlashLabels() )
207  , fPEOpHitThreshold( config().PEOpHitThreshold() )
208  , fDebug( config().Debug() )
209  , fGeom( lar::providerFrom<geo::Geometry>() )
210 { }
211 
212 
214 
215  art::ServiceHandle<art::TFileService const> tfs;
216 
217  TTree* fGeoTree = tfs->make<TTree>("geotree", "geometry information" );
218  fGeoTree->Branch("pmt_x",&m_pmt_x);
219  fGeoTree->Branch("pmt_y",&m_pmt_y);
220  fGeoTree->Branch("pmt_z",&m_pmt_z);
221 
222  double PMTxyz[3];
223  for(size_t opch=0; opch<fGeom->NOpChannels(); ++opch) {
224 
225  fGeom->OpDetGeoFromOpChannel(opch).GetCenter(PMTxyz);
226 
227  //std::cout << PMTxyz[0] << " " << PMTxyz[1] << " " << PMTxyz[2] << std::endl;
228 
229  m_pmt_x.push_back(PMTxyz[0]);
230  m_pmt_y.push_back(PMTxyz[1]);
231  m_pmt_z.push_back(PMTxyz[2]);
232 
233  }
234 
235  fGeoTree->Fill();
236 
237  fEventTree = tfs->make<TTree>("eventstree", "higher level information on the event" );
238  fEventTree->Branch("run", &m_run, "run/I");
239  fEventTree->Branch("event", &m_event, "event/I");
240  fEventTree->Branch("timestamp", &m_timestamp, "timestamp/I");
241  //fEventTree->Branch("nflashes", &m_nflashes, "nflashes/I");
242  //fEventTree->Branch("nophits", &m_nophit, "nophits/I");
243  fEventTree->Branch("beam_gate_start", &m_beam_gate_start, "beam_gate_start/F");
244  fEventTree->Branch("beam_gate_width", &m_beam_gate_width, "beam_gate_width/F");
245  fEventTree->Branch("beam_type", &m_beam_type, "beam_type/I");
246  fEventTree->Branch("gate_type", &m_gate_type, "gate_type/b");
247  fEventTree->Branch("gate_name", &m_gate_name);
248  fEventTree->Branch("trigger_timestamp", &m_trigger_timestamp, "trigger_timestamp/l");
249  fEventTree->Branch("gate_start_timestamp", &m_gate_start_timestamp, "gate_start_timestamp/l");
250  fEventTree->Branch("trigger_gate_diff", &m_trigger_gate_diff, "trigger_gate_diff/l");
251 
252  // This tree will hold some aggregated optical waveform information
253  // The flag must be enabled to have the information saved
254  if( !fOpDetWaveformLabels.empty() && fSaveWaveformInfo ) {
255 
256  for( auto const & label : fOpDetWaveformLabels ) {
257 
258  std::string name = label.label()+"wfttree";
259  std::string info = "TTree with aggregated optical waveform information with label: " + label.label();
260 
261  TTree* ttree = tfs->make<TTree>(name.c_str(), info.c_str());
262  ttree->Branch("run", &m_run, "run/I");
263  ttree->Branch("event", &m_event, "event/I");
264  ttree->Branch("timestamp", &m_timestamp, "timestamp/I");
265  ttree->Branch("channel_id", &m_channel_id, "channel_id/I");
266  ttree->Branch("baseline", &m_baseline, "baseline/s");
267  ttree->Branch("chargesum", &m_chargesum, "chargesum/s");
268  ttree->Branch("nticks", &m_nticks, "nticks/I");
269 
270  fOpDetWaveformTrees.push_back(ttree);
271 
272  }
273 
274  }
275 
276 
277  // This ttree will hold the ophit information when a flash is not found in the event
278  // NB: information of the optical hits in events where flashes are present are lost
279 
280  for( auto const & label : fOpHitLabels ) {
281 
282  std::string name = label.label()+"_ttree";
283  std::string info = "TTree for the recob::OpHit objects with label " + label.label() + " in events without flashes.";
284 
285  TTree* ttree = tfs->make<TTree>(name.c_str(), info.c_str());
286  ttree->Branch("run", &m_run, "run/I");
287  ttree->Branch("event", &m_event, "event/I");
288  ttree->Branch("timestamp", &m_timestamp, "timestamp/I");
289  ttree->Branch("channel_id", &m_channel_id, "channel_id/I");
290  ttree->Branch("integral", &m_integral, "integral/F");
291  ttree->Branch("amplitude", &m_amplitude, "amplitude/F");
292  ttree->Branch("start_time", &m_start_time, "start_time/F");
293  ttree->Branch("abs_start_time", &m_abs_start_time, "abs_start_time/F");
294  ttree->Branch("pe", &m_pe, "pe/F");
295  ttree->Branch("width", &m_width, "width/F");
296  ttree->Branch("fast_to_total", &m_fast_to_total, "fast_to_total/F");
297 
298  fOpHitTrees.push_back(ttree);
299 
300  }
301 
302 
303  if ( !fFlashLabels.empty() ) {
304 
305  for( auto const & label : fFlashLabels ) {
306 
307  // TTree for the flash in a given cryostat
308  std::string name = label.label()+"_flashtree";
309  std::string info = "TTree for the recob::Flashes with label "+label.label();
310 
311  TTree* ttree = tfs->make<TTree>(name.c_str(), info.c_str() );
312  ttree->Branch("run", &m_run, "run/I");
313  ttree->Branch("event", &m_event, "event/I");
314  ttree->Branch("timestamp", &m_timestamp, "timestamp/I");
315  ttree->Branch("flash_id", &m_flash_id, "flash_id/I");
316  ttree->Branch("multiplicity", &m_multiplicity, "multiplicity/I");
317  ttree->Branch("multiplicity_right", &m_multiplicity_right, "multiplicity_right/I" );
318  ttree->Branch("multiplicity_left", &m_multiplicity_left, "multiplicity_left/I" );
319  ttree->Branch("sum_pe", &m_sum_pe, "sum_pe/F");
320  ttree->Branch("sum_pe_right", &m_sum_pe_right, "sum_pe_right/F");
321  ttree->Branch("sum_pe_left", &m_sum_pe_left, "sum_pe_left/F");
322  ttree->Branch("flash_time", &m_flash_time, "flash_time/F");
323  //ttree->Branch("flash_x", &m_flash_x, "flash_x/F");
324  //ttree->Branch("flash_width_x", &m_flash_width_x, "flash_width_x/F");
325  ttree->Branch("flash_y", &m_flash_y, "flash_y/F");
326  ttree->Branch("flash_width_y", &m_flash_width_y, "flash_width_y/F");
327  ttree->Branch("flash_z", &m_flash_z, "flash_z/F");
328  ttree->Branch("flash_width_z", &m_flash_width_z, "flash_width_z/F");
329 
330  fOpFlashTrees.push_back( ttree );
331 
332  // Now the ttree for the OpHit associated in the flash
333  name = label.label()+"_ophittree";
334  info = "Three for the recob::OpHit associated with an OpHitFlash"+label.label();
335 
336  TTree* ophittree = tfs->make<TTree>(name.c_str(), info.c_str() );
337  ophittree->Branch("run", &m_run, "run/I");
338  ophittree->Branch("event", &m_event, "event/I");
339  ophittree->Branch("timestamp", &m_timestamp, "timestamp/I");
340  ophittree->Branch("flash_id", &m_flash_id, "flash_id/I");
341  ophittree->Branch("channel_id", &m_channel_id, "channel_id/I");
342  ophittree->Branch("integral", &m_integral, "integral/F");
343  ophittree->Branch("amplitude", &m_amplitude, "amplitude/F");
344  ophittree->Branch("start_time", &m_start_time, "start_time/F");
345  ophittree->Branch("abs_start_time", &m_abs_start_time, "abs_start_time/F");
346  ophittree->Branch("pe", &m_pe, "pe/F");
347  ophittree->Branch("width", &m_width, "width/F");
348  ophittree->Branch("fast_to_total", &m_fast_to_total, "fast_to_total/F");
349 
350  fOpHitFlashTrees.push_back( ophittree );
351 
352  }
353  }
354 
355 }
356 
357 
358 
359 template<typename T>
360  T opana::ICARUSFlashAssAna::Median( std::vector<T> data ) const {
361 
362  std::nth_element( data.begin(), data.begin() + data.size()/2, data.end() );
363 
364  return data[ data.size()/2 ];
365 
366 }
367 
368 
370 
371 
372  const geo::OpDetGeo& opdetgeo = fGeom->OpDetGeoFromOpChannel(channel);
373  geo::CryostatID::CryostatID_t cid = opdetgeo.ID().Cryostat ;
374 
375  return cid;
376 
377 }
378 
379 
381 
382  /*
383  Channels are numbered from east to west, from North (cryo side) to South (beam side)
384  We look in the opposide direction wrt to the beam direction South->North:
385 
386  - Left is the east wall of each cryostat;
387 
388  - Right is the west side of each cryostat;
389 
390  - [ 0:89 ] and [180:269] are on the left,
391  the return value of the function is 0;
392 
393  - [ 90-179 ] and [ 270:359 ] are on the right,
394  the return value of the function is 1;
395  */
396 
397 
398  int side = channel / 90; // always round down
399 
400  return side % 2;
401 }
402 
403 
404 void opana::ICARUSFlashAssAna::processOpHits( art::Event const& e, unsigned int cryo ) {
405 
406 
407  if( fOpHitLabels.empty() ){
408 
409  mf::LogError("ICARUSFlashAssAna") << "No recob::OpHit labels selected.";
410 
411  return;
412  }
413 
414  for( size_t iOpHitLabel=0; iOpHitLabel<fOpHitLabels.size(); iOpHitLabel++ ) {
415 
416  auto const label = fOpHitLabels[iOpHitLabel];
417 
418  art::Handle<std::vector<recob::OpHit>> ophit_handle;
419  e.getByLabel( label, ophit_handle );
420 
421 
422  // We want our flashes to be valid and not empty
423  if( !ophit_handle.isValid() || ophit_handle->empty() ) {
424  mf::LogError("ICARUSFlashAssAna")
425  << "Invalid recob::OpHit with label '" << label.encode() << "'";
426  continue;
427  }
428 
429 
430  for( auto const & ophit : *ophit_handle ) {
431 
432  //auto const & ophit = (*ophit_handle)[idx];
433 
434  const int channel_id = ophit.OpChannel();
435 
436  if( getCryostatByChannel(channel_id) != cryo ){ continue; }
437 
438  m_channel_id = channel_id;
439  m_integral = ophit.Area(); // in ADC x tick
440  m_amplitude = ophit.Amplitude(); // in ADC
441  m_start_time = ophit.PeakTime();
442  m_width = ophit.Width();
443  m_abs_start_time = ophit.PeakTimeAbs();
444  m_pe = ophit.PE();
445  m_fast_to_total = ophit.FastToTotal();
446 
447  fOpHitTrees[iOpHitLabel]->Fill();
448 
449  }
450  }
451 
452  return;
453 
454 }
455 
456 
457 void opana::ICARUSFlashAssAna::processOpHitsFlash( std::vector<art::Ptr<recob::OpHit>> const &ophits,
458  int &multiplicity_left, int &multiplicity_right,
459  float &sum_pe_left, float &sum_pe_right,
460  float *xyz, TTree *ophittree ) {
461 
462 
463  std::unordered_map<int, float > sumpe_map;
464 
465  // We caluclate the total charge clustered in the flash per channel taking part to the flash
466  for( auto const ophit : ophits ) {
467 
468  if ( ophit->PE() < fPEOpHitThreshold ) { continue; }
469 
470  const int channel_id = ophit->OpChannel();
471 
472  sumpe_map[ channel_id ]+=ophit->PE() ;
473 
474  //xyz[0] += m_pmt_x[channel_id]*ophit->PE();
475  //xyz[1] += m_pmt_y[channel_id]*ophit->PE();
476  //xyz[2] += m_pmt_z[channel_id]*ophit->PE();
477 
478  m_channel_id = channel_id;
479  m_integral = ophit->Area(); // in ADC x tick
480  m_amplitude = ophit->Amplitude(); // in ADC
481  m_start_time = ophit->PeakTime();
482  m_width = ophit->Width();
483  m_abs_start_time = ophit->PeakTimeAbs();
484  m_pe = ophit->PE();
485  m_fast_to_total = ophit->FastToTotal();
486 
487  ophittree->Fill();
488 
489  }
490 
491  m_multiplicity_left = std::accumulate( sumpe_map.begin(), sumpe_map.end(), 0,
492  [&](int value, const std::map<int, float>::value_type& p) {
493  return getSideByChannel(p.first)==0 ? ++value : value ;
494  });
495 
496  m_multiplicity_right =std::accumulate( sumpe_map.begin(), sumpe_map.end(), 0,
497  [&](int value, const std::map<int, float>::value_type& p) {
498  return getSideByChannel(p.first)==1 ? ++value : value ;
499  });
500 
501  m_sum_pe_left = std::accumulate( sumpe_map.begin(), sumpe_map.end(), 0.0,
502  [&](float value, const std::map<int, float>::value_type& p) {
503  return getSideByChannel(p.first)==0 ? value+p.second : value ;
504  });
505 
506  m_sum_pe_right = std::accumulate( sumpe_map.begin(), sumpe_map.end(), 0.0,
507  [&](float value, const std::map<int, float>::value_type& p) {
508  return getSideByChannel(p.first)==1 ? value+p.second : value ;
509  });
510 
511  //for( int i=0; i<3; i++ ){ xyz[i] /= (m_sum_pe_left+ m_sum_pe_right); }
512 
513 }
514 
515 
517 
518 }
519 
520 
521 void opana::ICARUSFlashAssAna::analyze(art::Event const& e) {
522 
523 
524  m_run = e.id().run();
525  m_event = e.id().event();
526  m_timestamp = e.time().timeHigh(); // precision to the second
527 
528 
529  /*
530  This part is for the trigger information
531  */
532 
533 
534  // We work out the trigger information here
535  if( !fTriggerLabel.empty() ) {
536 
537  // Beam information
538  art::Handle<std::vector<sim::BeamGateInfo>> beamgate_handle;
539  e.getByLabel( fTriggerLabel, beamgate_handle );
540 
541  if( beamgate_handle.isValid() ) {
542 
543  for( auto const & beamgate : *beamgate_handle ) {
544 
545  m_beam_gate_start = beamgate.Start();
546  m_beam_gate_width = beamgate.Width();
547  m_beam_type = beamgate.BeamType() ;
548 
549  }
550 
551  }
552 
553  else {
554  mf::LogError("ICARUSFlashAssAna") << "No sim::BeamGateInfo associated to label: " << fTriggerLabel.label() << "\n" ;
555  }
556 
557  // Now trigger information
558  art::Handle<sbn::ExtraTriggerInfo> trigger_handle;
559  e.getByLabel( fTriggerLabel, trigger_handle );
560 
561  if( trigger_handle.isValid() ) {
562 
563  sbn::triggerSource bit = trigger_handle->sourceType;
564 
565  m_gate_type = (unsigned int)bit;
566  m_gate_name = bitName(bit);
567  m_trigger_timestamp = trigger_handle->triggerTimestamp;
568  m_gate_start_timestamp = trigger_handle->beamGateTimestamp;
569  m_trigger_gate_diff = trigger_handle->triggerTimestamp - trigger_handle->beamGateTimestamp;
570 
571  }
572  else{
573  mf::LogError("ICARUSFlashAssAna") << "No raw::Trigger associated to label: " << fTriggerLabel.label() << "\n" ;
574  }
575 
576  }
577 
578  else {
579  mf::LogError("ICARUSFlashAssAna") << "Trigger Data product " << fTriggerLabel.label() << " not found!\n" ;
580  }
581 
582 
583  /*
584  Now we work on the waveforms if we are allowed to
585  */
586 
587  if( !fOpDetWaveformLabels.empty() && fSaveWaveformInfo ) {
588 
589  for( size_t i=0; i<fOpDetWaveformLabels.size(); i++ ) {
590 
591  auto const label = fOpDetWaveformLabels[i];
592 
593  art::Handle<std::vector<raw::OpDetWaveform>> wfm_handle;
594  e.getByLabel( label, wfm_handle );
595 
596  if( wfm_handle.isValid() && !wfm_handle->empty() ) {
597 
598  for( auto const & wave : *wfm_handle ){
599 
600  m_channel_id = wave.ChannelNumber();
601  m_nticks = wave.Waveform().size();
602  m_baseline = Median( wave.Waveform() );
603  m_chargesum = std::accumulate( wave.Waveform().begin(), wave.Waveform().end(), 0,
604  [ & ](short x, short y){ return ((m_baseline-x) + (m_baseline-y)) ; } );
605 
606  fOpDetWaveformTrees[i]->Fill();
607 
608  }
609  }
610  }
611  }
612 
613 
614  /*
615  Now we take care of the flashes: we separate the case where we have a flash and the case where we have not a flash
616  */
617 
618  if ( !fFlashLabels.empty() ) {
619 
620  // Hold the cryostat information
621  std::vector<unsigned int> cids;
622 
623 
624  for ( size_t iFlashLabel=0; iFlashLabel<fFlashLabels.size(); iFlashLabel++ ) {
625 
626  auto const label = fFlashLabels[iFlashLabel];
627 
628  art::Handle<std::vector<recob::OpFlash>> flash_handle;
629  e.getByLabel( label, flash_handle );
630 
631  // We want our flashes to be valid and not empty
632  if( !flash_handle.isValid() ) {
633  mf::LogError("ICARUSFlashAssAna")
634  << "Not found a recob::OpFlash with label '" << label.encode() << "'";
635  } else if ( flash_handle->empty() ) {
636  mf::LogWarning("ICARUSFlashAssAna")
637  << "No recob::OpFlash in collection with label '" << label.encode() << "'";
638  }
639  else {
640 
641  art::FindManyP<recob::OpHit> ophitsPtr( flash_handle, e, label );
642 
643 
644  for ( size_t idx=0; idx<flash_handle->size(); idx++ ) {
645 
646  m_flash_id = idx;
647  auto const & flash = (*flash_handle)[idx];
648 
649  m_flash_time = flash.Time();
650  m_sum_pe = flash.TotalPE();
651 
652  auto const & ophits = ophitsPtr.at(idx);
653 
654  // We keep track of the cryistats where the flashes are found;
655  geo::CryostatID::CryostatID_t cid = getCryostatByChannel(ophits.front()->OpChannel());
656 
657  auto const found = std::find(cids.begin(), cids.end(), cid);
658  if( found != cids.end() ){
659  cids.push_back( cid );
660  }
661 
662  // Get the multiplicity, the position and the number of PE per Side
663  float xyz[3] = {0.0, 0.0, 0.0};
664  processOpHitsFlash( ophits,
665  m_multiplicity_left, m_multiplicity_right,
666  m_sum_pe_left, m_sum_pe_right, xyz, fOpHitFlashTrees[iFlashLabel] );
667 
668  /*
669  std::cout << "\tflash id: " << idx << ", time: " << m_flash_time;
670  std::cout << ", multiplicity left: " << m_multiplicity_left << ", multiplicity right: " << m_multiplicity_right;
671  std::cout << ", sum pe left: " << m_sum_pe_left << ", sum pe right: " << m_sum_pe_right;
672  std::cout << " coor: [" << xyz[0] << ", " << xyz[1] << ", " << xyz[2] << "]";
673  std::cout << " coor: [" << 0.0 << ", " << flash.YCenter() << ", " << flash.ZCenter() << "]";
674  std::cout << " coor: [" << 0.0 << ", " << flash.YWidth() << ", " << flash.ZWidth() << "]";
675  std::cout << "\n";
676  */
677 
678  m_multiplicity = m_multiplicity_left+m_multiplicity_right;
679 
680  //m_flash_x = 0.0;
681  //m_flash_width_x = 0.0;
682  m_flash_y = flash.YCenter();
683  m_flash_width_y = flash.YWidth();
684  m_flash_z = flash.ZCenter();
685  m_flash_width_z = flash.ZWidth();
686 
687  fOpFlashTrees[iFlashLabel]->Fill();
688  }
689  }
690  }
691 
692  // If the flashes did not cover all three cryostats..
693  // ..well, we save the ophits on what is missing
694  for( unsigned int cid=0; cid<fGeom->Ncryostats(); cid++ ){
695 
696  auto const found = std::find( cids.begin(), cids.end(), cid );
697  if( found == cids.end() ){
698  processOpHits(e, cid);
699  }
700  }
701  }
702 
703  else {
704 
705  mf::LogError("ICARUSFlashAssAna")
706  << "No recob::OpFlash labels selected\n";
707 
708  // We save the ophits anyways even in absence of flashes
709  for( unsigned int cid=0; cid<fGeom->Ncryostats(); cid++ ){
710  processOpHits(e, cid);
711  }
712 
713  }
714 
715 
716  fEventTree->Fill();
717 
718 }
719 
720 
721 DEFINE_ART_MODULE(opana::ICARUSFlashAssAna)
std::vector< TTree * > fOpFlashTrees
static std::string_view firstLine(std::string const &s, const char *endl="\r")
Utilities related to art service access.
ICARUSFlashAssAna & operator=(ICARUSFlashAssAna const &)=delete
process_name opflash particleana ie x
std::vector< TTree * > fOpDetWaveformTrees
T::provider_type const * providerFrom()
Returns a constant pointer to the provider of specified service.
Definition: ServiceUtil.h:77
void processOpHitsFlash(std::vector< art::Ptr< recob::OpHit >> const &ophits, int &multiplicity_left, int &multiplicity_right, float &sum_pe_left, float &sum_pe_right, float *xyz, TTree *ophittree)
std::vector< art::InputTag > fOpDetWaveformLabels
pdgs p
Definition: selectors.fcl:22
ICARUSFlashAssAna(Parameters const &config)
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
fhicl::Atom< art::InputTag > TriggerLabel
geo::CryostatID::CryostatID_t getCryostatByChannel(int channel)
int getSideByChannel(const int channel)
std::string bitName(triggerSource bit)
Returns a mnemonic short name of the beam type.
Definition: BeamBits.h:267
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
process_name opflash particleana ie ie y
fhicl::Sequence< art::InputTag > OpDetWaveformLabels
fhicl::Sequence< art::InputTag > FlashLabels
BEGIN_PROLOG vertical distance to the surface Name
Description of geometry of one entire detector.
T Median(std::vector< T > data) const
geo::GeometryCore const * fGeom
art::EDAnalyzer::Table< Config > Parameters
unsigned int CryostatID_t
Type for the ID number.
Definition: geo_types.h:191
std::vector< TTree * > fOpHitFlashTrees
BEGIN_PROLOG opflashCryoW opflashCryoW triggerfilterBNB triggerfilterNuMI triggerfilterOffbeamBNB triggerfilterOffbeamNuMI triggerfilterUnknown roifinder roifinder2d gaushitTPCEE gaushitTPCWE purityana1 ophit
fhicl::Sequence< art::InputTag > OpHitLabels
void analyze(art::Event const &e) override
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
std::vector< TTree * > fOpHitTrees
do i e
triggerSource
Type of beam or beam gate or other trigger source.
Definition: BeamBits.h:97
then echo fcl name
geo::OpDetID const & ID() const
Returns the geometry ID of this optical detector.
Definition: OpDetGeo.h:72
Data product holding additional trigger information.
std::vector< art::InputTag > fFlashLabels
temporary value
art::ServiceHandle< art::TFileService > tfs
std::vector< art::InputTag > fOpHitLabels
art framework interface to geometry description
void processOpHits(art::Event const &e, unsigned int cryo)