DAQSimAna_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: DAQSimAna
3 // Module Type: analyzer
4 // File: DAQSimAna_module.cc
5 //
6 // Generated by Michael Baird using the old copy and paste...
7 // from cetpkgsupport v1_10_01.
8 ////////////////////////////////////////////////////////////////////////
9 
10 // C++ includes
11 
12 // ROOT includes
13 #include "TH1I.h"
14 #include "TH1F.h"
15 #include "TH2F.h"
16 #include "TTree.h"
17 
18 // Framework includes
23 #include "lardataobj/RawData/raw.h"
27 
30 
37 #include "art_root_io/TFileDirectory.h"
38 #include "art_root_io/TFileService.h"
41 #include "canvas/Persistency/Common/FindMany.h"
42 #include "canvas/Persistency/Common/FindManyP.h"
43 #include "fhiclcpp/ParameterSet.h"
45 
46 //const int nMaxDigs = 4492; // unused
47 
49 
50 class DAQSimAna : public art::EDAnalyzer {
51 
52 public:
53 
54  explicit DAQSimAna(fhicl::ParameterSet const & p);
55 
56  // Plugins should not be copied or assigned.
57  DAQSimAna(DAQSimAna const &) = delete;
58  DAQSimAna(DAQSimAna &&) = delete;
59  DAQSimAna & operator = (DAQSimAna const &) = delete;
60  DAQSimAna & operator = (DAQSimAna &&) = delete;
61 
62  // The main guts...
63  void analyze(art::Event const & evt) override;
64 
65  void reconfigure(fhicl::ParameterSet const & p);
66 
67  void beginJob() override;
68 
69 private:
70 
71  // --- Some of our own functions.
72  void ResetVariables();
73  void FillMyMaps ( std::map< int, simb::MCParticle> &MyMap,
74  art::FindManyP<simb::MCParticle> Assn,
75  art::ValidHandle< std::vector<simb::MCTruth> > Hand,
76  std::map<int, int>* indexMap=nullptr);
77  PType WhichParType( int TrID );
79  bool InMyMap ( int TrID, std::map< int, simb::MCParticle> ParMap );
80  void CalcAdjHits ( std::vector< recob::Hit > MyVec, TH1I* MyHist, bool HeavDebug="false" );
81  void SaveIDEs(art::Event const & evt);
82 
83  // --- Our fcl parameter labels for the modules that made the data products
87 
89  std::string fMARLLabel; std::map< int, simb::MCParticle > MarlParts;
90  std::string fAPALabel; std::map< int, simb::MCParticle > APAParts;
91  std::string fCPALabel; std::map< int, simb::MCParticle > CPAParts;
92  std::string fAr39Label; std::map< int, simb::MCParticle > Ar39Parts;
93  std::string fAr42Label; std::map< int, simb::MCParticle > Ar42Parts;
94  std::string fNeutLabel; std::map< int, simb::MCParticle > NeutParts;
95  std::string fKrypLabel; std::map< int, simb::MCParticle > KrypParts;
96  std::string fPlonLabel; std::map< int, simb::MCParticle > PlonParts;
97  std::string fRdonLabel; std::map< int, simb::MCParticle > RdonParts;
98 
99  std::map<int, int> trkIDToMarleyIndex;
100 
101  // Mapping from track ID to particle type, for use in WhichParType()
102  std::map<int, PType> trkIDToPType;
103 
104  // --- Other variables
105  //int nADC; // no longer used
106 
107  // --- Our TTree, and its associated variables.
108  TTree* fDAQSimTree;
109  // General event info.
110  int Run;
111  int SubRun;
112  int Event;
113  // Raw digits
114  //int NTotDigs; // unused
115 
116  // The reconstructed hits
117  int NTotHits;
118  int NColHits;
119  int NIndHits;
120 
121  std::vector<int> HitView; ///< View i.e Coll, U, V
122  std::vector<int> HitSize; ///< Time width (ticks) Start - End time
123  std::vector<int> HitTPC; ///< The TPC which the hit occurs in
124  std::vector<int> HitChan; ///< The channel which the hit occurs on
125  std::vector<float> HitTime; ///< The time of the hit (ticks)
126  std::vector<float> HitRMS; ///< The RMS of the hit
127  std::vector<float> HitSADC; ///< The summed ADC of the hit
128  std::vector<float> HitInt; ///< The ADC integral of the hit
129  std::vector<float> HitPeak; ///< The peak ADC value of the hit
130  std::vector<int> GenType; ///< The generator which generated the particle responsible for the hit
131  std::vector<int> MarleyIndex; ///< Which SN in the list of Marley interactions this hit is from (-1 if not from SN)
132 
142 
143  int NTotIDEs;
144  std::vector<int> IDEChannel;
145  std::vector<int> IDEStartTime;
146  std::vector<int> IDEEndTime;
147  std::vector<float> IDEEnergy;
148  std::vector<float> IDEElectrons;
149  std::vector<int> IDEParticle;
150 
151  // histograms to fill about Collection plane hits
162 
163  // --- Declare our services
167 
168 };
169 
170 //......................................................
172  :
173  EDAnalyzer(p)
174 {
175  this->reconfigure(p);
176 }
177 
178 //......................................................
180 {
181  fRawDigitLabel = p.get<std::string> ("RawDigitLabel");
182  fHitLabel = p.get<std::string> ("HitLabel");
183 
184  fGEANTLabel = p.get<std::string> ("GEANT4Label");
185  fMARLLabel = p.get<std::string> ("MARLEYLabel");
186  fAPALabel = p.get<std::string> ("APALabel");
187  fCPALabel = p.get<std::string> ("CPALabel");
188  fAr39Label = p.get<std::string> ("Argon39Label");
189  fAr42Label = p.get<std::string> ("Argon42Label");
190  fNeutLabel = p.get<std::string> ("NeutronLabel");
191  fKrypLabel = p.get<std::string> ("KryptonLabel");
192  fPlonLabel = p.get<std::string> ("PoloniumLabel");
193  fRdonLabel = p.get<std::string> ("RadonLabel");
194 
195  fDoCalcAdjHits = p.get<bool>("DoCalcAdjHits", false);
196 } // Reconfigure
197 
198 //......................................................
200 {
201  // Clear my MCParticle maps.
202  MarlParts.clear(); APAParts .clear(); CPAParts .clear(); Ar39Parts.clear();
203  Ar42Parts.clear();
204  NeutParts.clear(); KrypParts.clear(); PlonParts.clear(); RdonParts.clear();
205 
206  trkIDToPType.clear();
207 
208  // General event info.
209  Run = SubRun = Event = -1;
210 
211  // Set Number of GenParts to 0
213  TotGen_Ar42=0;
215 
216  // reconstructed hits
217  NTotHits = NColHits = NIndHits = 0;
218 
219  HitView.clear();
220  HitSize.clear();
221  HitTPC.clear();
222  HitChan.clear();
223  HitTime.clear();
224  HitRMS.clear();
225  HitSADC.clear();
226  HitInt.clear();
227  HitPeak.clear();
228  GenType.clear();
229  MarleyIndex.clear();
230 
231  // IDEs
232  NTotIDEs=0;
233  IDEChannel.clear();
234  IDEStartTime.clear();
235  IDEEndTime.clear();
236  IDEEnergy.clear();
237  IDEElectrons.clear();
238  IDEParticle.clear();
239 
240 } // ResetVariables
241 
242 //......................................................
244 {
245  // --- Make our handle to the TFileService
247  // --- Our TTree
248  fDAQSimTree = tfs->make<TTree>("DAQSimTree","DAQ simulation analysis tree");
249  // General event information...
250  fDAQSimTree -> Branch( "Run" , &Run , "Run/I" );
251  fDAQSimTree -> Branch( "SubRun", &SubRun, "SubRun/I" );
252  fDAQSimTree -> Branch( "Event" , &Event , "Event/I" );
253  // Reconstructed hits...
254  fDAQSimTree -> Branch( "NTotHits" , &NTotHits , "NTotHits/I" );
255  fDAQSimTree -> Branch( "NColHits" , &NColHits , "NColHits/I" );
256  fDAQSimTree -> Branch( "NIndHits" , &NIndHits , "NIndHits/I" );
257 
258  fDAQSimTree->Branch("HitView", &HitView);
259  fDAQSimTree->Branch("HitSize", &HitSize);
260  fDAQSimTree->Branch("HitTPC", &HitTPC);
261  fDAQSimTree->Branch("HitChan", &HitChan);
262  fDAQSimTree->Branch("HitTime", &HitTime);
263  fDAQSimTree->Branch("HitRMS", &HitRMS);
264  fDAQSimTree->Branch("HitSADC", &HitSADC);
265  fDAQSimTree->Branch("HitInt", &HitInt);
266  fDAQSimTree->Branch("HitPeak", &HitPeak);
267  fDAQSimTree->Branch("GenType", &GenType);
268  fDAQSimTree->Branch("MarleyIndex", &MarleyIndex);
269 
270  fDAQSimTree -> Branch( "TotGen_Marl", &TotGen_Marl, "TotGen_Marl/I" );
271  fDAQSimTree -> Branch( "TotGen_APA" , &TotGen_APA , "TotGen_APA/I" );
272  fDAQSimTree -> Branch( "TotGen_CPA" , &TotGen_CPA , "TotGen_CPA/I" );
273  fDAQSimTree -> Branch( "TotGen_Ar39", &TotGen_Ar39, "TotGen_Ar39/I" );
274  fDAQSimTree -> Branch( "TotGen_Ar42", &TotGen_Ar42, "TotGen_Ar42/I" );
275  fDAQSimTree -> Branch( "TotGen_Neut", &TotGen_Neut, "TotGen_Neut/I" );
276  fDAQSimTree -> Branch( "TotGen_Kryp", &TotGen_Kryp, "TotGen_Kryp/I" );
277  fDAQSimTree -> Branch( "TotGen_Plon", &TotGen_Plon, "TotGen_Plon/I" );
278  fDAQSimTree -> Branch( "TotGen_Rdon", &TotGen_Rdon, "TotGen_Rdon/I" );
279 
280  // IDEs
281  fDAQSimTree -> Branch( "NTotIDEs" , &NTotIDEs , "NTotIDEs/I" );
282  fDAQSimTree->Branch("IDEChannel", &IDEChannel);
283  fDAQSimTree->Branch("IDEStartTime", &IDEStartTime);
284  fDAQSimTree->Branch("IDEEndTime", &IDEEndTime);
285  fDAQSimTree->Branch("IDEEnergy", &IDEEnergy);
286  fDAQSimTree->Branch("IDEElectrons", &IDEElectrons);
287  fDAQSimTree->Branch("IDEParticle", &IDEParticle);
288 
289  // --- Our Histograms...
290  hAdjHits_Marl = tfs->make<TH1I>("hAdjHits_Marl", "Number of adjacent collection plane hits for MARLEY; Number of adjacent collection plane hits; Number of events" , 21, -0.5, 20.5 );
291  hAdjHits_APA = tfs->make<TH1I>("hAdjHits_APA" , "Number of adjacent collection plane hits for APAs; Number of adjacent collection plane hits; Number of events" , 21, -0.5, 20.5 );
292  hAdjHits_CPA = tfs->make<TH1I>("hAdjHits_CPA" , "Number of adjacent collection plane hits for CPAs; Number of adjacent collection plane hits; Number of events" , 21, -0.5, 20.5 );
293  hAdjHits_Ar39 = tfs->make<TH1I>("hAdjHits_Ar39", "Number of adjacent collection plane hits for Argon39; Number of adjacent collection plane hits; Number of events" , 21, -0.5, 20.5 );
294  hAdjHits_Ar42 = tfs->make<TH1I>("hAdjHits_Ar42", "Number of adjacent collection plane hits for Argon42; Number of adjacent collection plane hits; Number of events" , 21, -0.5, 20.5 );
295  hAdjHits_Neut = tfs->make<TH1I>("hAdjHits_Neut", "Number of adjacent collection plane hits for Neutrons; Number of adjacent collection plane hits; Number of events", 21, -0.5, 20.5 );
296  hAdjHits_Kryp = tfs->make<TH1I>("hAdjHits_Kryp", "Number of adjacent collection plane hits for Krypton; Number of adjacent collection plane hits; Number of events" , 21, -0.5, 20.5 );
297  hAdjHits_Plon = tfs->make<TH1I>("hAdjHits_Plon", "Number of adjacent collection plane hits for Polonium; Number of adjacent collection plane hits; Number of events", 21, -0.5, 20.5 );
298  hAdjHits_Rdon = tfs->make<TH1I>("hAdjHits_Rdon", "Number of adjacent collection plane hits for Radon; Number of adjacent collection plane hits; Number of events" , 21, -0.5, 20.5 );
299  hAdjHits_Oth = tfs->make<TH1I>("hAdjHits_Oth" , "Number of adjacent collection plane hits for Others; Number of adjacent collection plane hits; Number of events" , 21, -0.5, 20.5 );
300 } // BeginJob
301 
302 //......................................................
304 {
305  auto allParticles = evt.getValidHandle<std::vector<simb::MCParticle> >(fGEANTLabel);
306  art::FindMany<simb::MCTruth> assn(allParticles,evt,fGEANTLabel);
307  std::map<int, const simb::MCTruth*> idToTruth;
308  for(size_t i=0; i<allParticles->size(); ++i){
309  const simb::MCParticle& particle=allParticles->at(i);
310  const std::vector<const simb::MCTruth*> truths=assn.at(i);
311  if(truths.size()==1){
312  idToTruth[particle.TrackId()]=truths[0];
313  }
314  else{
315  mf::LogDebug("DAQSimAna") << "Particle " << particle.TrackId() << " has " << truths.size() << " truths";
316  idToTruth[particle.TrackId()]=nullptr;
317  }
318  }
319 
320  // Get the SimChannels so we can see where the actual energy depositions were
321  auto& simchs=*evt.getValidHandle<std::vector<sim::SimChannel>>("largeant");
322 
323  for(auto&& simch: simchs){
324  // We only care about collection channels
325  if(geo->SignalType(simch.Channel())!=geo::kCollection) continue;
326 
327  // The IDEs record energy depositions at every tick, but
328  // mostly we have several depositions at contiguous times. So
329  // we're going to save just one output IDE for each contiguous
330  // block of hits on a channel. Each item in vector is a list
331  // of (TDC, IDE*) for contiguous-in-time IDEs
332  std::vector<std::vector<std::pair<int, const sim::IDE*> > > contigIDEs;
333  int prevTDC=0;
334  for (const auto& TDCinfo: simch.TDCIDEMap()) {
335  // Do we need to start a new group of IDEs? Yes if this is
336  // the first IDE in this channel. Yes if this IDE is not
337  // contiguous with the previous one
338  if(contigIDEs.empty() || TDCinfo.first-prevTDC>5){
339  contigIDEs.push_back(std::vector<std::pair<int, const sim::IDE*> >());
340  }
341  std::vector<std::pair<int, const sim::IDE*> >& currentIDEs=contigIDEs.back();
342 
343  // Add all the current tick's IDEs to the list
344  for (const sim::IDE& ide: TDCinfo.second) {
345  currentIDEs.push_back(std::make_pair(TDCinfo.first, &ide));
346  }
347  prevTDC=TDCinfo.first;
348  }
349 
350  for(auto const& contigs : contigIDEs){
351  float energy=0;
352  float electrons=0;
353  int startTime=99999;
354  int endTime=0;
355  std::map<PType, float> ptypeToEnergy;
356  for(auto const& timeide : contigs){
357  const int tdc=timeide.first;
358  startTime=std::min(tdc, startTime);
359  endTime=std::max(tdc, endTime);
360  const sim::IDE& ide=*timeide.second;
361  const float thisEnergy=ide.energy;
362  const PType thisPType=WhichParType(std::abs(ide.trackID));
363  energy+=thisEnergy;
364  electrons+=ide.numElectrons;
365  ptypeToEnergy[thisPType]+=thisEnergy;
366  }
367  float bestEnergy=0;
368  PType bestPType=kUnknown;
369  for(auto const& it : ptypeToEnergy){
370  if(it.second>bestEnergy){
371  bestEnergy=it.second;
372  bestPType=it.first;
373  }
374  }
375  // Ignore anything past the end of the readout window
376  if(startTime<4492){
377  IDEChannel.push_back(simch.Channel());
378  IDEStartTime.push_back(startTime);
379  IDEEndTime.push_back(endTime);
380  IDEEnergy.push_back(energy);
381  IDEElectrons.push_back(electrons);
382  IDEParticle.push_back(bestPType);
383  }
384  } // loop over our compressed IDEs
385  } // loop over SimChannels
386 }
387 
388 //......................................................
390 {
391 
392  // --- We want to reset all of our TTree variables...
393  ResetVariables();
394 
395  // --- Set all of my general event information...
396  Run = evt.run();
397  SubRun = evt.subRun();
398  Event = evt.event();
399 
400  // --- Lift out the TPC raw digits:
401  //auto rawdigits = evt.getValidHandle<std::vector<raw::RawDigit> >(fRawDigitLabel);
402 
403  // --- Lift out the reco hits:
404  auto reco_hits = evt.getValidHandle<std::vector<recob::Hit> >(fHitLabel);
405 
406  // --- Lift out the MARLEY particles.
407  auto MarlTrue = evt.getValidHandle<std::vector<simb::MCTruth> >(fMARLLabel);
408  std::cout << "MarlTrue.size()=" << MarlTrue->size() << std::endl;
409  art::FindManyP<simb::MCParticle> MarlAssn(MarlTrue,evt,fGEANTLabel);
410  FillMyMaps( MarlParts, MarlAssn, MarlTrue, &trkIDToMarleyIndex );
411  TotGen_Marl = MarlParts.size();
412  mf::LogDebug("DAQSimAna") << "--- The size of MarleyParts is " << MarlParts.size();
413 
414  // --- Lift out the APA particles.
415  auto APATrue = evt.getValidHandle<std::vector<simb::MCTruth> >(fAPALabel);
416  art::FindManyP<simb::MCParticle> APAAssn(APATrue,evt,fGEANTLabel);
417  FillMyMaps( APAParts, APAAssn, APATrue );
418  TotGen_APA = APAParts.size();
419  mf::LogDebug("DAQSimAna") << "--- The size of APAParts is " << APAParts.size();
420 
421  // --- Lift out the CPA particles.
422  auto CPATrue = evt.getValidHandle<std::vector<simb::MCTruth> >(fCPALabel);
423  art::FindManyP<simb::MCParticle> CPAAssn(CPATrue,evt,fGEANTLabel);
424  FillMyMaps( CPAParts, CPAAssn, CPATrue );
425  TotGen_CPA = CPAParts.size();
426  mf::LogDebug("DAQSimAna") << "--- The size of CPAParts is " << CPAParts.size();
427 
428  // --- Lift out the Ar39 particles.
429  auto Ar39True = evt.getValidHandle<std::vector<simb::MCTruth> >(fAr39Label);
430  art::FindManyP<simb::MCParticle> Ar39Assn(Ar39True,evt,fGEANTLabel);
431  FillMyMaps( Ar39Parts, Ar39Assn, Ar39True );
432  TotGen_Ar39 = Ar39Parts.size();
433  mf::LogDebug("DAQSimAna") << "--- The size of Ar39Parts is " << Ar39Parts.size();
434 
435  // --- Lift out the Ar42 particles.
436  auto Ar42True = evt.getValidHandle<std::vector<simb::MCTruth> >(fAr42Label);
437  art::FindManyP<simb::MCParticle> Ar42Assn(Ar42True,evt,fGEANTLabel);
438  FillMyMaps( Ar42Parts, Ar42Assn, Ar42True );
439  TotGen_Ar42 = Ar42Parts.size();
440  mf::LogDebug("DAQSimAna") << "--- The size of Ar42Parts is " << Ar42Parts.size();
441 
442  // --- Lift out the Neut particles.
443  auto NeutTrue = evt.getValidHandle<std::vector<simb::MCTruth> >(fNeutLabel);
444  art::FindManyP<simb::MCParticle> NeutAssn(NeutTrue,evt,fGEANTLabel);
445  FillMyMaps( NeutParts, NeutAssn, NeutTrue );
446  TotGen_Neut = NeutParts.size();
447  mf::LogDebug("DAQSimAna") << "--- The size of NeutParts is " << NeutParts.size();
448 
449  // --- Lift out the Kryp particles.
450  auto KrypTrue = evt.getValidHandle<std::vector<simb::MCTruth> >(fKrypLabel);
451  art::FindManyP<simb::MCParticle> KrypAssn(KrypTrue,evt,fGEANTLabel);
452  FillMyMaps( KrypParts, KrypAssn, KrypTrue );
453  TotGen_Kryp = KrypParts.size();
454  mf::LogDebug("DAQSimAna") << "--- The size of KrypParts is " << KrypParts.size();
455 
456  // --- Lift out the Plon particles.
457  auto PlonTrue = evt.getValidHandle<std::vector<simb::MCTruth> >(fPlonLabel);
458  art::FindManyP<simb::MCParticle> PlonAssn(PlonTrue,evt,fGEANTLabel);
459  FillMyMaps( PlonParts, PlonAssn, PlonTrue );
460  TotGen_Plon = PlonParts.size();
461  mf::LogDebug("DAQSimAna") << "--- The size of PlonParts is " << PlonParts.size();
462 
463  // --- Lift out the Rdon particles.
464  auto RdonTrue = evt.getValidHandle<std::vector<simb::MCTruth> >(fRdonLabel);
465  art::FindManyP<simb::MCParticle> RdonAssn(RdonTrue,evt,fGEANTLabel);
466  FillMyMaps( RdonParts, RdonAssn, RdonTrue );
467  TotGen_Rdon = RdonParts.size();
468  mf::LogDebug("DAQSimAna") << "--- The size of RdonParts is " << RdonParts.size();
469 
470  std::map<PType, std::map< int, simb::MCParticle >&> PTypeToMap{
471  {kMarl, MarlParts},
472  {kAPA, APAParts},
473  {kCPA, CPAParts},
474  {kAr39, Ar39Parts},
475  {kAr42, Ar42Parts},
476  {kNeutron, NeutParts},
477  {kKryp, KrypParts},
478  {kPlon, PlonParts},
479  {kRdon, RdonParts}
480  };
481 
482  for(auto const& it : PTypeToMap){
483  const PType p=it.first;
484  if(p>kNPTypes){
485  std::cout << "PType is " << (int)p << std::endl;
486  }
487  auto const& m=it.second;
488  for(auto const& it2 : m){
489  trkIDToPType.insert(std::make_pair(it2.first, p));
490  }
491  }
492 
493  // --- Finally, get a list of all of my particles in one chunk.
494  const sim::ParticleList& PartList = pi_serv->ParticleList();
495  mf::LogDebug("DAQSimAna") << "There are a total of " << PartList.size() << " MCParticles in the event ";
496 
497  // Now that we've filled all the truth maps, we can fill a list of the true energy deposititions (IDEs)
498  SaveIDEs(evt);
499 
500  std::vector< recob::Hit > ColHits_Marl;
501  std::vector< recob::Hit > ColHits_CPA;
502  std::vector< recob::Hit > ColHits_APA;
503  std::vector< recob::Hit > ColHits_Ar39;
504  std::vector< recob::Hit > ColHits_Ar42;
505  std::vector< recob::Hit > ColHits_Neut;
506  std::vector< recob::Hit > ColHits_Kryp;
507  std::vector< recob::Hit > ColHits_Plon;
508  std::vector< recob::Hit > ColHits_Rdon;
509  std::vector< recob::Hit > ColHits_Oth;
510 
511  //*
512  // --- Loop over the reconstructed hits to determine the "size" of each hit
513  NTotHits = reco_hits->size();
514 
515  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
516 
517  for(int hit = 0; hit < NTotHits; ++hit) {
518  // --- Let access this particular hit.
519  recob::Hit const& ThisHit = reco_hits->at(hit);
520 
521  // --- Lets figure out which particle contributed the most charge to this hit...
522  int MainTrID = -1;
523  double TopEFrac = -DBL_MAX;
524 
525  // HitToTrackIDEs opens a specific window around the hit. I want a
526  // wider one, because the filtering can delay the hit. So this bit
527  // is a copy of HitToTrackIDEs from the backtracker, with some
528  // modification
529  const double start = ThisHit.PeakTime()-20;
530  const double end = ThisHit.PeakTime()+ThisHit.RMS()+20;
531  std::vector<sim::TrackIDE> ThisHitIDE = bt_serv->ChannelToTrackIDEs(clockData, ThisHit.Channel(), start, end);
532  // The old method
533  // std::vector< sim::TrackIDE > ThisHitIDE = bt_serv->HitToTrackIDEs(clockData, ThisHit );
534  for (size_t ideL=0; ideL < ThisHitIDE.size(); ++ideL) {
535  if ( ThisHitIDE[ideL].energyFrac > TopEFrac ) {
536  TopEFrac = ThisHitIDE[ideL].energyFrac;
537  MainTrID = ThisHitIDE[ideL].trackID;
538  }
539  }
540  // --- Lets figure out how that particle was generated...
541  PType ThisPType = WhichParType( MainTrID );
542  int thisMarleyIndex=-1;
543  if(ThisPType==kMarl){
544  auto const it=trkIDToMarleyIndex.find(MainTrID);
545  if(it==trkIDToMarleyIndex.end()){
546  std::cout << "Track ID " << MainTrID << " is not in Marley index map" << std::endl;
547  }
548  else{
549  thisMarleyIndex=it->second;
550  }
551  }
552  // --- Write out some information about this hit....
553  // std::cout << "Looking at hit on channel " << ThisHit.Channel() << " corresponding to TPC " << ThisHit.WireID().TPC << ", wire " << ThisHit.WireID().Wire << ", plane " << ThisHit.WireID().Plane << ".\n"
554  // << "\tIt was at time " << ThisHit.PeakTime() << ", with amplitude " << ThisHit.PeakAmplitude() << ", it was caused by " << ThisHitIDE.size() << " particles, the main one being"
555  // << " TrackID " << MainTrID << " which was generated by " << ThisPType
556  // << std::endl;
557  //*/
558  // --- Check which view this hit is on...
559  if(ThisHit.View() == geo::kU || ThisHit.View() == geo::kV) {
560  ++NIndHits;
561  } else { // If not induction then must be collection.
562  ++NColHits;
563  }
564 
565  // --- Now fill in all of the hit level variables.
566  HitView.push_back(ThisHit.View());
567  HitSize.push_back(ThisHit.EndTick() - ThisHit.StartTick());
568  HitTPC .push_back(ThisHit.WireID().TPC);
569  HitChan.push_back(ThisHit.Channel());
570  HitTime.push_back(ThisHit.PeakTime());
571  HitRMS .push_back(ThisHit.RMS());
572  HitSADC.push_back(ThisHit.SummedADC());
573  HitInt .push_back(ThisHit.Integral());
574  HitPeak.push_back(ThisHit.PeakAmplitude());
575  GenType.push_back(ThisPType);
576  MarleyIndex.push_back(thisMarleyIndex);
577 
578  // --- I want to fill a vector of coll plane hits, for each of the different kinds of generator.
579  if (ThisHit.View() == 2) {
580  if (ThisPType == kUnknown) ColHits_Oth .push_back( ThisHit );
581  else if (ThisPType == kMarl) ColHits_Marl.push_back( ThisHit );
582  else if (ThisPType == kAPA) ColHits_APA .push_back( ThisHit );
583  else if (ThisPType == kCPA) ColHits_CPA .push_back( ThisHit );
584  else if (ThisPType == kAr39) ColHits_Ar39.push_back( ThisHit );
585  else if (ThisPType == kAr42) ColHits_Ar42.push_back( ThisHit );
586  else if (ThisPType == kNeutron) ColHits_Neut.push_back( ThisHit );
587  else if (ThisPType == kKryp) ColHits_Kryp.push_back( ThisHit );
588  else if (ThisPType == kPlon) ColHits_Plon.push_back( ThisHit );
589  else if (ThisPType == kRdon) ColHits_Rdon.push_back( ThisHit );
590  }
591  } // Loop over reco_hits.
592 
593  // ---- Write out the Marley hits....
594  mf::LogDebug("DAQSimAna") << "\n\nAfter all of that I have a total of " << ColHits_Marl.size() << " MARLEY col plane hits.";
595  for (size_t hh=0; hh<ColHits_Marl.size(); ++hh) {
596  mf::LogDebug("DAQSimAna") << "\tHit " << hh << " was on chan " << ColHits_Marl[hh].Channel() << " at " << ColHits_Marl[hh].PeakTime();
597  }
598  if(fDoCalcAdjHits){
599  // --- Now calculate all of the hits...
600  CalcAdjHits( ColHits_Marl, hAdjHits_Marl, false );
601  mf::LogDebug("DAQSimAna") << "\nAnd now for APA hits...";
602  CalcAdjHits( ColHits_APA , hAdjHits_APA , false );
603  mf::LogDebug("DAQSimAna") << "\nAnd now for CPA hits...";
604  CalcAdjHits( ColHits_CPA , hAdjHits_CPA , false );
605  mf::LogDebug("DAQSimAna") << "\nAnd now for Ar39 hits...";
606  CalcAdjHits( ColHits_Ar39, hAdjHits_Ar39, false );
607  mf::LogDebug("DAQSimAna") << "\nAnd now for Ar42 hits...";
608  CalcAdjHits( ColHits_Ar42, hAdjHits_Ar42, false );
609  mf::LogDebug("DAQSimAna") << "\nAnd now for Neuton hits...";
610  CalcAdjHits( ColHits_Neut, hAdjHits_Neut, false );
611  mf::LogDebug("DAQSimAna") << "\nAnd now for Krypton hits...";
612  CalcAdjHits( ColHits_Kryp, hAdjHits_Kryp, false );
613  mf::LogDebug("DAQSimAna") << "\nAnd now for Polonium hits...";
614  CalcAdjHits( ColHits_Plon, hAdjHits_Plon, false );
615  mf::LogDebug("DAQSimAna") << "\nAnd now for Radon hits...";
616  CalcAdjHits( ColHits_Rdon, hAdjHits_Rdon, false );
617  mf::LogDebug("DAQSimAna") << "\nAnd now for Other hits...";
618  CalcAdjHits( ColHits_Oth , hAdjHits_Oth , false );
619  }
620 
621  fDAQSimTree -> Fill();
622 
623 } // Analyze DAQSimAna.
624 
625 
626 //......................................................
627 void DAQSimAna::FillMyMaps( std::map< int, simb::MCParticle> &MyMap, art::FindManyP<simb::MCParticle> Assn, art::ValidHandle< std::vector<simb::MCTruth> > Hand,
628  std::map<int, int>* indexMap)
629 {
630  for ( size_t L1=0; L1 < Hand->size(); ++L1 ) {
631  for ( size_t L2=0; L2 < Assn.at(L1).size(); ++L2 ) {
632  const simb::MCParticle ThisPar = (*Assn.at(L1).at(L2));
633  MyMap[ThisPar.TrackId()] = ThisPar;
634  if(indexMap) indexMap->insert({ThisPar.TrackId(), L1});
635  }
636  }
637  return;
638 }
639 
640 //......................................................
642 {
643  PType ThisPType = kUnknown;
644  auto const& it=trkIDToPType.find(TrID);
645  if(it!=trkIDToPType.end()){
646  ThisPType=it->second;
647  }
648  if(ThisPType>kNPTypes){
649  std::cout << "In WhichParType, ptype is " << (int)ThisPType << std::endl;
650  }
651  return ThisPType;
652 }
653 
654 //......................................................
656 {
657  const std::string& label=truthHand.provenance()->moduleLabel();
658  if(label==fMARLLabel){ return kMarl; }
659  if(label==fAPALabel) { return kAPA; }
660  if(label==fCPALabel) { return kCPA; }
661  if(label==fAr39Label){ return kAr39; }
662  if(label==fAr42Label){ return kAr42; }
663  if(label==fNeutLabel){ return kNeutron; }
664  if(label==fKrypLabel){ return kKryp; }
665  if(label==fPlonLabel){ return kPlon; }
666  if(label==fRdonLabel){ return kRdon; }
667  return kUnknown;
668 }
669 
670 //......................................................
671 bool DAQSimAna::InMyMap( int TrID, std::map< int, simb::MCParticle> ParMap )
672 {
674  ParIt = ParMap.find( TrID );
675  if ( ParIt != ParMap.end() ) {
676  return true;
677  } else
678  return false;
679 }
680 
681 //......................................................
682 void DAQSimAna::CalcAdjHits( std::vector< recob::Hit > MyVec, TH1I* MyHist, bool HeavDebug ) {
683  const double TimeRange = 20;
684  const int ChanRange = 2;
685  unsigned int FilledHits = 0;
686  unsigned int NumOriHits = MyVec.size();
687  while( NumOriHits != FilledHits ) {
688  if (HeavDebug) mf::LogDebug("DAQSimAna") << "\nStart of my while loop";
689  std::vector< recob::Hit > AdjHitVec;
690  AdjHitVec.push_back ( MyVec[0] );
691  MyVec.erase( MyVec.begin()+0 );
692  int LastSize = 0;
693  int NewSize = AdjHitVec.size();
694  while ( LastSize != NewSize ) {
695  std::vector<int> AddNow;
696  for (size_t aL=0; aL < AdjHitVec.size(); ++aL) {
697  for (size_t nL=0; nL < MyVec.size(); ++nL) {
698  if (HeavDebug) {
699  mf::LogDebug("DAQSimAna") << "\t\tLooping though AdjVec " << aL << " and MyVec " << nL
700  << " AdjHitVec - " << AdjHitVec[aL].Channel() << " & " << AdjHitVec[aL].PeakTime()
701  << " MVec - " << MyVec[nL].Channel() << " & " << MyVec[nL].PeakTime()
702  << " Channel " << abs( (int)AdjHitVec[aL].Channel() - (int)MyVec[nL].Channel() ) << " bool " << (bool)(abs( (int)AdjHitVec[aL].Channel() - (int)MyVec[nL].Channel() ) <= ChanRange)
703  << " Time " << abs( AdjHitVec[aL].PeakTime() - MyVec[nL].PeakTime() ) << " bool " << (bool)(abs( (double)AdjHitVec[aL].PeakTime() - (double)MyVec[nL].PeakTime() ) <= TimeRange);
704 
705  }
706  if ( abs( (int)AdjHitVec[aL].Channel() - (int)MyVec[nL].Channel() ) <= ChanRange &&
707  abs( (double)AdjHitVec[aL].PeakTime() - (double)MyVec[nL].PeakTime() ) <= TimeRange ) {
708  if (HeavDebug) mf::LogDebug("DAQSimAna") << "\t\t\tFound a new thing!!!";
709  // --- Check that this element isn't already in AddNow.
710  bool AlreadyPres = false;
711  for (size_t zz=0; zz<AddNow.size(); ++zz) {
712  if (AddNow[zz] == (int)nL) AlreadyPres = true;
713  }
714  if (!AlreadyPres)
715  AddNow.push_back( nL );
716  } // If this hit is within the window around one of my other hits.
717  } // Loop through my vector of colleciton plane hits.
718  } // Loop through AdjHitVec
719  // --- Now loop through AddNow and remove from Marley whilst adding to AdjHitVec
720  for (size_t aa=0; aa<AddNow.size(); ++aa) {
721  if (HeavDebug) {
722  mf::LogDebug("DAQSimAna") << "\tRemoving element " << AddNow.size()-1-aa << " from MyVec ===> "
723  << MyVec[ AddNow[AddNow.size()-1-aa] ].Channel() << " & " << MyVec[ AddNow[AddNow.size()-1-aa] ].PeakTime();
724 
725  }
726  AdjHitVec.push_back ( MyVec[ AddNow[AddNow.size()-1-aa] ] );
727  MyVec.erase( MyVec.begin() + AddNow[AddNow.size()-1-aa] );
728  }
729  LastSize = NewSize;
730  NewSize = AdjHitVec.size();
731  if (HeavDebug) {
732  mf::LogDebug("DAQSimAna") << "\t---After that pass, AddNow was size " << AddNow.size() << " ==> LastSize is " << LastSize << ", and NewSize is " << NewSize
733  << "\nLets see what is in AdjHitVec....";
734  for (size_t aL=0; aL < AdjHitVec.size(); ++aL) {
735  mf::LogDebug("DAQSimAna") << "\tElement " << aL << " is ===> " << AdjHitVec[aL].Channel() << " & " << AdjHitVec[aL].PeakTime();
736  }
737  }
738 
739  } // while ( LastSize != NewSize )
740  int NumAdjColHits = AdjHitVec.size();
741  if (HeavDebug) mf::LogDebug("DAQSimAna") << "After that loop, I had " << NumAdjColHits << " adjacent collection plane hits.";
742  MyHist -> Fill( NumAdjColHits );
743  FilledHits += NumAdjColHits;
744  }
745  return;
746 }
747 
748 //......................................................
TrackID_t trackID
Geant4 supplied track ID.
Definition: SimChannel.h:112
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
TH1I * hAdjHits_Ar39
std::vector< int > GenType
The generator which generated the particle responsible for the hit.
intermediate_table::iterator iterator
TTree * fDAQSimTree
EventNumber_t event() const
Definition: DataViewImpl.cc:85
art::ServiceHandle< cheat::BackTrackerService > bt_serv
void CalcAdjHits(std::vector< recob::Hit > MyVec, TH1I *MyHist, bool HeavDebug="false")
std::string fPlonLabel
std::vector< int > HitChan
The channel which the hit occurs on.
std::map< int, int > trkIDToMarleyIndex
std::string string
Definition: nybbler.cc:12
std::string fRawDigitLabel
Planes which measure V.
Definition: geo_types.h:130
std::vector< int > IDEEndTime
geo::WireID WireID() const
Definition: Hit.h:233
float RMS() const
RMS of the hit shape, in tick units.
Definition: Hit.h:220
std::map< int, PType > trkIDToPType
std::string fRdonLabel
TH1I * hAdjHits_APA
std::vector< int > IDEStartTime
struct vector vector
std::map< int, simb::MCParticle > PlonParts
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:232
std::string fHitLabel
std::vector< int > IDEParticle
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
TH1I * hAdjHits_Neut
DAQSimAna(fhicl::ParameterSet const &p)
std::map< int, simb::MCParticle > CPAParts
void FillMyMaps(std::map< int, simb::MCParticle > &MyMap, art::FindManyP< simb::MCParticle > Assn, art::ValidHandle< std::vector< simb::MCTruth > > Hand, std::map< int, int > *indexMap=nullptr)
std::string fNeutLabel
art framework interface to geometry description
std::vector< int > IDEChannel
TH1I * hAdjHits_CPA
int TrackId() const
Definition: MCParticle.h:210
TH1I * hAdjHits_Rdon
float PeakAmplitude() const
The estimated amplitude of the hit at its peak, in ADC units.
Definition: Hit.h:221
std::vector< int > HitSize
Time width (ticks) Start - End time.
void beginJob() override
std::map< int, simb::MCParticle > NeutParts
std::map< int, simb::MCParticle > KrypParts
TH1I * hAdjHits_Ar42
T abs(T value)
Planes which measure U.
Definition: geo_types.h:129
std::map< int, simb::MCParticle > Ar42Parts
std::string fAr39Label
std::string fMARLLabel
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
std::string fCPALabel
DAQSimAna & operator=(DAQSimAna const &)=delete
TH1I * hAdjHits_Oth
Ionization at a point of the TPC sensitive volume.
Definition: SimChannel.h:84
void ResetVariables()
T get(std::string const &key) const
Definition: ParameterSet.h:271
float energy
energy deposited by ionization by this track ID and time [MeV]
Definition: SimChannel.h:114
std::vector< float > IDEEnergy
TH1I * hAdjHits_Kryp
Provenance const * provenance() const
Definition: Handle.h:344
std::map< int, simb::MCParticle > APAParts
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
p
Definition: test.py:223
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
RunNumber_t run() const
Definition: DataViewImpl.cc:71
static int max(int a, int b)
std::string fAPALabel
TH1I * hAdjHits_Plon
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
Definition: Hit.h:216
std::vector< int > MarleyIndex
Which SN in the list of Marley interactions this hit is from (-1 if not from SN)
bool InMyMap(int TrID, std::map< int, simb::MCParticle > ParMap)
Detector simulation of raw signals on wires.
std::string fGEANTLabel
const sim::ParticleList & ParticleList() const
void SaveIDEs(art::Event const &evt)
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
Definition: Hit.h:217
std::map< int, simb::MCParticle > MarlParts
std::map< int, simb::MCParticle > Ar39Parts
std::vector< float > HitPeak
The peak ADC value of the hit.
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
Declaration of signal hit object.
std::vector< float > HitTime
The time of the hit (ticks)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
art::ServiceHandle< cheat::ParticleInventoryService > pi_serv
std::vector< float > HitInt
The ADC integral of the hit.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
std::string fKrypLabel
float SummedADC() const
The sum of calibrated ADC counts of the hit (0. by default)
Definition: Hit.h:223
std::map< int, simb::MCParticle > RdonParts
TH1I * hAdjHits_Marl
std::vector< float > HitRMS
The RMS of the hit.
void reconfigure(fhicl::ParameterSet const &p)
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
Tools and modules for checking out the basics of the Monte Carlo.
TCEvent evt
Definition: DataStructs.cxx:7
std::vector< float > HitSADC
The summed ADC of the hit.
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
LArSoft geometry interface.
Definition: ChannelGeo.h:16
int bool
Definition: qglobal.h:345
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:230
art::ServiceHandle< geo::Geometry > geo
std::vector< float > IDEElectrons
PType WhichParType(int TrID)
std::string fAr42Label
std::vector< int > HitTPC
The TPC which the hit occurs in.
std::vector< sim::TrackIDE > ChannelToTrackIDEs(detinfo::DetectorClocksData const &clockData, raw::ChannelID_t channel, const double hit_start_time, const double hit_end_time) const
std::vector< int > HitView
View i.e Coll, U, V.
float numElectrons
number of electrons at the readout for this track ID and time
Definition: SimChannel.h:113
QTextStream & endl(QTextStream &s)
Signal from collection planes.
Definition: geo_types.h:146
void analyze(art::Event const &evt) override