All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ICARUSOpFlashAna_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: ICARUSOpFlashAna
3 // Plugin Type: analyzer (art v3_01_01)
4 // File: ICARUSOpFlashAna_module.cc
5 //
6 // Generated at Tue Feb 12 06:49:35 2019 by Kazuhiro Terao using cetskelgen
7 // from cetlib version v3_05_01.
8 ////////////////////////////////////////////////////////////////////////
9 
10 #include "art/Framework/Core/EDAnalyzer.h"
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/Handle.h"
14 #include "art/Framework/Principal/Run.h"
15 #include "art/Framework/Principal/SubRun.h"
16 #include "canvas/Utilities/InputTag.h"
17 #include "fhiclcpp/ParameterSet.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
19 
20 #include "nusimdata/SimulationBase/MCTruth.h"
22 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
25 #include <TTree.h>
26 #include <TFile.h>
27 #include <TLorentzVector.h>
28 
29 #include <numeric> // std::accumulate
30 
31 class ICARUSOpFlashAna;
32 
33 class ICARUSOpFlashAna : public art::EDAnalyzer {
34 public:
35  explicit ICARUSOpFlashAna(fhicl::ParameterSet const& p);
36  // The compiler-generated destructor is fine for non-base
37  // classes without bare pointers or other resource use.
38 
39  // Plugins should not be copied or assigned.
40  ICARUSOpFlashAna(ICARUSOpFlashAna const&) = delete;
44 
45  // Required functions.
46  void analyze(art::Event const& e) override;
47  void beginJob() override;
48  void endJob() override;
49 private:
50 
51  // Declare member data here.
52  TFile *_f;
53  std::string _output_fname;
54  // For data product labels
55  std::string _mcflash_label;
56  std::string _mctruth_label;
57  std::vector<std::string> _flash_label_v;
58 
59  // For waveform tree
60 
61 
62  // For flash trees
63  int _run, _event;
64  std::vector<TTree*> _flashtree_v;
65  double _time;
66  double _pe_sum;
67  std::vector<double> _pe_v;
68  double _time_true;
69  double _pe_sum_true;
70  std::vector<double> _pe_true_v;
71  double _x;
72  double _y;
73  double _z;
74  double _nphotons;
75 
76  // Time period to match reco<=>MC (in micro-second)
79  double _match_dt;
80 
81  // For geometry info
82  TTree *_geotree;
83 
84 };
85 
86 
87 ICARUSOpFlashAna::ICARUSOpFlashAna(fhicl::ParameterSet const& p)
88  : EDAnalyzer{p}, _geotree(nullptr)
89 {
90  _output_fname = p.get<std::string>("OutputFileName");
91  _mcflash_label = p.get<std::string>("MCOpFlashProducer","");
92  _mctruth_label = p.get<std::string>("MCTruthProducer","");
93  _flash_label_v = p.get<std::vector<std::string> >("OpFlashProducerList");
94  _match_time_min = p.get<double>("MatchTimeStart",0.105); // in micro-seconds
95  _match_time_max = p.get<double>("MatchTimeEnd",0.120); // in micro-seconds
96  _match_dt = _match_time_max - _match_time_min;
97  assert(_match_dt>0);
98 }
99 
101 {
102  _f = TFile::Open(_output_fname.c_str(),"RECREATE");
103 
104  for(auto const& label : _flash_label_v) {
105  std::string name = label + "_flashtree";
106  auto flashtree = new TTree(name.c_str(),name.c_str());
107  flashtree->Branch("run",&_run,"run/I");
108  flashtree->Branch("event",&_event,"event/I");
109  flashtree->Branch("time",&_time,"time/D");
110  flashtree->Branch("pe_v",&_pe_v);
111  flashtree->Branch("pe_sum",&_pe_sum,"pe_sum/D");
112  if(!_mctruth_label.empty() && !_mcflash_label.empty()) {
113  flashtree->Branch("time_true",&_time_true,"time_true/D");
114  flashtree->Branch("pe_true_v",&_pe_true_v);
115  flashtree->Branch("pe_sum_true",&_pe_sum_true,"pe_sum_true/D");
116  flashtree->Branch("x",&_x,"x/D");
117  flashtree->Branch("y",&_y,"y/D");
118  flashtree->Branch("z",&_z,"z/D");
119  flashtree->Branch("nphotons",&_nphotons,"nphotons/D");
120  }
121  _flashtree_v.push_back(flashtree);
122  }
123 
124  _geotree = new TTree("geotree","geotree");
125  std::vector<double> pmtX, pmtY, pmtZ;
126  std::vector<double> minX, minY, minZ;
127  std::vector<double> maxX, maxY, maxZ;
128  auto const geop = lar::providerFrom<geo::Geometry>();
129  double PMTxyz[3];
130  for(size_t opch=0; opch<geop->NOpChannels(); ++opch) {
131  geop->OpDetGeoFromOpChannel(opch).GetCenter(PMTxyz);
132  pmtX.push_back(PMTxyz[0]);
133  pmtY.push_back(PMTxyz[1]);
134  pmtZ.push_back(PMTxyz[2]);
135  }
136  for(auto iter=geop->begin_TPC(); iter!=geop->end_TPC(); ++iter) {
137  auto const& tpc = (*iter);
138  minX.push_back(tpc.ActiveBoundingBox().MinX());
139  minY.push_back(tpc.ActiveBoundingBox().MinY());
140  minZ.push_back(tpc.ActiveBoundingBox().MinZ());
141  maxX.push_back(tpc.ActiveBoundingBox().MaxX());
142  maxY.push_back(tpc.ActiveBoundingBox().MaxY());
143  maxZ.push_back(tpc.ActiveBoundingBox().MaxZ());
144  }
145  _geotree->Branch("pmtX",&pmtX);
146  _geotree->Branch("pmtY",&pmtY);
147  _geotree->Branch("pmtZ",&pmtZ);
148  _geotree->Branch("minX",&minX);
149  _geotree->Branch("minY",&minY);
150  _geotree->Branch("minZ",&minZ);
151  _geotree->Branch("maxX",&maxX);
152  _geotree->Branch("maxY",&maxY);
153  _geotree->Branch("maxZ",&maxZ);
154  _geotree->Fill();
155 }
156 
158 {
159  _f->cd();
160  for(auto& ptr : _flashtree_v) { _f->cd(); ptr->Write(); }
161  _f->cd(); _geotree->Write();
162  if(_f) _f->Close();
163 }
164 
165 void ICARUSOpFlashAna::analyze(art::Event const& e)
166 {
167 
168  _event = e.id().event();
169  _run = e.id().run();
170 
171  // get MCTruth
172  art::Handle< std::vector< simb::MCTruth > > mctruth_h;
173  std::map<double, int> mctruth_db;
174  if(!_mctruth_label.empty()) {
175  e.getByLabel(_mctruth_label, mctruth_h);
176  for (size_t mctruth_index = 0; mctruth_index < mctruth_h->size(); ++mctruth_index) {
177  auto const& mctruth = (*mctruth_h)[mctruth_index];
178  for (int part_idx = 0; part_idx < mctruth.NParticles(); ++part_idx) {
179  const simb::MCParticle & particle = mctruth.GetParticle(part_idx);
180  //const TLorentzVector& pos = particle.Position();
181  //const TLorentzVector& mom = particle.Momentum();
182  mctruth_db[particle.T() + _match_time_min] = part_idx; // FIXME assumes mctruth_h->size() == 1 always?
183  }
184  }
185  }
186 
187  // get MCOpFlash
188  art::Handle< std::vector< recob::OpFlash > > mcflash_h;
189  if(!_mcflash_label.empty()) {
190  e.getByLabel(_mcflash_label, mcflash_h);
191  if(!mcflash_h.isValid()) {
192  std::cerr << "Invalid producer for truth recob::OpFlash: " << _mcflash_label << std::endl;
193  throw std::exception();
194  }
195  }
196  // Create a "time-map" of MCOpFlash
197  // inner map ... key = mcflash timing
198  // value = mcflash location (i.e. array index number)
199  std::map<double,int> mcflash_db;
200  if(!_mcflash_label.empty()) {
201  // fill the map
202  //auto const geop = lar::providerFrom<geo::Geometry>();
203  for(size_t mcflash_index=0; mcflash_index < mcflash_h->size(); ++mcflash_index) {
204  auto const& mcflash = (*mcflash_h)[mcflash_index];
205  mcflash_db[mcflash.Time() + _match_time_min] = mcflash_index;
206  }
207  }
208  // now fill opflash trees
209  for(size_t label_idx=0; label_idx<_flash_label_v.size(); ++label_idx) {
210  // Get data product handle
211  auto const& label = _flash_label_v[label_idx];
212  auto& flashtree = _flashtree_v[label_idx];
213  art::Handle< std::vector< recob::OpFlash > > flash_h;
214  e.getByLabel(label,flash_h);
215  if(!flash_h.isValid()){
216  std::cerr << "Invalid producer for recob::OpFlash: " << label << std::endl;
217  throw std::exception();
218  }
219 
220  // keep the record of which mcflash was used (to store un-tagged mcflash at the end)
221  std::vector<bool> mcflash_used;
222  if(!_mcflash_label.empty()) { mcflash_used.resize(mcflash_h->size(),false); }
223  // now loop over flash, identify mc flash, fill ttree
224  for(auto const& flash : (*flash_h)) {
225  // fill simple info
226  _time = flash.Time();
227  _pe_v = flash.PEs();
228  _pe_sum = flash.TotalPE();//std::accumulate(_pe_v.begin(),_pe_v.end());
229 
230  if(!_mctruth_label.empty() && !_mcflash_label.empty()) {
231  // search for corresponding mctruth
232  auto low_mct = mctruth_db.lower_bound(_time);
233  if (low_mct != mctruth_db.begin()) {
234  --low_mct;
235  auto const& mctruth = (*mctruth_h).at(0);
236  auto const& particle = mctruth.GetParticle((*low_mct).second);
237  if ( (particle.T() - (*low_mct).first) < _match_dt) {
238  _nphotons = particle.E();
239  _x = particle.Vx();
240  _y = particle.Vy();
241  _z = particle.Vz();
242  }
243  }
244  // search for corresponding mcflash
245  auto low = mcflash_db.lower_bound(_time);
246  _pe_true_v.resize(_pe_v.size());
247  for(auto& pe : _pe_true_v) pe = 0.;
248  _time_true = std::numeric_limits<double>::max();
249  _pe_sum_true = -1;
250  if(low != mcflash_db.begin()) {
251  --low;
252  // get mc opflash
253  auto const& mcflash = (*mcflash_h).at((*low).second);
254  // Check if this is in the "match" range
255  if( (_time - (*low).first) < _match_dt ) {
256  _pe_true_v = mcflash.PEs();
257  _time_true = mcflash.Time();
258  _pe_sum_true = mcflash.TotalPE();
259  //_pe_sum_true = std::accumulate(_pe_true_v.begin(),_pe_true_v.end());
260  mcflash_used[(*low).second] = true;
261  std::cout << mcflash.TotalPE() << " " << std::accumulate(_pe_true_v.begin(), _pe_true_v.end(), 0.) << std::endl;
262  }
263  }
264  }
265  flashtree->Fill();
266  }
267 
268 
269  // now fill mcflash info that was not tagged
270  if(!_mctruth_label.empty() && !_mcflash_label.empty()) {
271  for(size_t mcflash_idx=0; mcflash_idx < mcflash_used.size(); ++mcflash_idx) {
272  if(mcflash_used[mcflash_idx]) continue;
273  auto const& mcflash = (*mcflash_h)[mcflash_idx];
274  _pe_true_v = mcflash.PEs();
275  //_pe_sum_true = std::accumulate(_pe_true_v.begin(),_pe_true-v.end());
276  _pe_sum_true = mcflash.TotalPE();
277  _time_true = mcflash.Time();
278  // fill the "reco flash" values with vogus values
279  _time = std::numeric_limits<double>::max();
280  _pe_v.clear();
281  _pe_v.resize(_pe_true_v.size(),0.);
282  _pe_sum = -1.;
283  flashtree->Fill();
284  }
285  }
286 
287  }
288 
289 }
290 
291 DEFINE_ART_MODULE(ICARUSOpFlashAna)
Utilities related to art service access.
BEGIN_PROLOG could also be cerr
pdgs p
Definition: selectors.fcl:22
std::vector< TTree * > _flashtree_v
process_name mcflash
ICARUSOpFlashAna(fhicl::ParameterSet const &p)
standard_dbscan3dalg useful for diagnostics hits not in a line will not be clustered on on only for track like only for track like on on the smaller the less shower like tracks low
std::vector< double > _pe_true_v
std::vector< double > _pe_v
std::vector< std::string > _flash_label_v
do i e
ICARUSOpFlashAna & operator=(ICARUSOpFlashAna const &)=delete
then echo fcl name
art framework interface to geometry description
BEGIN_PROLOG could also be cout
void analyze(art::Event const &e) override