LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
CellTree_module.cc
Go to the documentation of this file.
1 // Read data from MC raw files and convert it into ROOT tree
2 // Chao Zhang (chao@bnl.gov) 5/13/2014
3 // Added optical info --- Brooke Russell (brussell@yale.edu) 1/31/2017
4 
5 // LArSoft includes
20 
21 // Framework includes
28 #include "fhiclcpp/ParameterSet.h"
30 
31 // ROOT includes.
32 #include "TClonesArray.h"
33 #include "TDatabasePDG.h"
34 #include "TDirectory.h"
35 #include "TFile.h"
36 #include "TH1F.h"
37 #include "TLorentzVector.h"
38 #include "TObjArray.h"
39 #include "TString.h"
40 #include "TSystem.h"
41 #include "TTimeStamp.h"
42 #include "TTree.h"
43 
44 // C++ Includes
45 #include <cstdio>
46 #include <fstream>
47 #include <map>
48 
49 #define MAX_TRACKS 30000
50 
51 using namespace std;
52 
53 namespace wc {
54 
55  class CellTree : public art::EDAnalyzer {
56  public:
57  explicit CellTree(fhicl::ParameterSet const& pset);
58 
59  private:
60  void endJob();
61  void beginRun(const art::Run& run);
62  void analyze(const art::Event& evt);
63 
64  void initOutput();
65  void printEvent();
66  void print_vector(ostream& out, vector<double>& v, TString desc, bool end = false);
67 
68  void processRaw(const art::Event& evt);
69  void processCalib(const art::Event& evt);
70  void processOpHit(const art::Event& evt);
71  void processOpFlash(const art::Event& evt);
72  void processSpacePoint(const art::Event& event, TString option, ostream& out = cout);
73  void processSpacePointTruthDepo(const art::Event& event,
74  TString option,
75  ostream& out = cout,
76  bool t0_corrected = true);
77  void processSimChannel(const art::Event& evt);
78  void processMC(const art::Event& evt);
79  void processMCTracks();
80  void processTrigger(const art::Event& evt);
81 
82  void reset();
83  void InitProcessMap();
84 
85  bool IsPrimary(int i) { return mc_mother[i] == 0; }
86  bool KeepMC(int i);
87  double KE(float* momentum); // KE
88  TString PDGName(int pdg);
89  bool DumpMCJSON(int id, ostream& out);
90  void DumpMCJSON(ostream& out = cout);
91 
92  // the parameters we'll read from the .fcl
93  std::string fRawDigitLabel;
94  std::string fCalibLabel;
95  std::string fOpHitLabel;
96  std::string fOpFlashLabel;
97  std::string fTriggerLabel;
99  std::vector<std::string> fSpacePointLabels;
100  std::string fSimChannelLabel;
101  std::string fOutFileName;
102  std::string mcOption;
105  float drift_speed;
108  bool fSaveRaw;
112  bool fSaveMC;
114  bool fSaveJSON;
116  art::ServiceHandle<geo::Geometry const> fGeometry; // pointer to Geometry service
117 
118  // art::ServiceHandle<geo::Geometry const> fGeom;
119  // // auto const* larp = lar::providerFrom<detinfo::LArPropertiesService>();
120 
121  TFile* fOutFile;
122  TTree* fEventTree;
123  std::map<std::string, int> processMap;
124  std::map<int, int> savedMCTrackIdMap; // key: id; value: pdg;
125 
126  int entryNo;
127 
128  // Event Tree Leafs
129  int fEvent;
130  int fRun;
131  int fSubRun;
132  double fEventTime;
133 
134  unsigned int fTriggernumber; //trigger counter
135  double fTriggertime; //trigger time w.r.t. electronics clock T0
136  double fBeamgatetime; //beamgate time w.r.t. electronics clock T0
137  unsigned int fTriggerbits; //trigger bits
138 
140  // int fCalib_channelId[MAX_CHANNEL]; // hit channel id; size == fCalib_Nhit
141  // // FIXEME:: cannot save e.g std::vector<std::vector<float> > in ttree
142  std::vector<int> fCalib_channelId;
143  // std::vector<std::vector<float> > fCalib_wf;
144  TClonesArray* fCalib_wf;
145  // std::vector<std::vector<int> > fCalib_wfTDC;
146 
147  int oh_nHits;
148  vector<int> oh_channel;
149  vector<double> oh_bgtime;
150  vector<double> oh_trigtime;
151  vector<double> oh_pe;
152 
154  vector<float> of_t;
155  vector<float> of_peTotal;
156  vector<int> of_multiplicity;
157  TClonesArray* fPEperOpDet;
158 
160  std::vector<int> fRaw_channelId;
161  TClonesArray* fRaw_wf;
162 
164  vector<int> fSIMIDE_channelIdY;
165  vector<int> fSIMIDE_trackId;
166  vector<unsigned short> fSIMIDE_tdc;
167  vector<float> fSIMIDE_x;
168  vector<float> fSIMIDE_y;
169  vector<float> fSIMIDE_z;
170  vector<float> fSIMIDE_numElectrons;
171 
172  int mc_Ntrack; // number of tracks in MC
173  int mc_id[MAX_TRACKS]; // track id; size == mc_Ntrack
174  int mc_pdg[MAX_TRACKS]; // track particle pdg; size == mc_Ntrack
175  int mc_process[MAX_TRACKS]; // track generation process code; size == mc_Ntrack
176  int mc_mother[MAX_TRACKS]; // mother id of this track; size == mc_Ntrack
177  float mc_startXYZT[MAX_TRACKS][4]; // start position of this track; size == mc_Ntrack
178  float mc_endXYZT[MAX_TRACKS][4]; // end position of this track; size == mc_Ntrack
179  float mc_startMomentum[MAX_TRACKS][4]; // start momentum of this track; size == mc_Ntrack
180  float mc_endMomentum[MAX_TRACKS][4]; // end momentum of this track; size == mc_Ntrack
181  std::vector<std::vector<int>> mc_daughters; // daughters id of this track; vector
182  TObjArray* fMC_trackPosition;
183 
184  int mc_isnu; // is neutrino interaction
185  int mc_nGeniePrimaries; // number of Genie primaries
186  int mc_nu_pdg; // pdg code of neutrino
187  int mc_nu_ccnc; // cc or nc
188  int mc_nu_mode; // mode: http://nusoft.fnal.gov/larsoft/doxsvn/html/MCNeutrino_8h_source.html
189  int mc_nu_intType; // interaction type
190  int mc_nu_target; // target interaction
191  int mc_hitnuc; // hit nucleon
192  int mc_hitquark; // hit quark
193  double mc_nu_Q2; // Q^2
194  double mc_nu_W; // W
195  double mc_nu_X; // X
196  double mc_nu_Y; // Y
197  double mc_nu_Pt; // Pt
198  double mc_nu_Theta; // angle relative to lepton
199  float mc_nu_pos[4]; // interaction position of nu
200  float mc_nu_mom[4]; // interaction momentum of nu
201 
202  // ----- derived ---
203  std::map<int, int> trackIndex;
204  std::vector<std::vector<int>> trackParents;
205  std::vector<std::vector<int>> trackChildren;
206  std::vector<std::vector<int>> trackSiblings;
207  TDatabasePDG* dbPDG;
208 
209  }; // class CellTree
210 
211  //-----------------------------------------------------------------------
212  CellTree::CellTree(fhicl::ParameterSet const& p) : EDAnalyzer(p)
213  {
214  dbPDG = new TDatabasePDG();
215  entryNo = 0;
216 
217  fRawDigitLabel = p.get<std::string>("RawDigitLabel");
218  fCalibLabel = p.get<std::string>("CalibLabel");
219  fOpHitLabel = p.get<std::string>("OpHitLabel");
220  fOpFlashLabel = p.get<std::string>("OpFlashLabel");
221  fTriggerLabel = p.get<std::string>("TriggerLabel");
222  fSimEnergyDepositLabel = p.get<std::string>("SimEnergyDepositLabel");
223  fSpacePointLabels = p.get<std::vector<std::string>>("SpacePointLabels");
224  fSimChannelLabel = p.get<std::string>("SimChannelLabel");
225  fOutFileName = p.get<std::string>("outFile");
226  mcOption = p.get<std::string>("mcOption");
227  fSaveMCTrackPoints = p.get<bool>("saveMCTrackPoints");
228  fSaveRaw = p.get<bool>("saveRaw");
229  fSaveCalib = p.get<bool>("saveCalib");
230  fSaveOpHit = p.get<bool>("saveOpHit");
231  fSaveOpFlash = p.get<bool>("saveOpFlash");
232  fSaveMC = p.get<bool>("saveMC");
233  fSaveSimChannel = p.get<bool>("saveSimChannel");
234  fSaveTrigger = p.get<bool>("saveTrigger");
235  fSaveJSON = p.get<bool>("saveJSON");
236  fT0_corrected = p.get<bool>("t0_corrected");
237  opMultPEThresh = p.get<float>("opMultPEThresh");
238  drift_speed = p.get<float>("drift_speed"); // mm/us
239  nRawSamples = p.get<int>("nRawSamples");
240 
241  InitProcessMap();
242  initOutput();
243  }
244 
245  //-----------------------------------------------------------------------
247  {
248  TDirectory* tmpDir = gDirectory;
249 
250  fOutFile = new TFile(fOutFileName.c_str(), "recreate");
251 
252  // 3.1: add mc_trackPosition
253  TNamed version("version", "4.0");
254  version.Write();
255 
256  // init Event TTree
257  TDirectory* subDir = fOutFile->mkdir("Event");
258  subDir->cd();
259  fEventTree = new TTree("Sim", "Event Tree from Simulation");
260  fEventTree->Branch("eventNo", &fEvent);
261  fEventTree->Branch("runNo", &fRun);
262  fEventTree->Branch("subRunNo", &fSubRun);
263  fEventTree->Branch("eventTime", &fEventTime); // timestamp
264 
265  fEventTree->Branch("triggerNo", &fTriggernumber); // timestamp
266  fEventTree->Branch("triggerTime", &fTriggertime); // timestamp
267  fEventTree->Branch("beamgateTime", &fBeamgatetime); // timestamp
268  fEventTree->Branch("triggerBits", &fTriggerbits); // timestamp
269 
270  fEventTree->Branch("raw_nChannel", &fRaw_nChannel); // number of hit channels above threshold
271  fEventTree->Branch("raw_channelId", &fRaw_channelId); // hit channel id; size == raw_nChannel
272  fRaw_wf = new TClonesArray("TH1F");
273  fEventTree->Branch("raw_wf", &fRaw_wf, 256000, 0); // raw waveform adc of each channel
274 
275  fEventTree->Branch("calib_nChannel",
276  &fCalib_nChannel); // number of hit channels above threshold
277  fEventTree->Branch("calib_channelId", &fCalib_channelId); // hit channel id; size == calib_Nhit
278  fCalib_wf = new TClonesArray("TH1F");
279  fEventTree->Branch("calib_wf", &fCalib_wf, 256000, 0); // calib waveform adc of each channel
280  // fCalib_wf->BypassStreamer();
281  // fEventTree->Branch("calib_wfTDC", &fCalib_wfTDC); // calib waveform tdc of each channel
282 
283  fEventTree->Branch("oh_nHits", &oh_nHits); // number of op hits
284  fEventTree->Branch("oh_channel", &oh_channel); //opchannel id; size == no ophits
285  fEventTree->Branch("oh_bgtime",
286  &oh_bgtime); // optical pulse peak time w.r.t. start of beam gate
287  fEventTree->Branch("oh_trigtime", &oh_trigtime); // optical pulse peak time w.r.t. trigger
288  fEventTree->Branch("oh_pe", &oh_pe); // pulse PE
289 
290  fEventTree->Branch("of_nFlash", &of_nFlash);
291  fEventTree->Branch("of_t", &of_t); // time in us w.r.t. the trigger for each flash
292  fEventTree->Branch("of_peTotal", &of_peTotal); // total PE (sum of all PMTs) for each flash
293  fEventTree->Branch("of_multiplicity",
294  &of_multiplicity); // total number of PMTs above threshold for each flash
295  fPEperOpDet = new TClonesArray("TH1F");
296  fEventTree->Branch("pe_opdet", &fPEperOpDet, 256000, 0);
297 
298  fEventTree->Branch("simide_size", &fSIMIDE_size); // size of stored sim:IDE
299  fEventTree->Branch("simide_channelIdY", &fSIMIDE_channelIdY);
300  fEventTree->Branch("simide_trackId", &fSIMIDE_trackId);
301  fEventTree->Branch("simide_tdc", &fSIMIDE_tdc);
302  fEventTree->Branch("simide_x", &fSIMIDE_x);
303  fEventTree->Branch("simide_y", &fSIMIDE_y);
304  fEventTree->Branch("simide_z", &fSIMIDE_z);
305  fEventTree->Branch("simide_numElectrons", &fSIMIDE_numElectrons);
306 
307  fEventTree->Branch("mc_Ntrack", &mc_Ntrack); // number of tracks in MC
308  fEventTree->Branch("mc_id", &mc_id, "mc_id[mc_Ntrack]/I"); // track id; size == mc_Ntrack
309  fEventTree->Branch(
310  "mc_pdg", &mc_pdg, "mc_pdg[mc_Ntrack]/I"); // track particle pdg; size == mc_Ntrack
311  fEventTree->Branch(
312  "mc_process",
313  &mc_process,
314  "mc_process[mc_Ntrack]/I"); // track generation process code; size == mc_Ntrack
315  fEventTree->Branch("mc_mother",
316  &mc_mother,
317  "mc_mother[mc_Ntrack]/I"); // mother id of this track; size == mc_Ntrack
318  fEventTree->Branch("mc_daughters", &mc_daughters); // daughters id of this track; vector
319  fEventTree->Branch(
320  "mc_startXYZT",
321  &mc_startXYZT,
322  "mc_startXYZT[mc_Ntrack][4]/F"); // start position of this track; size == mc_Ntrack
323  fEventTree->Branch(
324  "mc_endXYZT",
325  &mc_endXYZT,
326  "mc_endXYZT[mc_Ntrack][4]/F"); // start position of this track; size == mc_Ntrack
327  fEventTree->Branch(
328  "mc_startMomentum",
330  "mc_startMomentum[mc_Ntrack][4]/F"); // start momentum of this track; size == mc_Ntrack
331  fEventTree->Branch(
332  "mc_endMomentum",
334  "mc_endMomentum[mc_Ntrack][4]/F"); // start momentum of this track; size == mc_Ntrack
335  fMC_trackPosition = new TObjArray();
336  fMC_trackPosition->SetOwner(kTRUE);
337  fEventTree->Branch("mc_trackPosition", &fMC_trackPosition);
338 
339  fEventTree->Branch("mc_isnu", &mc_isnu);
340  fEventTree->Branch("mc_nGeniePrimaries", &mc_nGeniePrimaries);
341  fEventTree->Branch("mc_nu_pdg", &mc_nu_pdg);
342  fEventTree->Branch("mc_nu_ccnc", &mc_nu_ccnc);
343  fEventTree->Branch("mc_nu_mode", &mc_nu_mode);
344  fEventTree->Branch("mc_nu_intType", &mc_nu_intType);
345  fEventTree->Branch("mc_nu_target", &mc_nu_target);
346  fEventTree->Branch("mc_hitnuc", &mc_hitnuc);
347  fEventTree->Branch("mc_hitquark", &mc_hitquark);
348  fEventTree->Branch("mc_nu_Q2", &mc_nu_Q2);
349  fEventTree->Branch("mc_nu_W", &mc_nu_W);
350  fEventTree->Branch("mc_nu_X", &mc_nu_X);
351  fEventTree->Branch("mc_nu_Y", &mc_nu_Y);
352  fEventTree->Branch("mc_nu_Pt", &mc_nu_Pt);
353  fEventTree->Branch("mc_nu_Theta", &mc_nu_Theta);
354  fEventTree->Branch("mc_nu_pos", &mc_nu_pos, "mc_nu_pos[4]/F");
355  fEventTree->Branch("mc_nu_mom", &mc_nu_mom, "mc_nu_mom[4]/F");
356 
357  gDirectory = tmpDir;
358  if (fSaveJSON) {
359  system("rm -rf bee");
360  gSystem->MakeDirectory("bee");
361  // gSystem->ChangeDirectory("bee");
362  gSystem->MakeDirectory("bee/data");
363  }
364  }
365 
366  //-----------------------------------------------------------------------
368  {
369  // Write fEventTree to file
370  TDirectory* tmpDir = gDirectory;
371  fOutFile->cd("/Event");
372 
373  fEventTree->Write();
374 
375  gDirectory = tmpDir;
376 
377  fOutFile->Close();
378 
379  if (fSaveJSON) {
380  gSystem->ChangeDirectory("bee");
381  system("zip -r bee_upload data");
382  gSystem->ChangeDirectory("..");
383  }
384  }
385 
386  //-----------------------------------------------------------------------
387  void CellTree::beginRun(const art::Run& /*run*/)
388  {
389  mf::LogInfo("CellTree") << "begin run";
390  }
391 
392  //-----------------------------------------------------------------------
394  {
395  reset();
396  fEvent = event.id().event();
397  fRun = event.run();
398  fSubRun = event.subRun();
399  art::Timestamp ts = event.time();
400  TTimeStamp tts(ts.timeHigh(), ts.timeLow());
401  fEventTime = tts.AsDouble();
402 
403  if (fSaveRaw) processRaw(event);
404  if (fSaveCalib) processCalib(event);
405  if (fSaveOpHit) processOpHit(event);
406  if (fSaveOpFlash) processOpFlash(event);
408  if (fSaveMC) processMC(event);
409  if (fSaveTrigger) processTrigger(event);
410 
411  if (fSaveJSON) {
412  gSystem->MakeDirectory(TString::Format("bee/data/%i", entryNo).Data());
413  int nSp = fSpacePointLabels.size();
414  for (int i = 0; i < nSp; i++) {
415  TString jsonfile;
416  jsonfile.Form("bee/data/%i/%i-%s.json", entryNo, entryNo, fSpacePointLabels[i].c_str());
417  std::ofstream out(jsonfile.Data());
418  if (fSpacePointLabels[i] == "truthDepo") {
420  }
421  else {
422  processSpacePoint(event, fSpacePointLabels[i], out);
423  }
424  out.close();
425  }
426 
427  if (fSaveMC) {
428  processMCTracks();
429  TString jsonfile;
430  jsonfile.Form("bee/data/%i/%i-mc.json", entryNo, entryNo);
431  std::ofstream out(jsonfile.Data());
432  DumpMCJSON(out);
433  out.close();
434  }
435  }
436 
437  // printEvent();
438  fEventTree->Fill();
439 
440  entryNo++;
441  }
442 
443  //-----------------------------------------------------------------------
445  {
446 
447  fRaw_channelId.clear();
448  // fRaw_wf->Clear();
449  fRaw_wf->Delete();
450 
451  fCalib_channelId.clear();
452  fCalib_wf->Clear();
453 
454  oh_channel.clear();
455  oh_bgtime.clear();
456  oh_trigtime.clear();
457  oh_pe.clear();
458 
459  of_t.clear();
460  of_peTotal.clear();
461  of_multiplicity.clear();
462  fPEperOpDet->Delete();
463 
464  fSIMIDE_channelIdY.clear();
465  fSIMIDE_trackId.clear();
466  fSIMIDE_tdc.clear();
467  fSIMIDE_x.clear();
468  fSIMIDE_y.clear();
469  fSIMIDE_z.clear();
470  fSIMIDE_numElectrons.clear();
471 
472  mc_Ntrack = 0;
473  for (int i = 0; i < MAX_TRACKS; i++) {
474  mc_id[i] = 0;
475  mc_pdg[i] = 0;
476  mc_mother[i] = 0;
477  for (int j = 0; j < 4; j++) {
478  mc_startXYZT[i][j] = 0;
479  mc_endXYZT[i][j] = 0;
480  mc_startMomentum[i][j] = 0;
481  mc_endMomentum[i][j] = 0;
482  }
483  }
484  mc_daughters.clear();
485  savedMCTrackIdMap.clear();
486  fMC_trackPosition->Clear();
487 
488  mc_isnu = 0;
489  mc_nGeniePrimaries = -1;
490  mc_nu_pdg = -1;
491  mc_nu_ccnc = -1;
492  mc_nu_mode = -1;
493  mc_nu_intType = -1;
494  mc_nu_target = -1;
495  mc_hitnuc = -1;
496  mc_hitquark = -1;
497  mc_nu_Q2 = -1;
498  mc_nu_W = -1;
499  mc_nu_X = -1;
500  mc_nu_Y = -1;
501  mc_nu_Pt = -1;
502  mc_nu_Theta = -1;
503  for (int i = 0; i < 4; i++) {
504  mc_nu_pos[i] = 0;
505  mc_nu_mom[i] = 0;
506  }
507 
508  trackIndex.clear();
509  trackParents.clear();
510  trackChildren.clear();
511  trackSiblings.clear();
512  }
513 
514  //-----------------------------------------------------------------------
516  {
518  if (!event.getByLabel(fRawDigitLabel, rawdigit)) {
519  cout << "WARNING: no label " << fRawDigitLabel << endl;
520  return;
521  }
522  std::vector<art::Ptr<raw::RawDigit>> wires;
523  art::fill_ptr_vector(wires, rawdigit);
524 
525  fRaw_nChannel = wires.size();
526 
527  int i = 0;
528  for (auto const& wire : wires) {
529  int chanId = wire->Channel();
530  fRaw_channelId.push_back(chanId);
531 
532  int nSamples = wire->Samples();
533  std::vector<short> uncompressed(nSamples);
534  raw::Uncompress(wire->ADCs(), uncompressed, wire->Compression());
535 
536  TH1F* h = new ((*fRaw_wf)[i]) TH1F("", "", nRawSamples, 0, nRawSamples);
537  for (int j = 1; j <= nSamples; j++) {
538  h->SetBinContent(j, uncompressed[j - 1]);
539  }
540  i++;
541  if (i == 1) { cout << nSamples << " samples expanding to " << nRawSamples << endl; }
542  }
543  }
544 
545  //-----------------------------------------------------------------------
547  {
548 
550  if (!event.getByLabel(fCalibLabel, wires_handle)) {
551  cout << "WARNING: no label " << fCalibLabel << endl;
552  return;
553  }
554  std::vector<art::Ptr<recob::Wire>> wires;
555  art::fill_ptr_vector(wires, wires_handle);
556 
557  // wires size should == Nchannels == 1992; (no hit channel has a flat 0-waveform)
558  // cout << "\n wires size: " << wires.size() << endl;
559  fCalib_nChannel = wires.size();
560 
561  int i = 0;
562  for (auto const& wire : wires) {
563  std::vector<float> calibwf = wire->Signal();
564  int chanId = wire->Channel();
565  fCalib_channelId.push_back(chanId);
566  TH1F* h = new ((*fCalib_wf)[i]) TH1F("", "", nRawSamples, 0, nRawSamples);
567  for (int j = 1; j <= nRawSamples; j++) {
568  h->SetBinContent(j, calibwf[j]);
569  }
570  // fCalib_wf.push_back(calibwf);
571  // cout << chanId << ", " << nSamples << endl;
572  i++;
573  }
574  }
575 
576  //----------------------------------------------------------------------
578  {
580  if (!event.getByLabel(fOpHitLabel, ophit_handle)) {
581  cout << "WARNING: no label " << fOpHitLabel << endl;
582  return;
583  }
584  std::vector<art::Ptr<recob::OpHit>> ophits;
585  art::fill_ptr_vector(ophits, ophit_handle);
586  oh_nHits = (int)ophits.size();
587 
588  for (auto const& oh : ophits) {
589  oh_channel.push_back(oh->OpChannel());
590  oh_bgtime.push_back(oh->PeakTime());
591  oh_trigtime.push_back(oh->PeakTimeAbs());
592  oh_pe.push_back(oh->PE());
593  }
594  }
595 
596  //----------------------------------------------------------------------
598  {
600  if (!event.getByLabel(fOpFlashLabel, flash_handle)) {
601  cout << "WARNING: no label " << fOpFlashLabel << endl;
602  return;
603  }
604  std::vector<art::Ptr<recob::OpFlash>> flashes;
605  art::fill_ptr_vector(flashes, flash_handle);
606  of_nFlash = (int)flashes.size();
607 
608  int a = 0;
609  int nOpDet = fGeometry->NOpDets();
610 
611  for (auto const& flash : flashes) {
612  of_t.push_back(flash->Time());
613  of_peTotal.push_back(flash->TotalPE());
614  TH1F* h = new ((*fPEperOpDet)[a]) TH1F("", "", nOpDet, 0, nOpDet);
615 
616  int mult = 0;
617  for (int i = 0; i < nOpDet; ++i) {
618  if (flash->PE(i) >= opMultPEThresh) { mult++; }
619  h->SetBinContent(i, flash->PE(i));
620  }
621  of_multiplicity.push_back(mult);
622  a++;
623  }
624  }
625 
626  //-----------------------------------------------------------------------
628  {
630  // event.getByLabel("largeant", simChannelHandle);
631  if (!event.getByLabel(fSimChannelLabel, simChannelHandle)) {
632  cout << "WARNING: no label " << fSimChannelLabel << endl;
633  return;
634  }
635 
636  // cout << "total simChannel: " << (*simChannelHandle).size() << endl;
637  fSIMIDE_size = 0;
638  for (auto const& channel : (*simChannelHandle)) {
639  auto channelNumber = channel.Channel();
640  // cout << channelNumber << endl;
641  // if (! (fGeometry->SignalType( channelNumber ) == geo::kCollection) ) {
642  // continue;
643  // }
644  auto const& timeSlices = channel.TDCIDEMap();
645  for (auto const& timeSlice : timeSlices) {
646  auto const& energyDeposits = timeSlice.second;
647  for (auto const& energyDeposit : energyDeposits) {
648  fSIMIDE_size++;
649  fSIMIDE_channelIdY.push_back(channelNumber);
650  fSIMIDE_tdc.push_back(timeSlice.first);
651  fSIMIDE_trackId.push_back(energyDeposit.trackID);
652  fSIMIDE_x.push_back(energyDeposit.x);
653  fSIMIDE_y.push_back(energyDeposit.y);
654  fSIMIDE_z.push_back(energyDeposit.z);
655  fSIMIDE_numElectrons.push_back(energyDeposit.numElectrons);
656  // cout << channelNumber << ": " << energyDeposit.trackID << ": " << timeSlice.first << ": "
657  // << energyDeposit.x << ", " << energyDeposit.y << ", " << energyDeposit.z << ", "
658  // << energyDeposit.numElectrons << endl;
659  }
660  }
661  }
662  cout << "total IDEs: " << fSIMIDE_size << endl;
663  }
664 
665  //-----------------------------------------------------------------------
667  {
669  if (!event.getByLabel("largeant", particleHandle)) return;
670  std::vector<art::Ptr<simb::MCParticle>> particles;
671  art::fill_ptr_vector(particles, particleHandle);
672 
674  event.getByLabel("largeant", simChannelHandle);
675 
676  // art::ServiceHandle<cheat::BackTracker const> bt;
677  art::FindOneP<simb::MCTruth> fo(particleHandle, event, "largeant");
678 
679  int i = 0; // track index in saved MCParticles;
680  int i_all = 0; // track index in all MCParticles;
681  for (auto const& particle : particles) {
682  art::Ptr<simb::MCTruth> mctruth = fo.at(i_all);
683  i_all++;
684 
685  if (mcOption == "nuOnly") {
686  if (!(mctruth->Origin() == 1 && particle->Mother() == 0)) { continue; }
687  }
688 
689  // if (mctruth->Origin() == 1 || mc_mother[i] == 0) {
690  // cout << "process: " << particle->Process()
691  // << ", id: " << mc_id[i]
692  // << ", pdg: " << mc_pdg[i]
693  // << ", mother: " << mc_mother[i]
694  // << ", nDaughter: " << (particle->NumberDaughters())
695  // << ", truth: " << mctruth->Origin()
696  // << endl;
697  // }
698  // const art::Ptr<simb::MCTruth> mctruth = bt_serv->TrackIDToMCTruth(mc_id[i]);
699 
700  mc_process[i] = processMap[particle->Process()];
701  if (mc_process[i] == 0) cout << "unknown process: " << particle->Process() << endl;
702  mc_id[i] = particle->TrackId();
703  mc_pdg[i] = particle->PdgCode();
704  mc_mother[i] = particle->Mother();
705  savedMCTrackIdMap[mc_id[i]] = mc_pdg[i];
706 
707  int Ndaughters = particle->NumberDaughters();
708  vector<int> daughters;
709  for (int i = 0; i < Ndaughters; i++) {
710  daughters.push_back(particle->Daughter(i));
711  }
712  mc_daughters.push_back(daughters);
713  size_t numberTrajectoryPoints = particle->NumberTrajectoryPoints();
714  int last = numberTrajectoryPoints - 1;
715  const TLorentzVector& positionStart = particle->Position(0);
716  const TLorentzVector& positionEnd = particle->Position(last);
717  const TLorentzVector& momentumStart = particle->Momentum(0);
718  const TLorentzVector& momentumEnd = particle->Momentum(last);
719  positionStart.GetXYZT(mc_startXYZT[i]);
720  positionEnd.GetXYZT(mc_endXYZT[i]);
721  momentumStart.GetXYZT(mc_startMomentum[i]);
722  momentumEnd.GetXYZT(mc_endMomentum[i]);
723 
724  if (fSaveMCTrackPoints) {
725  TClonesArray* Lposition = new TClonesArray("TLorentzVector", numberTrajectoryPoints);
726  // Read the position and momentum along this particle track
727  for (unsigned int j = 0; j < numberTrajectoryPoints; j++) {
728  new ((*Lposition)[j]) TLorentzVector(particle->Position(j));
729  }
730  fMC_trackPosition->Add(Lposition);
731  }
732 
733  i++;
734  if (i == MAX_TRACKS) {
735  cout << "WARNING:: # tracks exceeded MAX_TRACKS " << MAX_TRACKS << endl;
736  break;
737  }
738  } // particle loop done
739  mc_Ntrack = i;
740  // cout << "MC_Ntracks:" << mc_Ntrack << endl;
741 
742  // Generator Info
743  art::Handle<std::vector<simb::MCTruth>> mctruthListHandle;
744  event.getByLabel("generator", mctruthListHandle);
745  std::vector<art::Ptr<simb::MCTruth>> mclist;
746  art::fill_ptr_vector(mclist, mctruthListHandle);
747  art::Ptr<simb::MCTruth> mctruth;
748 
749  if (mclist.size() > 0) {
750  mctruth = mclist.at(0);
751  if (mctruth->NeutrinoSet()) {
752  simb::MCNeutrino nu = mctruth->GetNeutrino();
753  mc_isnu = 1;
754  mc_nGeniePrimaries = mctruth->NParticles();
755  mc_nu_pdg = nu.Nu().PdgCode();
756  mc_nu_ccnc = nu.CCNC();
757  mc_nu_mode = nu.Mode();
759  mc_nu_target = nu.Target();
760  mc_hitnuc = nu.HitNuc();
761  mc_hitquark = nu.HitQuark();
762  mc_nu_Q2 = nu.QSqr();
763  mc_nu_W = nu.W();
764  mc_nu_X = nu.X();
765  mc_nu_Y = nu.Y();
766  mc_nu_Pt = nu.Pt();
767  mc_nu_Theta = nu.Theta();
768 
769  const TLorentzVector& position = nu.Nu().Position(0);
770  const TLorentzVector& momentum = nu.Nu().Momentum(0);
771  position.GetXYZT(mc_nu_pos);
772  momentum.GetXYZT(mc_nu_mom);
773  // cout << "nu: " << mc_nu_pdg << ", nPrim: " << mc_nGeniePrimaries
774  // << ", ccnc: " << mc_nu_ccnc << endl;
775  // for (int i=0; i<mc_nGeniePrimaries; i++) {
776  // simb::MCParticle particle = mctruth->GetParticle(i);
777  // cout << "id: " << particle.TrackId()
778  // << ", pdg: " << particle.PdgCode()
779  // << endl;
780  // }
781  }
782  }
783  }
784 
785  //-----------------------------------------------------------------------
786  void CellTree::processSpacePoint(const art::Event& event, TString option, ostream& out)
787  {
788 
791  bool sp_exists = event.getByLabel(option.Data(), sp_handle);
792  bool pc_exists = event.getByLabel(option.Data(), pc_handle);
793  if (!sp_exists) {
794  cout << "WARNING: no label " << option << endl;
795  return;
796  }
797  std::vector<art::Ptr<recob::SpacePoint>> sps;
798  std::vector<art::Ptr<recob::PointCharge>> pcs;
799  art::fill_ptr_vector(sps, sp_handle);
800  if (pc_exists) {
801  art::fill_ptr_vector(pcs, pc_handle);
802  if (sps.size() != pcs.size()) {
803  cout << "WARNING: SpacePoint and PointCharge length mismatch" << endl;
804  return;
805  }
806  }
807  double x = 0, y = 0, z = 0, q = 0, nq = 1;
808  vector<double> vx, vy, vz, vq, vnq;
809 
810  for (uint i = 0; i < sps.size(); i++) {
811  // cout << sp->XYZ()[0] << ", " << sp->XYZ()[1] << ", " << sp->XYZ()[2] << endl;
812  x = sps[i]->XYZ()[0];
813  y = sps[i]->XYZ()[1];
814  z = sps[i]->XYZ()[2];
815  if (pc_exists && pcs[i]->hasCharge()) { q = pcs[i]->charge(); }
816  else {
817  q = 0;
818  }
819  vx.push_back(x);
820  vy.push_back(y);
821  vz.push_back(z);
822  vq.push_back(q);
823  vnq.push_back(nq);
824  }
825 
826  out << fixed << setprecision(1);
827  out << "{" << endl;
828 
829  out << '"' << "runNo" << '"' << ":" << '"' << fRun << '"' << "," << endl;
830  out << '"' << "subRunNo" << '"' << ":" << '"' << fSubRun << '"' << "," << endl;
831  out << '"' << "eventNo" << '"' << ":" << '"' << fEvent << '"' << "," << endl;
832 
833  TString geomName(fGeometry->DetectorName().c_str());
834  if (geomName.Contains("35t")) { geomName = "dune35t"; }
835  else if (geomName.Contains("protodunevd")) {
836  geomName = "protodunevd";
837  }
838  else if (geomName.Contains("protodune")) {
839  geomName = "protodune";
840  }
841  else if (geomName.Contains("workspace")) {
842  geomName = "dune10kt_workspace";
843  }
844  else if (geomName.Contains("icarus")) {
845  geomName = "icarus";
846  }
847  else if (geomName.Contains("sbnd")) {
848  geomName = "sbnd";
849  }
850  else {
851  geomName = "uboone";
852  } // use uboone as default
853  out << '"' << "geom" << '"' << ":" << '"' << geomName << '"' << "," << endl;
854 
855  print_vector(out, vx, "x");
856  print_vector(out, vy, "y");
857  print_vector(out, vz, "z");
858 
859  out << fixed << setprecision(0);
860  print_vector(out, vq, "q");
861  print_vector(out, vnq, "nq");
862 
863  out << '"' << "type" << '"' << ":" << '"' << option << '"' << endl;
864  out << "}" << endl;
865  }
866 
867  //---- The X-axis position along drift changes to wire plane readout view without t0 correction ----
869  TString option,
870  ostream& out,
871  bool t0_corrected)
872  {
873 
875  if (!event.getByLabel(fSimEnergyDepositLabel, sed_handle)) {
876  cout << "WARNING: no label " << fSimEnergyDepositLabel << " for SimEnergyDeposit" << endl;
877  return;
878  }
879  std::vector<art::Ptr<sim::SimEnergyDeposit>> sed;
880  art::fill_ptr_vector(sed, sed_handle);
881  int size = sed.size();
882  double t = 0, x = 0, y = 0, z = 0, q = 0, nq = 1, cluster_id = 1;
883  vector<double> vx, vy, vz, vq, vnq, vcluster;
884 
885  TString geomName(fGeometry->DetectorName().c_str());
886  if (geomName.Contains("35t")) { geomName = "dune35t"; }
887  else if (geomName.Contains("protodunevd")) {
888  geomName = "protodunevd";
889  }
890  else if (geomName.Contains("protodune")) {
891  geomName = "protodune";
892  }
893  else if (geomName.Contains("workspace")) {
894  geomName = "dune10kt_workspace";
895  }
896  else if (geomName.Contains("icarus")) {
897  geomName = "icarus";
898  }
899  else if (geomName.Contains("sbnd")) {
900  geomName = "sbnd";
901  }
902  else {
903  geomName = "uboone";
904  } // use uboone as default
905 
906  for (int i = 0; i < size; i++) {
907  // cout << sp->XYZ()[0] << ", " << sp->XYZ()[1] << ", " << sp->XYZ()[2] << endl;
908  x = sed[i]->MidPointX(); // unit: cm
909  t = sed[i]->Time(); // unit: ns
910  y = sed[i]->MidPointY();
911  z = sed[i]->MidPointZ();
912  q = sed[i]->NumElectrons();
913  if (q < 0) q = sed[i]->Energy() * 25000; // approx. #electrons
914  // cout << q << ", " << sed[i]->Energy()*25000 << endl;
915  if (q < 1000) continue; // skip small dots to reduce size
916  if (!t0_corrected) { // t0 ''enters'' in position along drift
917  if (geomName == "sbnd") {
918  if (x < 0) {
919  x = x + t * 1e-3 * drift_speed * 0.1;
920  cluster_id = 1;
921  }
922  else if (x > 0) {
923  x = x - t * 1e-3 * drift_speed * 0.1;
924  cluster_id = 2;
925  }
926  else {
927  cluster_id = 3;
928  }
929  if (t * 1e-3 > 0 && t * 1e-3 < 5) cluster_id = 0;
930  }
931  else if (geomName == "uboone") {
932  x = x + t * 1e-3 * drift_speed * 0.1;
933  }
934  else {
935  cout << "t0 uncorrection for drift volume(s) yet to be added for " << geomName << endl;
936  }
937  }
938  vx.push_back(x);
939  vy.push_back(y);
940  vz.push_back(z);
941  vq.push_back(q);
942  vnq.push_back(nq);
943  vcluster.push_back(cluster_id);
944  }
945 
946  out << fixed << setprecision(1);
947  out << "{" << endl;
948 
949  out << '"' << "runNo" << '"' << ":" << '"' << fRun << '"' << "," << endl;
950  out << '"' << "subRunNo" << '"' << ":" << '"' << fSubRun << '"' << "," << endl;
951  out << '"' << "eventNo" << '"' << ":" << '"' << fEvent << '"' << "," << endl;
952 
953  out << '"' << "geom" << '"' << ":" << '"' << geomName << '"' << "," << endl;
954 
955  print_vector(out, vx, "x");
956  print_vector(out, vy, "y");
957  print_vector(out, vz, "z");
958 
959  out << fixed << setprecision(0);
960  print_vector(out, vq, "q");
961  print_vector(out, vnq, "nq");
962  print_vector(out, vcluster, "cluster_id");
963 
964  out << '"' << "type" << '"' << ":" << '"' << option << '"' << endl;
965  out << "}" << endl;
966  }
967 
968  //-----------------------------------------------------------------------
969  void CellTree::print_vector(ostream& out, vector<double>& v, TString desc, bool end)
970  {
971  int N = v.size();
972 
973  out << '"' << desc << '"' << ":[";
974  for (int i = 0; i < N; i++) {
975  out << v[i];
976  if (i != N - 1) { out << ","; }
977  }
978  out << "]";
979  if (!end) out << ",";
980  out << endl;
981  }
982 
983  //-----------------------------------------------------------------------
985  {
986  // map track id to track index in the array
987  for (int i = 0; i < mc_Ntrack; i++) {
988  trackIndex[mc_id[i]] = i;
989  }
990 
991  // in trackParents, trackChildren, trackSiblings vectors, store track index (not track id)
992  for (int i = 0; i < mc_Ntrack; i++) {
993  // currently, parent size == 1;
994  // for primary particle, parent id = 0;
995  vector<int> parents;
996  if (!IsPrimary(i)) { parents.push_back(trackIndex[mc_mother[i]]); }
997  trackParents.push_back(parents); // primary track will have 0 parents
998 
999  vector<int> children;
1000  int nChildren = mc_daughters.at(i).size();
1001  for (int j = 0; j < nChildren; j++) {
1002  children.push_back(trackIndex[mc_daughters.at(i).at(j)]);
1003  }
1004  trackChildren.push_back(children);
1005  }
1006 
1007  // siblings
1008  for (int i = 0; i < mc_Ntrack; i++) {
1009  vector<int> siblings;
1010  if (IsPrimary(i)) {
1011  for (int j = 0; j < mc_Ntrack; j++) {
1012  if (IsPrimary(j)) { siblings.push_back(j); }
1013  }
1014  }
1015  else {
1016  // siblings are simply children of the mother
1017  int mother = trackIndex[mc_mother[i]];
1018  int nSiblings = trackChildren.at(mother).size();
1019  for (int j = 0; j < nSiblings; j++) {
1020  siblings.push_back(trackChildren.at(mother).at(j));
1021  }
1022  }
1023  trackSiblings.push_back(siblings);
1024  }
1025  }
1026 
1027  //-----------------------------------------------------------------------
1029  {
1030  art::Handle<std::vector<raw::Trigger>> triggerListHandle;
1031  std::vector<art::Ptr<raw::Trigger>> triggerlist;
1032  if (event.getByLabel(fTriggerLabel, triggerListHandle)) {
1033  art::fill_ptr_vector(triggerlist, triggerListHandle);
1034  }
1035  else {
1036  cout << "WARNING: no trigger label " << fTriggerLabel << endl;
1037  }
1038  if (triggerlist.size()) {
1039  fTriggernumber = triggerlist[0]->TriggerNumber();
1040  fTriggertime = triggerlist[0]->TriggerTime();
1041  fBeamgatetime = triggerlist[0]->BeamGateTime();
1042  fTriggerbits = triggerlist[0]->TriggerBits();
1043  }
1044  else {
1045  fTriggernumber = 0;
1046  fTriggertime = 0;
1047  fBeamgatetime = 0;
1048  fTriggerbits = 0;
1049  }
1050  }
1051 
1052  //-----------------------------------------------------------------------
1053  bool CellTree::DumpMCJSON(int id, ostream& out)
1054  {
1055  int i = trackIndex[id];
1056  if (!KeepMC(i)) return false;
1057 
1058  int e = KE(mc_startMomentum[i]) * 1000;
1059 
1060  int nDaughter = mc_daughters.at(i).size();
1061  vector<int> saved_daughters;
1062  for (int j = 0; j < nDaughter; j++) {
1063  int daughter_id = mc_daughters.at(i).at(j);
1064  // int e_daughter = KE(mc_startMomentum[ trackIndex[daughter_id] ])*1000;
1065  // if (e_daughter >= thresh_KE) {
1066  if (KeepMC(trackIndex[daughter_id])) { saved_daughters.push_back(daughter_id); }
1067  }
1068 
1069  vector<double> vx, vy, vz;
1070  if (fSaveMCTrackPoints) {
1071  // fMC_trackPosition->Print();
1072  TClonesArray* traj = (TClonesArray*)(*fMC_trackPosition)[i];
1073  int nPoints = traj->GetEntries();
1074  // cout << "traj points: " << nPoints << endl;
1075  for (int j = 0; j < nPoints; j++) {
1076  TLorentzVector* pos = (TLorentzVector*)(*traj)[j];
1077  vx.push_back(pos->X());
1078  vy.push_back(pos->Y());
1079  vz.push_back(pos->Z());
1080  }
1081  }
1082 
1083  out << fixed << setprecision(1);
1084  out << "{";
1085 
1086  out << "\"id\":" << id << ",";
1087  out << "\"text\":"
1088  << "\"" << PDGName(mc_pdg[i]) << " " << e << " MeV\",";
1089  out << "\"data\":{";
1090  print_vector(out, vx, "traj_x");
1091  print_vector(out, vy, "traj_y");
1092  print_vector(out, vz, "traj_z");
1093  out << "\"start\":[" << mc_startXYZT[i][0] << ", " << mc_startXYZT[i][1] << ", "
1094  << mc_startXYZT[i][2] << "],";
1095  out << "\"end\":[" << mc_endXYZT[i][0] << ", " << mc_endXYZT[i][1] << ", " << mc_endXYZT[i][2]
1096  << "]";
1097  out << "},";
1098  out << "\"children\":[";
1099  int nSavedDaughter = saved_daughters.size();
1100  if (nSavedDaughter == 0) {
1101  out << "],";
1102  out << "\"icon\":"
1103  << "\"jstree-file\"";
1104  out << "}";
1105  return true;
1106  }
1107  else {
1108  for (int j = 0; j < nSavedDaughter; j++) {
1109  DumpMCJSON(saved_daughters.at(j), out);
1110  if (j != nSavedDaughter - 1) { out << ","; }
1111  }
1112  out << "]";
1113  out << "}";
1114  return true;
1115  }
1116  }
1117 
1118  //-----------------------------------------------------------------------
1119  void CellTree::DumpMCJSON(ostream& out)
1120  {
1121  out << "[";
1122  vector<int> primaries;
1123  for (int i = 0; i < mc_Ntrack; i++) {
1124  if (IsPrimary(i)) {
1125  // int e = KE(mc_startMomentum[i])*1000;
1126  // if (e<thresh_KE) continue;
1127  if (KeepMC(i)) { primaries.push_back(i); }
1128  }
1129  }
1130  int size = primaries.size();
1131  // cout << size << endl;
1132  for (int i = 0; i < size; i++) {
1133  if (DumpMCJSON(mc_id[primaries[i]], out) && i != size - 1) { out << ", "; }
1134  }
1135 
1136  out << "]";
1137  }
1138 
1139  //-----------------------------------------------------------------------
1140  double CellTree::KE(float* momentum)
1141  {
1142  TLorentzVector particle(momentum);
1143  return particle.E() - particle.M();
1144  }
1145 
1146  //-----------------------------------------------------------------------
1147  bool CellTree::KeepMC(int i)
1148  {
1149  double e = KE(mc_startMomentum[i]) * 1000;
1150  double thresh_KE_em = 5.; // MeV
1151  double thresh_KE_np = 50; // MeV
1152  // cout << "pdg: " << mc_pdg[i] << ", KE: " << e << " MeV, process: " << mc_process[i] << endl;
1153  if (mc_process[i] == 8 // muIoni
1154  || mc_process[i] == 6 // eBrem
1155  || mc_process[i] == 5 // eIoni
1156  ) {
1157  return false; // skip those ionization and radiation electrons as there are too many to show.
1158  }
1159 
1160  if (mc_pdg[i] == 22 || mc_pdg[i] == 11 || mc_pdg[i] == -11) {
1161  if (e >= thresh_KE_em)
1162  return true;
1163  else
1164  return false;
1165  }
1166  else if (mc_pdg[i] == 2112 || mc_pdg[i] == 2212 || mc_pdg[i] > 1e9) {
1167  if (e >= thresh_KE_np)
1168  return true;
1169  else
1170  return false;
1171  }
1172  return true;
1173  }
1174 
1175  //-----------------------------------------------------------------------
1176  TString CellTree::PDGName(int pdg)
1177  {
1178  TParticlePDG* p = dbPDG->GetParticle(pdg);
1179  if (p == 0) {
1180  if (pdg > 1e9) {
1181  int z = (pdg - 1e9) / 10000;
1182  int a = (pdg - 1e9 - z * 1e4) / 10;
1183  TString name;
1184  if (z == 18)
1185  name = "Ar";
1186 
1187  else if (z == 17)
1188  name = "Cl";
1189  else if (z == 19)
1190  name = "Ca";
1191  else if (z == 16)
1192  name = "S";
1193  else if (z == 15)
1194  name = "P";
1195  else if (z == 14)
1196  name = "Si";
1197  else if (z == 1)
1198  name = "H";
1199  else if (z == 2)
1200  name = "He";
1201 
1202  else
1203  return Form("%i", pdg);
1204  return Form("%s-%i", name.Data(), a);
1205  }
1206  return Form("%i", pdg);
1207  }
1208  else {
1209  return p->GetName();
1210  }
1211  }
1212 
1213  //-----------------------------------------------------------------------
1215  {
1216  cout << " Run/SubRun/Event: " << fRun << "/" << fSubRun << "/" << fEvent << endl;
1217  cout << " Ntracks:" << mc_Ntrack << endl;
1218 
1219  for (int i = 0; i < mc_Ntrack; i++) {
1220  cout << "\n id: " << mc_id[i];
1221  cout << "\n pdg: " << mc_pdg[i];
1222  cout << "\n mother: " << mc_mother[i];
1223  cout << "\n Ndaughters: " << mc_daughters.at(i).size();
1224  cout << "\n start XYZT: (" << mc_startXYZT[i][0] << ", " << mc_startXYZT[i][1] << ", "
1225  << mc_startXYZT[i][2] << ", " << mc_startXYZT[i][3] << ")";
1226  cout << "\n end XYZT: (" << mc_endXYZT[i][0] << ", " << mc_endXYZT[i][1] << ", "
1227  << mc_endXYZT[i][2] << ", " << mc_endXYZT[i][3] << ")";
1228  cout << "\n start momentum: (" << mc_startMomentum[i][0] << ", " << mc_startMomentum[i][1]
1229  << ", " << mc_startMomentum[i][2] << ", " << mc_startMomentum[i][3] << ")";
1230  cout << "\n end momentum: (" << mc_endMomentum[i][0] << ", " << mc_endMomentum[i][1]
1231  << ", " << mc_endMomentum[i][2] << ", " << mc_endMomentum[i][3] << ")";
1232 
1233  cout << endl;
1234  }
1235  }
1236 
1237  //-----------------------------------------------------------------------
1239  {
1240  processMap["unknown"] = 0;
1241  processMap["primary"] = 1;
1242  processMap["compt"] = 2;
1243  processMap["phot"] = 3;
1244  processMap["annihil"] = 4;
1245  processMap["eIoni"] = 5;
1246  processMap["eBrem"] = 6;
1247  processMap["conv"] = 7;
1248  processMap["muIoni"] = 8;
1249  processMap["muMinusCaptureAtRest"] = 9;
1250  processMap["neutronInelastic"] = 10;
1251  processMap["nCapture"] = 11;
1252  processMap["hadElastic"] = 12;
1253  processMap["Decay"] = 13;
1254  processMap["CoulombScat"] = 14;
1255  processMap["muPairProd"] = 15;
1256  processMap["muBrems"] = 16;
1257  processMap["muPairProd"] = 17;
1258  processMap["PhotonInelastic"] = 18;
1259  processMap["hIoni"] = 19;
1260  processMap["protonInelastic"] = 20;
1261  processMap["pi+Inelastic"] = 21;
1262  processMap["CHIPSNuclearCaptureAtRest"] = 22;
1263  processMap["pi-Inelastic"] = 23;
1264  }
1265 
1266  //-----------------------------------------------------------------------
1268 } // namespace microboone
Float_t x
Definition: compare.C:6
float mc_startMomentum[MAX_TRACKS][4]
std::vector< std::vector< int > > trackChildren
vector< double > oh_pe
vector< int > fSIMIDE_channelIdY
const TLorentzVector & Position(const int i=0) const
Definition: MCParticle.h:220
int PdgCode() const
Definition: MCParticle.h:213
int CCNC() const
Definition: MCNeutrino.h:148
constexpr std::uint32_t timeLow() const
Definition: Timestamp.h:29
double QSqr() const
Definition: MCNeutrino.h:157
double Theta() const
angle between incoming and outgoing leptons, in radians
Definition: MCNeutrino.cxx:63
const simb::MCNeutrino & GetNeutrino() const
Definition: MCTruth.h:77
system("rm -rf microbeam.root")
std::map< int, int > trackIndex
vector< int > fSIMIDE_trackId
int HitQuark() const
Definition: MCNeutrino.h:153
std::string fSimChannelLabel
float mc_endXYZT[MAX_TRACKS][4]
void processMCTracks()
void processRaw(const art::Event &evt)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
int mc_id[MAX_TRACKS]
TString PDGName(int pdg)
Float_t y
Definition: compare.C:6
const simb::MCParticle & Nu() const
Definition: MCNeutrino.h:146
constexpr std::uint32_t timeHigh() const
Definition: Timestamp.h:34
Double_t z
Definition: plot.C:276
simb::Origin_t Origin() const
Definition: MCTruth.h:74
double Pt() const
transverse momentum of interaction, in GeV/c
Definition: MCNeutrino.cxx:74
int HitNuc() const
Definition: MCNeutrino.h:152
int mc_pdg[MAX_TRACKS]
std::vector< std::vector< int > > trackSiblings
vector< int > of_multiplicity
STL namespace.
Definition of basic raw digits.
Information about charge reconstructed in the active volume.
vector< float > fSIMIDE_y
int NParticles() const
Definition: MCTruth.h:75
void processSimChannel(const art::Event &evt)
Particle class.
art::ServiceHandle< geo::Geometry const > fGeometry
std::string fOutFileName
std::string fRawDigitLabel
Definition: Run.h:37
vector< float > fSIMIDE_x
bool DumpMCJSON(int id, ostream &out)
int mc_mother[MAX_TRACKS]
vector< unsigned short > fSIMIDE_tdc
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
std::map< int, int > savedMCTrackIdMap
float mc_endMomentum[MAX_TRACKS][4]
vector< int > oh_channel
std::string fOpHitLabel
std::string fOpFlashLabel
int InteractionType() const
Definition: MCNeutrino.h:150
int mc_process[MAX_TRACKS]
void analyze(const art::Event &evt)
void print_vector(ostream &out, vector< double > &v, TString desc, bool end=false)
double W() const
Definition: MCNeutrino.h:154
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
vector< double > oh_bgtime
bool KeepMC(int i)
double Y() const
Definition: MCNeutrino.h:156
TDatabasePDG * dbPDG
void processOpFlash(const art::Event &evt)
vector< double > oh_trigtime
TClonesArray * fCalib_wf
Collect all the RawData header files together.
T get(std::string const &key) const
Definition: ParameterSet.h:314
TObjArray * fMC_trackPosition
std::vector< int > fRaw_channelId
double X() const
Definition: MCNeutrino.h:155
vector< float > fSIMIDE_z
unsigned int fTriggerbits
std::string fSimEnergyDepositLabel
#define MAX_TRACKS
void processOpHit(const art::Event &evt)
std::vector< std::vector< int > > mc_daughters
TClonesArray * fRaw_wf
void beginRun(const art::Run &run)
unsigned int NOpDets() const
Number of OpDets in the whole detector.
unsigned int fTriggernumber
double KE(float *momentum)
std::string mcOption
std::vector< int > fCalib_channelId
int Target() const
Definition: MCNeutrino.h:151
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
void processCalib(const art::Event &evt)
std::string fCalibLabel
float mc_nu_mom[4]
contains information for a single step in the detector simulation
void processMC(const art::Event &evt)
std::vector< std::string > fSpacePointLabels
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:221
object containing MC truth information necessary for making RawDigits and doing back tracking ...
TClonesArray * fPEperOpDet
vector< float > fSIMIDE_numElectrons
std::string fTriggerLabel
std::map< std::string, int > processMap
Declaration of basic channel signal object.
float mc_startXYZT[MAX_TRACKS][4]
std::string const & DetectorName() const
Returns a string with the name of the detector, as configured.
Definition: GeometryCore.h:203
bool NeutrinoSet() const
Definition: MCTruth.h:78
TCEvent evt
Definition: DataStructs.cxx:8
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:306
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:744
Float_t e
Definition: plot.C:35
void processSpacePoint(const art::Event &event, TString option, ostream &out=cout)
bool IsPrimary(int i)
Event generator information.
Definition: MCNeutrino.h:18
void processSpacePointTruthDepo(const art::Event &event, TString option, ostream &out=cout, bool t0_corrected=true)
vector< float > of_peTotal
int Mode() const
Definition: MCNeutrino.h:149
float mc_nu_pos[4]
art framework interface to geometry description
Event finding and building.
void processTrigger(const art::Event &evt)
vector< float > of_t
std::vector< std::vector< int > > trackParents