All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ICARUSOpHitTuple_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: ICARUSOpHitAna
3 // Plugin Type: analyzer (art v3_01_01)
4 // File: ICARUSOpHitAna_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 
28 class ICARUSOpHitTuple;
29 
30 class ICARUSOpHitTuple : public art::EDAnalyzer {
31 public:
32  explicit ICARUSOpHitTuple(fhicl::ParameterSet const& p);
33  // The compiler-generated destructor is fine for non-base
34  // classes without bare pointers or other resource use.
35 
36  // Plugins should not be copied or assigned.
37  ICARUSOpHitTuple(ICARUSOpHitTuple const&) = delete;
41 
42  // Required functions.
43  void analyze(art::Event const& e) override;
44  void beginJob() override;
45  void endJob() override;
46 private:
47 
48  // Declare member data here.
49  TFile *_f;
50  std::string _output_fname;
51  // For data product labels
52  std::string _wf_label;
53  std::string _mct_label;
54  std::vector<std::string> _hit_label_v;
55 
56  // Event wise info
57  int _run, _event, _ch;
60  int _tpc;
61 
62  // For waveform tree
63  TTree* _wftree;
64  double _tstart;
65  std::vector<float> _wf;
66  std::vector<std::string> _wf_label_v;
67 
68  // For hit trees
69  std::vector<TTree*> _hittree_v;
70  double _width;
71  double _time;
72  double _amp;
73  double _area;
74  double _pe;
75 
76  // For geometry info
77  TTree *_geotree;
78 
79 };
80 
81 
82 ICARUSOpHitTuple::ICARUSOpHitTuple(fhicl::ParameterSet const& p)
83  : EDAnalyzer{p}, _wftree(nullptr), _geotree(nullptr)
84 {
85  _output_fname = p.get<std::string>("OutputFileName" );
86  _wf_label = p.get<std::string>("OpDetWaveformProducer" );
87  _mct_label = p.get<std::string>("MCTruthProducer","generator");
88  _hit_label_v = p.get<std::vector<std::string> >("OpHitProducerList");
89 }
90 
92 {
93  _f = TFile::Open(_output_fname.c_str(),"RECREATE");
94  _wftree = nullptr;
95  if(!_wf_label.empty()) {
96  std::string name = _wf_label + "_wftree";
97  _wftree = new TTree(name.c_str(),name.c_str());
98  _wftree->Branch("run",&_run,"run/I");
99  _wftree->Branch("event",&_event,"event/I");
100  _wftree->Branch("event_time",&_event_time,"event_time/D");
101  _wftree->Branch("event_x",&_event_x,"event_x/D");
102  _wftree->Branch("event_y",&_event_y,"event_y/D");
103  _wftree->Branch("event_z",&_event_z,"event_z/D");
104  _wftree->Branch("event_dr",&_event_dr,"event_dr/D");
105  _wftree->Branch("event_dx",&_event_dx,"event_dx/D");
106  _wftree->Branch("event_dy",&_event_dy,"event_dy/D");
107  _wftree->Branch("event_dz",&_event_dz,"event_dz/D");
108  _wftree->Branch("tpc",&_tpc,"tpc/I");
109  _wftree->Branch("ch",&_ch,"ch/I");
110  _wftree->Branch("wf",&_wf);
111  _wftree->Branch("tstart",&_tstart,"tstart/D");
112  }
113 
114  for(auto const& label : _hit_label_v) {
115  std::string name = label + "_hittree";
116  auto hittree = new TTree(name.c_str(),name.c_str());
117  hittree->Branch("run",&_run,"run/I");
118  hittree->Branch("event",&_event,"event/I");
119  hittree->Branch("event_time",&_event_time,"event_time/D");
120  hittree->Branch("event_x",&_event_x,"event_x/D");
121  hittree->Branch("event_y",&_event_y,"event_y/D");
122  hittree->Branch("event_z",&_event_z,"event_z/D");
123  hittree->Branch("event_dr",&_event_dr,"event_dr/D");
124  hittree->Branch("event_dx",&_event_dx,"event_dx/D");
125  hittree->Branch("event_dy",&_event_dy,"event_dy/D");
126  hittree->Branch("event_dz",&_event_dz,"event_dz/D");
127  hittree->Branch("tpc",&_tpc,"tpc/I");
128  hittree->Branch("ch",&_ch,"ch/I");
129  hittree->Branch("amp",&_amp,"amp/D");
130  hittree->Branch("area",&_area,"area/D");
131  hittree->Branch("width",&_width,"width/D");
132  hittree->Branch("time",&_time,"time/D");
133  hittree->Branch("pe",&_pe,"pe/D");
134  _hittree_v.push_back(hittree);
135  }
136 
137  _geotree = new TTree("geotree","geotree");
138  std::vector<double> pmtX, pmtY, pmtZ;
139  std::vector<double> minX, minY, minZ;
140  std::vector<double> maxX, maxY, maxZ;
141  auto const geop = lar::providerFrom<geo::Geometry>();
142  double PMTxyz[3];
143  for(size_t opch=0; opch<geop->NOpChannels(); ++opch) {
144  geop->OpDetGeoFromOpChannel(opch).GetCenter(PMTxyz);
145  pmtX.push_back(PMTxyz[0]);
146  pmtY.push_back(PMTxyz[1]);
147  pmtZ.push_back(PMTxyz[2]);
148  }
149  for(auto iter=geop->begin_TPC(); iter!=geop->end_TPC(); ++iter) {
150  auto const& tpc = (*iter);
151  minX.push_back(tpc.BoundingBox().MinX());
152  minY.push_back(tpc.BoundingBox().MinY());
153  minZ.push_back(tpc.BoundingBox().MinZ());
154  maxX.push_back(tpc.BoundingBox().MaxX());
155  maxY.push_back(tpc.BoundingBox().MaxY());
156  maxZ.push_back(tpc.BoundingBox().MaxZ());
157  }
158  _geotree->Branch("pmtX",&pmtX);
159  _geotree->Branch("pmtY",&pmtY);
160  _geotree->Branch("pmtZ",&pmtZ);
161  _geotree->Branch("minX",&minX);
162  _geotree->Branch("minY",&minY);
163  _geotree->Branch("minZ",&minZ);
164  _geotree->Branch("maxX",&maxX);
165  _geotree->Branch("maxY",&maxY);
166  _geotree->Branch("maxZ",&maxZ);
167  _geotree->Fill();
168 }
169 
171 {
172  _f->cd();
173  if(_wftree) _wftree->Write();
174  for(auto& ptr : _hittree_v) { _f->cd(); ptr->Write(); }
175  _f->cd(); _geotree->Write();
176  if(_f) _f->Close();
177 }
178 
179 void ICARUSOpHitTuple::analyze(art::Event const& e)
180 {
181 
182  _event = e.id().event();
183  _run = e.id().run();
184 
185  // Fill waveforms if requested
186  if(!_wf_label.empty()) {
187  art::Handle< std::vector< raw::OpDetWaveform > > wf_h;
188  e.getByLabel(_wf_label,wf_h);
189  if(!wf_h.isValid()){
190  std::cerr << "Invalid producer for raw::OpDetWaveform: " << _wf_label << std::endl;
191  throw std::exception();
192  }
193  for(auto const& wf : (*wf_h)) {
194  _wf.resize(wf.size());
195  for(size_t i=0; i<_wf.size(); ++i) { _wf.at(i) = wf.at(i); }
196  _ch=wf.ChannelNumber();
197  _tstart=wf.TimeStamp();
198  _wftree->Fill();
199  }
200  }
201 
202  // get MCTruth
203  _event_time = std::numeric_limits<double>::max();
204  _event_x = _event_y = _event_z = std::numeric_limits<double>::max();
205  if(!_mct_label.empty()) {
206  art::Handle< std::vector<simb::MCTruth> > mct_h;
207  e.getByLabel(_mct_label,mct_h);
208  if(!mct_h.isValid()) {
209  std::cerr << "Invalid producer for simb::MCTruth: " << _mct_label << std::endl;
210  throw std::exception();
211  }
212  for(size_t mct_index=0; mct_index<mct_h->size(); ++mct_index) {
213 
214  auto const& mct = (*mct_h)[mct_index];
215 
216  for(int i=0; i<mct.NParticles(); ++i) {
217  auto const& mcp = mct.GetParticle(i);
218  if(mcp.StatusCode() != 1) continue;
219 
220  auto const& pos = mcp.Position(0);
221  if(_event_time < pos.T()/1000.) continue;
222  _event_time = pos.T()/1000.;
223  _event_x = pos.X();
224  _event_y = pos.Y();
225  _event_z = pos.Z();
226  }
227  }
228  }
229 
230  // set dr, dx, dy, dz
231  _event_dr = _event_dx = _event_dy = _event_dz =std::numeric_limits<double>::max();
232  _tpc = -1;
233  if(_event_time != std::numeric_limits<double>::max()) {
234  auto const geop = lar::providerFrom<geo::Geometry>();
235  // measure smallest dr to any pmt
236  double PMTxyz[3];
237  for(size_t opch=0; opch<geop->NOpChannels(); ++opch) {
238  geop->OpDetGeoFromOpChannel(opch).GetCenter(PMTxyz);
239  double dx = PMTxyz[0] - _event_x;
240  double dy = PMTxyz[1] - _event_y;
241  double dz = PMTxyz[2] - _event_z;
242  double dr = sqrt(pow(dx,2)+pow(dy,2)+pow(dz,2));
243  if(_event_dr < dr) continue;
244  _event_dr = dr;
245  _event_dx = dx;
246  _event_dy = dy;
247  _event_dz = dz;
248  }
249  }
250 
251  // now fill ophit trees
252  for(size_t label_idx=0; label_idx<_hit_label_v.size(); ++label_idx) {
253  // Get data product handle
254  auto const& label = _hit_label_v[label_idx];
255  auto& hittree = _hittree_v[label_idx];
256  art::Handle< std::vector< recob::OpHit > > hit_h;
257  e.getByLabel(label,hit_h);
258  if(!hit_h.isValid()){
259  std::cerr << "Invalid producer for recob::OpHit: " << label << std::endl;
260  throw std::exception();
261  }
262 
263  // now loop over hit, identify mc hit, fill ttree
264  for(auto const& hit : (*hit_h)) {
265  // fill simple info
266  _ch=hit.OpChannel();
267  _time = hit.PeakTime();
268  _amp = hit.Amplitude();
269  _width = hit.Width();
270  _area = hit.Area();
271  _pe = hit.PE();
272  hittree->Fill();
273  }
274 
275  }
276 
277 }
278 
279 DEFINE_ART_MODULE(ICARUSOpHitTuple)
Utilities related to art service access.
BEGIN_PROLOG could also be cerr
pdgs p
Definition: selectors.fcl:22
process_name hit
Definition: cheaterreco.fcl:51
ICARUSOpHitTuple(fhicl::ParameterSet const &p)
void analyze(art::Event const &e) override
std::vector< float > _wf
std::vector< std::string > _hit_label_v
ICARUSOpHitTuple & operator=(ICARUSOpHitTuple const &)=delete
std::vector< std::string > _wf_label_v
std::vector< TTree * > _hittree_v
do i e
then echo fcl name
art framework interface to geometry description