truepionXsection_module.cc
Go to the documentation of this file.
5 #include "art_root_io/TFileService.h"
6 #include "art_root_io/TFileDirectory.h"
9 #include "canvas/Persistency/Common/FindManyP.h"
12 #include "fhiclcpp/ParameterSet.h"
13 
15 //#include "larcore/Geometry/CryostatGeo.h"
16 //#include "larcore/Geometry/TPCGeo.h"
17 //#include "larcore/Geometry/PlaneGeo.h"
18 //#include "larcore/Geometry/WireGeo.h"
19 
21 //#include "larcoreobj/SimpleTypeAndConstants/RawTypes.h"
30 #include "lardataobj/RawData/raw.h"
53 #include "dune/DuneObj/ProtoDUNEBeamEvent.h"
55 
60 #include "dune/Protodune/singlephase/DataUtils/ProtoDUNEDataUtils.h"
61 
62 #include "TFile.h"
63 #include "TTree.h"
64 #include "TDirectory.h"
65 #include "TH1.h"
66 #include "TH2.h"
67 #include "TF1.h"
68 #include "TProfile.h"
69 #include "TROOT.h"
70 #include "TStyle.h"
71 #include "TMath.h"
72 #include "TGraphErrors.h"
73 #include "TMinuit.h"
74 #include "TString.h"
75 #include "TTimeStamp.h"
76 #include "TVectorD.h"
77 #include "TCanvas.h"
78 #include "TFrame.h"
79 #include "TLine.h"
80 #include "TAxis.h"
81 #include "TTimeStamp.h"
82 
83 #include "TComplex.h"
84 #include <vector>
85 #include <fstream>
86 #include "TPaveStats.h"
87 #include <iostream>
88 #include <string>
89 #include "math.h"
90 #include "stdio.h"
91 #include <iterator>
92 #include <map>
93 
94 namespace protoana{
95 
97  public:
98 
99  explicit truepionXsection(fhicl::ParameterSet const& pset);
100  virtual ~truepionXsection();
101 
102  void beginJob();
103  void endJob();
104  void beginRun(const art::Run& run);
105  void analyze(const art::Event& evt);
106  void reset();
107  // double distance(double, double, double, double, double, double );
108  private:
109  ///below are some addition to be able to use protodune utitilites
110  // Helper utility functions
111  // ProtoDUNEDataUtils dataUtil;
112  // ProtoDUNEPFParticleUtils pfpUtil;
113  // ProtoDUNETrackUtils trackUtil;
114 
115 
117 
118  //fcl parameters
125  ///////////////////////helper utility ends/////////
126 
127 
128  TTree* fEventTree;
129  Int_t run;
130  Int_t subrun;
131  Int_t event;
132  // TH1D* h_DE ;
133  // TH1D* h_DX ;
134  // TH1D* h_DEDX ;
135  TH1D* h_DEUniform ;
136  TH1D* h_DXUniform ;
138  TH1D* h_DeltaE ;
139  // TH1D* h_SimIDEDist ;
145  TH1D *hIncidentKE;
149  TH1D *hKEAtTPCFF;
150  TH1D *hInitialKE;
151  TH1D *hInitialPz;
152  TH2D *hXZ;
153  TH2D *hYZ;
154  TH2D *hXZPre;
155  TH2D *hYZPre;
156  TH2D *hdEVsdX;
157  TH2D *hdEVsKE;
158  TH1D *processtot;//number of processes for each mc particle
159  TH1D *processEl;
160  TH1D *processInel;
161  //bool debug = false;
162  double trueVtxX ;
163  double trueVtxY ;
164  double trueVtxZ ;
165  double trueEndX ;
166  double trueEndY ;
167  double trueEndZ ;
168  double finalKE ;
169  std::vector<std::string> G4Process;
170 
171  double minX = -360.0;
172  double maxX = 360.0;
173  double minY =0.0;
174  double maxY = 600.0;
175  double minZ = 0.0; // G10 at z=1.2
176  double maxZ = 695.0;
177  int evtsPreTPC = 0;
179  int evtsPostTPC = 0;
180  int throughgoing = 0;
187  };
188 
189  //========================================================================
191  EDAnalyzer(pset),
192  ///new lines
193  //dataUtil(pset.get<fhicl::ParameterSet>("DataUtils")),
194  fBeamModuleLabel(pset.get< art::InputTag >("BeamModuleLabel")),
195  //fTrackerTag(pset.get<std::string>("TrackerTag")),
196  //fShowerTag(pset.get<std::string>("ShowerTag")),
197  //fPFParticleTag(pset.get<std::string>("PFParticleTag")),
198  fGeneratorTag(pset.get<std::string>("GeneratorTag")),
199  ///new lines end here
200 
201  fHitsModuleLabel (pset.get< std::string >("HitsModuleLabel","") ),
202  fTrackModuleLabel (pset.get< std::string >("TrackModuleLabel","") ),
203  fCalorimetryModuleLabel (pset.get< std::string >("CalorimetryModuleLabel","") ),
204  fSaveCaloInfo (pset.get< bool>("SaveCaloInfo",false)),
205  fSaveTrackInfo (pset.get< bool>("SaveTrackInfo",false))
206  {
207  if (fSaveTrackInfo == false) fSaveCaloInfo = false;
208  }
209 
210  //========================================================================
212  }
213  //========================================================================
214 
215  //========================================================================
216 
217  double distance(double x1, double y1, double z1, double x2, double y2, double z2)
218  {
219  double d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
220  return d;
221  }
222 
223 
224 
225 
227  std::cout<<"job begin..."<<std::endl;
229  fEventTree = tfs->make<TTree>("Event", "Event Tree from Reco");
230  fEventTree->Branch("event", &event,"event/I");
231  fEventTree->Branch("run", &run,"run/I");
232  fEventTree->Branch("subrun", &subrun,"surbrun/I");
233 
234  // h_DE = tfs->make<TH1D>("h_DE","h_DE; Energy Deposited [MeV]",200, 0,100);
235  // h_DX = tfs->make<TH1D>("h_DX","h_DX; Distance between points [cm]",400, 0,20);
236  // h_DEDX = tfs->make<TH1D>("h_DEDEX","h_DEDX; dE/dX [MeV/cm]",500, 0,50);
237  h_DEUniform = tfs->make<TH1D>("h_DEUniform","h_DE; Energy Deposited [MeV]",200, 0,100);
238  h_DXUniform = tfs->make<TH1D>("h_DXUniform","h_DX; Distance between points [cm]",400, 0,20);
239  h_DEDXUniform = tfs->make<TH1D>("h_DEDEXUniform","h_DEDX; dE/dX [MeV/cm]",500, 0,50);
240  h_DeltaE = tfs->make<TH1D>("h_DeltaE","h_DeltaE; dEDep - TrjDE [MeV/cm]",500, -1000,1000);
241  // h_SimIDEDist= tfs->make<TH1D>("h_SimIDEDist","h_SimIDEDist; h_SimIDEDist [cm]",1000, 0,10);
242 
243  h_UniformDistances = tfs->make<TH1D>("h_UniformDistances","h_UniformDistances; Distance between uniform points [cm]",500, 0,5);
244  hInitialPz = tfs->make<TH1D>("hInitialPz" , "Initial Pz [MeV/c]" , 42, -100, 2000);
245  hInitialKE = tfs->make<TH1D>("hInitialKE" , "Initial Kinetic Energy [MeV]" , 42, -100, 2000);
246  hKEAtTPCFF = tfs->make<TH1D>("hKEAtTPCFF" , "Kinetic Energy @ TPC FF [MeV]" , 42, -100, 2000);
247  hIncidentKE = tfs->make<TH1D>("hIncidentKE" , "Incident Kinetic Energy [MeV]" , 42, -100, 2000);
248 
249  processtot=tfs->make<TH1D>("processtot","Total number of interaction for each particle;number of interaction;number of entries",50,0,50);
250  processEl=tfs->make<TH1D>("processEl","Total number of Elastic interaction for each particle;number of interaction;number of entries",50,0,50);
251  processInel=tfs->make<TH1D>("processInel","Total number of InElastic interaction for each particle;number of interaction;number of entries",50,0,50);
252  hInteractingKE = tfs->make<TH1D>("hInteractingKE", "Interacting Kinetic Energy [MeV]", 42, -100, 2000);
253  hInteractingKEEl = tfs->make<TH1D>("hInteractingKEEl", "Elastic Interacting Kinetic Energy [MeV]", 42, -100, 2000);
254  hInteractingKEElDep = tfs->make<TH1D>("hInteractingKEElDep", "Dep Elastic Interacting Kinetic Energy [MeV]", 42, -100, 2000);
255  hInteractingKEInel = tfs->make<TH1D>("hInteractingKEInel", "Inelastic Interacting Kinetic Energy [MeV]", 42, -100, 2000);
256  hCrossSection = tfs->make<TH1D>("hCrossSection" , "Cross-Section [barn]" , 42, -100, 2000);
257  hCrossSectionEl = tfs->make<TH1D>("hCrossSectionEl" , "Elastic Cross-Section [barn]" , 42, -100, 2000);
258  hCrossSectionInel = tfs->make<TH1D>("hCrossSectionInel" , "Inelastic Cross-Section [barn]" , 42, -100, 2000);
259  hXZ = tfs->make<TH2D>("hXZ" , "hXZ" , 895, -200, 695 , 720, -360, 360);
260  hYZ = tfs->make<TH2D>("hYZ" , "hYZ" , 895, -200, 695 , 600, 0, 600);
261  hXZPre = tfs->make<TH2D>("hXZPre" , "hXZPre", 200, -100, 100 , 200, -100, 100);
262  hYZPre = tfs->make<TH2D>("hYZPre" , "hYZPre", 200, -100, 100 , 200, 300, 500);
263  hdEVsdX = tfs->make<TH2D>("hdEVsdX" , "hdEVsdX" , 504, -1, 50, 1100, -10, 100);
264  hdEVsKE = tfs->make<TH2D>("hdEVsKE" , "hdEVsKE" , 504, -1, 50, 220, -10, 1000);
265 
266  fEventTree->Branch("trueVtxX" ,&trueVtxX ,"trueVtxX/D");
267  fEventTree->Branch("trueVtxY" ,&trueVtxY ,"trueVtxY/D");
268  fEventTree->Branch("trueVtxZ" ,&trueVtxZ ,"trueVtxZ/D");
269  fEventTree->Branch("trueEndX" ,&trueEndX ,"trueEndX/D");
270  fEventTree->Branch("trueEndY" ,&trueEndY ,"trueEndY/D");
271  fEventTree->Branch("trueEndZ" ,&trueEndZ ,"trueEndZ/D");
272  fEventTree->Branch("finalKE" ,&finalKE ,"finalKE/D" );
273  fEventTree->Branch("G4Process",&G4Process);
274 
275 
276  }
277 
278 
279  //========================================================================
281  mf::LogInfo("truepionXsection")<<"begin run..."<<std::endl;
282  }
283  //========================================================================
284 
285  //========================================================================
286 
287  //========================================================================
288 
290  reset();
291  bool verbose=false;
292  run = evt.run();
293  subrun = evt.subRun();
294  event = evt.id().event();
297  const sim::ParticleList& plist=pi_serv->ParticleList();
298  // sim::ParticleList::const_iterator itPartp=plist.begin();
299  bool keepInteraction=false;
300 
301  //for(size_t iPart=0;(iPart<plist.size()) && (plist.begin()!=plist.end());++iPart){ //particle loop begins here
302  auto mcTruths = evt.getValidHandle<std::vector<simb::MCTruth>>(fGeneratorTag);
303  const simb::MCParticle* particle = truthUtil.GetGeantGoodParticle((*mcTruths)[0],evt);
304 
305  //const simb::MCParticle* particle=(itPartp++)->second;
306  if(particle!=0x0){
307  std::cout<<"particle pdg code is "<<particle->PdgCode()<<std::endl;
308  if(particle->PdgCode()==211 && particle->Process()=="primary"){
309  std::cout<<"found a pi+"<<std::endl;
311  simb::MCTrajectory truetraj=particle->Trajectory();
312  geo::View_t view = geom->View(2);
313  auto simIDE_prim=bt_serv->TrackIdToSimIDEs_Ps(particle->TrackId(),view);
314  std::map<double, sim::IDE> orderedSimIDE;
315  for (auto& ide : simIDE_prim) orderedSimIDE[ide->z]= *ide;
316  std::string interactionLabel="";
317  double mass=particle->Mass();
318  if(verbose) std::cout<<"mass "<<mass<<"\n";
319  //Store the kinetic energy and momentum on z at WC4. Just for cross check
320  auto inTPCPoint = truetraj.begin();
321  auto Momentum0 = inTPCPoint->second;
322  double KE0 = 1000*(TMath::Sqrt(Momentum0.X()*Momentum0.X() + Momentum0.Y()*Momentum0.Y() + Momentum0.Z()*Momentum0.Z() + mass*mass ) - mass); //I want this in MeV
323  hInitialKE->Fill(KE0);
324  hInitialPz->Fill(1000*Momentum0.Z());
325  if(verbose) std::cout<<KE0;
326 
327  //--------------------------------------------------------
328  // Identify the first trajectory point inside the TPC
329  // Loop From First TrajPoint --> First Point in TPC
330  // Stop when you get into the TPC
331  for ( auto t = truetraj.begin(); t!= std::prev(truetraj.end()); t++)
332  {
333  auto pos = t->first;
334  if (pos.Z() < minZ) continue;
335  else if (pos.X() < minX || pos.X() > maxX ) continue;
336  else if (pos.Y() < minY || pos.Y() > maxY ) continue;
337  else {
338  inTPCPoint = t;
339  break;
340  }
341  }// End search for first point in TPC
342  evtsPreTPC++;
343  hXZPre->Fill((inTPCPoint->first).Z(), (inTPCPoint->first).X());
344  hYZPre->Fill((inTPCPoint->first).Z(), (inTPCPoint->first).Y());
345  if (inTPCPoint !=truetraj.begin()){
346  evtsPostTPC++;
347  hXZ ->Fill((inTPCPoint->first).Z(), (inTPCPoint->first).X());
348  hYZ ->Fill((inTPCPoint->first).Z(), (inTPCPoint->first).Y());
349 
350  // Identify the last interesting trajectory point in TPC
351  auto finTPCPoint = std::prev(truetraj.end());
352  // The last point is a bit more complicated:
353  // if there's no interaction, then it is simply the last point in the TPC
354  // if there's one or more interaction points, it's the first interaction point deemed interesting (no coulomb)
355  // Take the interaction Map... check if there's something there
356  auto thisTracjectoryProcessMap = truetraj.TrajectoryProcesses();
357 
358  int el=0;
359  int inel=0;
360  int totint=0;
361  if (thisTracjectoryProcessMap.size())
362  {
363  for(auto const& couple: thisTracjectoryProcessMap)
364  {
365  totint++;
366  // I'm not interested in the CoulombScattering, discard this case
367  if(!verbose) std::cout<<(truetraj.KeyToProcess(couple.second))<<" Position "<<((truetraj.at(couple.first)).first).Z()<<" Momentum "<<((truetraj.at(couple.first)).second).Z()<<std::endl;
368  if ((truetraj.KeyToProcess(couple.second)).find("CoulombScat")!= std::string::npos) continue;
369 
370  // Let's check if the interaction is in the the TPC
371  auto interactionPos4D = (truetraj.at(couple.first)).first ;
372  if (interactionPos4D.Z() < minZ || interactionPos4D.Z() > maxZ ) continue;
373  else if (interactionPos4D.X() < minX || interactionPos4D.X() > maxX ) continue;
374  else if (interactionPos4D.Y() < minY || interactionPos4D.Y() > maxY ) continue;
375  if ((truetraj.KeyToProcess(couple.second)).find("hadElastic")!= std::string::npos) el++;
376  if ((truetraj.KeyToProcess(couple.second)).find("pi+InElastic")!= std::string::npos) inel++;
377 
378  // If we made it here, then this is the first interesting interaction in the TPC
379  // Our job is done!!! Great! Store the interaction label and the iterator for the final point
380  interactionLabel = truetraj.KeyToProcess(couple.second);
381  std::cout<<"interaction Label "<<interactionLabel<<" EndProcess "<<particle->EndProcess()<<std::endl;
382  finTPCPoint = truetraj.begin() + couple.first;
383  keepInteraction=true;
385  break; //commented for now
386  }// Loop on interaction points
387  } // If there are G4 interactions
388 
389  std::cout<<"this trjectory size "<<thisTracjectoryProcessMap.size()<<std::endl;
390  processtot->Fill(totint);
391  processEl->Fill(el);
392  processInel->Fill(inel);
393 
394 
395  sim::ParticleList::const_iterator itPart=plist.begin();
396 
397  // If I didn't find anything interesting in the intereaction map, let's loop back!
398  if (!keepInteraction)
399  {
400  //Loop on the daughters
401  for(size_t iPart1=0;(iPart1<plist.size()) && (plist.begin()!=plist.end());++iPart1)
402  {
403  const simb::MCParticle* pPart=(itPart++)->second;
404  // art::Ptr<simb::MCTruth> const& mcDaught=pi_serv->ParticleToMCTruth_P(pPart)
405  //We keep only the dauthers of the primary not coming from elastic or inelastic scattering
406  if (pPart->Mother() != 1 ) continue;
407  // std::cout<<"pPart mother "<<pPart->Mother()<<std::endl;
408  if ((pPart->Process()).find("astic")!= std::string::npos) continue;
409  if ((pPart->Process()).find("CoulombScat")!= std::string::npos) continue;
410  //Is the daughter born inside the TPC? If yes, store the process which created it
411  simb::MCTrajectory trueDaugthTraj = pPart->Trajectory();
412  if (trueDaugthTraj.begin()->first.Z() < minZ || trueDaugthTraj.begin()->first.Z() > maxZ) continue;
413  else if (trueDaugthTraj.begin()->first.X() < minX || trueDaugthTraj.begin()->first.X() > maxX ) continue;
414  else if (trueDaugthTraj.begin()->first.Y() < minY || trueDaugthTraj.begin()->first.Y() > maxY ) continue;
415  else {
416  interactionLabel = pPart->Process();
417 
418  break;
419  }
420  }
421  for ( auto t = std::prev(truetraj.end()); t!= truetraj.begin(); t--)
422  {
423  auto pos = t->first;
424 
425  if (pos.Z() > maxZ) continue;
426  else if (pos.X() < minX || pos.X() > maxX ) continue;
427  else if (pos.Y() < minY || pos.Y() > maxY ) continue;
428  else {
429  finTPCPoint = t;
430  break;
431  }
432  }
433  }
434  //}//new bracket added here
435 
436  if (finTPCPoint != inTPCPoint){
437  auto posFin = finTPCPoint->first;
438  auto posIni = inTPCPoint->first;
439  //Let's record what the initial and final points are.
440  trueVtxX = posIni.X();
441  trueVtxY = posIni.Y();
442  trueVtxZ = posIni.Z();
443  trueEndX = posFin.X();
444  trueEndY = posFin.Y();
445  trueEndZ = posFin.Z();
446  // std::cout<<"initial x, y and z && final x, y and z "<<trueVtxX<<" "<<trueVtxY<<" "<<trueVtxZ<<" "<<trueEndX<<" "<<trueEndY<<" "<<trueEndZ<<std::endl;
447  auto totLength = distance(posFin.X(), posFin.Y(), posFin.Z(),posIni.X(), posIni.Y(), posIni.Z() );
448  // std::cout<<"totalLength "<<totLength<<std::endl;
449 
450  // We want to chop up the points between the first and last uniformly
451  // and ordered by Z
452  // Order them in order of increasing Z
453  std::map<double, TVector3> orderedUniformTrjPts;
454  // We want the first and uniform point to coincide with the
455  // the first and last points we just found
456  auto positionVector0 = (inTPCPoint ->first).Vect();
457  auto positionVector1 = (finTPCPoint->first).Vect();
458  orderedUniformTrjPts[positionVector0.Z()] = positionVector0;
459  orderedUniformTrjPts[positionVector1.Z()] = positionVector1;
460  // const double trackPitch = 0.47;
461  const double trackPitch = 0.4792;
462  // I do have space for at least one extra point, so let's put it there!
463  // Calculate how many extra points I need to put between the new first point and the second TrajPoint
464  int nPts = (int) (totLength/trackPitch);
465  for (int iPt = 1; iPt <= nPts; iPt++ )
466  {
467  auto newPoint = positionVector0 + iPt*(trackPitch/totLength) * (positionVector1 - positionVector0);
468  orderedUniformTrjPts[newPoint.Z()] = newPoint;
469  }
470  // If the distance between the last point and the second to last is less then 0.235
471  // eliminate the second to last point
472  auto lastPt = (orderedUniformTrjPts.rbegin())->second;
473  auto secondtoLastPt = (std::next(orderedUniformTrjPts.rbegin()))->second;
474  double lastDist = distance(lastPt.X(),lastPt.Y(),lastPt.Z(),secondtoLastPt.X(),secondtoLastPt.Y(),secondtoLastPt.Z());
475  if (lastDist < 0.240)
476  {
477  orderedUniformTrjPts.erase((std::next(orderedUniformTrjPts.rbegin()))->first );
478  }
479 
480  // Calculate the initial kinetic energy
481  auto initialMom = inTPCPoint->second;
482  double initialKE = 1000*(TMath::Sqrt(initialMom.X()*initialMom.X() + initialMom.Y()*initialMom.Y() + initialMom.Z()*initialMom.Z() + mass*mass ) - mass);
483  hKEAtTPCFF->Fill(initialKE);
484  double kineticEnergy = initialKE;
485  auto old_it = orderedUniformTrjPts.begin();
486  for (auto it = std::next(orderedUniformTrjPts.begin()); it != orderedUniformTrjPts.end(); it++, old_it++ )
487  {
488 
489  if (verbose) std::cout << it->first<<" : " << (it->second).Z() << std::endl ;
490  auto oldPos = old_it->second;
491  auto currentPos = it->second;
492 
493  double uniformDist = (currentPos - oldPos).Mag();
494  h_UniformDistances->Fill(uniformDist);
495 
496  //Calculate the energy deposited in this slice
497  auto old_iter = orderedSimIDE.begin();
498  double currentDepEnergy = 0.;
499  for ( auto iter= orderedSimIDE.begin(); iter!= orderedSimIDE.end(); iter++,old_iter++)
500  {
501  auto currentIde = iter->second;
502  // std::cout<<"Z position of the trajectory hits "<<currentIde.z<<std::endl;
503  if ( currentIde.z < oldPos.Z()) continue;
504  if ( currentIde.z > currentPos.Z()) continue;
505  currentDepEnergy += currentIde.energy;
506  }// Determing which simIDE is within the current slice
507  // avoid overfilling super tiny energy depositions
508  if (currentDepEnergy/uniformDist < 0.1 ) continue;
509  //Calculate the current kinetic energy
510  kineticEnergy -= currentDepEnergy;
511  hdEVsdX->Fill(currentDepEnergy,(currentPos.Z()-oldPos.Z()) );
512  hdEVsKE->Fill(currentDepEnergy,kineticEnergy);
513  hIncidentKE->Fill(kineticEnergy);
514  h_DEUniform->Fill(currentDepEnergy);
515  h_DXUniform->Fill(uniformDist);
516  h_DEDXUniform->Fill(currentDepEnergy/uniformDist);
517 
518  }// Loop on OrderedPoints
519 
520  if(interactionLabel.find("Inelastic")!= std::string::npos )//added pi+Inelastic instead of Inelastic
521  //if(interactionLabel=="pi+Inelastic")
522  // if(particle->EndProcess()=="pi+Inelastic")
523  {
524  // std::cout<<"Interaction Label: "<<interactionLabel<<" EndProcess "<<particle->EndProcess();
525  hInteractingKE->Fill(kineticEnergy);
526  hInteractingKEInel->Fill(kineticEnergy);
527  //std::cout<<"inside pi+Inelastic loop and ke "<<kineticEnergy<<std::endl;
528  }
529 
530  //Fill the Elastic and Total Interacting with the last point
531  if ( interactionLabel.find("Elastic")!= std::string::npos ) //added hadElastic instead of Elastic
532  // if(interactionLabel=="hadElastic")
533  // if(particle->EndProcess()=="hadElastic")
534  {
535  // std::cout<<"Interaction Label: "<<interactionLabel<<" EndProcess "<<particle->EndProcess();
536  h_DeltaE ->Fill(kineticEnergy - 1000*((finTPCPoint->second).E() - mass) );
537  hInteractingKEElDep->Fill(kineticEnergy);
538  hInteractingKE->Fill(kineticEnergy);
539  // auto MomentumF = finTPCPoint->second;
540  // double KEF = 1000*(TMath::Sqrt(MomentumF.X()*MomentumF.X() + MomentumF.Y()*MomentumF.Y() + MomentumF.Z()*MomentumF.Z() + mass*mass ) - mass); //I want this in MeV
541  // hInteractingKEEl->Fill(KEF);
542  hInteractingKEEl->Fill(kineticEnergy);
543  // std::cout<<"inside hadElastic Loop and KEF "<<KEF<<std::endl;
544  }
545  finalKE = kineticEnergy;
546  keepInteraction = false;
547  if (!interactionLabel.size())
548  {
549  throughgoing++;
550  G4Process.push_back("throughgoing");
551  }else
552  {
553  G4Process.push_back(interactionLabel);
554  }
555 
556 
557 
558  ////***********************new segment of the code ends here******************************************************************************//
559  }
560  }//if finTPC!=inTPC
561  }//if primary
562  } //if particle
563  fEventTree->Fill();
564  } // end of analyze function
565 
566  //========================================================================
568 
569  std::cout<<"-------------------------------------------"<<std::endl;
570  std::cout<<"True Events pre-TPC .............. "<<evtsPreTPC<<std::endl;
571  std::cout<<"True Events pre-TPC .............. "<<evtsInTheMiddle<<std::endl;
572  std::cout<<"True Events post-TPC ............. "<<evtsPostTPC<<std::endl;
573  std::cout<<"True Throughgoing ............. "<<throughgoing<<std::endl;
574  std::cout<<"True interactingInTPC ............ "<<interactingInTPC<<std::endl;
575  std::cout<<"-------------------------------------------"<<std::endl;
576  float rho = 1396; //kg/m^3
577  float molar_mass = 39.95; //g/mol
578  float g_per_kg = 1000;
579  float avogadro = 6.022e+23; //number/mol
580  float number_density = rho*g_per_kg/molar_mass*avogadro;
581  //float slab_width = 0.0047;//in m
582  float slab_width = 0.004792;//in m
583  // Calculate the Cross Section
584  // ###################################################################
585  // #### Looping over the exiting bins to extract the cross-section ###
586  // ###################################################################
587  for( int iBin = 1; iBin <= hInteractingKE->GetNbinsX(); ++iBin )
588  {
589  // ### If an incident bin is equal to zero then skip that bin ###
590  if( hIncidentKE->GetBinContent(iBin) == 0 )continue; //Temporary fix to ensure that no Infinities are propagated to pad
591 
592  // ### Cross-section = (Exit Bins / Incident Bins) * (1/Density) * (1/slab width) ###
593  float TempCrossSection = (hInteractingKE->GetBinContent(iBin)/hIncidentKE->GetBinContent(iBin)) * (1/number_density) * (1/slab_width);
594 
595  float elCrossSection = ((hInteractingKEEl->GetBinContent(iBin)/hIncidentKE->GetBinContent(iBin)) * (1/number_density) * (1/slab_width) ) * (1/1e-28);
596  float inelCrossSection = ((hInteractingKEInel->GetBinContent(iBin)/hIncidentKE->GetBinContent(iBin)) * (1/number_density) * (1/slab_width) ) * (1/1e-28);
597  // ### Convert this into Barns ###
598  float crossSection = TempCrossSection * (1/1e-28);
599 
600  // ### Putting the value on the plot
601  hCrossSection ->SetBinContent(iBin,crossSection);
602  hCrossSectionEl ->SetBinContent(iBin,elCrossSection);
603  hCrossSectionInel->SetBinContent(iBin,inelCrossSection);
604  // ###########################################################
605  // ### Calculating the error on the numerator of the ratio ###
606  // ###########################################################
607  float denomError = pow(hIncidentKE->GetBinContent(iBin),0.5);
608  float denom = hIncidentKE->GetBinContent(iBin);
609  if(denom == 0) continue;
610  float term2 = denomError/denom;
611 
612  float numError = pow(hInteractingKE->GetBinContent(iBin),0.5);
613  float num = hInteractingKE->GetBinContent(iBin);
614  float numErrorEl = pow(hInteractingKEEl->GetBinContent(iBin),0.5);
615  float numEl = hInteractingKEEl->GetBinContent(iBin);
616  float numErrorInel = pow(hInteractingKEInel->GetBinContent(iBin),0.5);
617  float numInel = hInteractingKEInel->GetBinContent(iBin);
618  // ### Putting in a protection against dividing by zero ###
619  if(num != 0){
620  float term1 = numError/num;
621  float totalError = (TempCrossSection) * (pow( ( (term1*term1) + (term2*term2) ),0.5)) * (1/number_density) * (1/slab_width) * (1/1e-28) *(1e26);
622  hCrossSection->SetBinError(iBin,totalError);
623  }
624 
625  if(numEl != 0){
626  float term1 = numErrorEl/numEl;
627  float totalError = (elCrossSection) * (pow( ( (term1*term1) + (term2*term2) ),0.5)) * (1/number_density) * (1/slab_width) *(1e26);
628  hCrossSectionEl->SetBinError(iBin,totalError);
629  }
630 
631  if(numInel != 0){
632  float term1 = numErrorInel/numInel;
633  float totalError = (inelCrossSection) * (pow( ( (term1*term1) + (term2*term2) ),0.5)) * (1/number_density) * (1/slab_width) *(1e26);
634  hCrossSectionInel->SetBinError(iBin,totalError);
635  }
636  }//<---End iBin Loop
637 
638 
639  }
640 
641 
642 
643 
644  /////////////////// Defintion of reset function ///////////
646  run = -99999;
647  subrun = -99999;
648  event = -99999;
649 
650  trueVtxX = -999.;
651  trueVtxY = -999.;
652  trueVtxZ = -999.;
653  trueEndX = -999.;
654  trueEndY = -999.;
655  trueEndZ = -999.;
656  trueEndZ = -999.;
657  finalKE = -999.;
658  G4Process.clear();
659 
660 
661  }
662 
663 
664 
665 
666 
667 
668 
669 
670  //////////////////////// End of definition ///////////////
671 
673 }
674 
675 
const simb::MCParticle * GetGeantGoodParticle(const simb::MCTruth &genTruth, const art::Event &evt) const
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
const simb::MCTrajectory & Trajectory() const
Definition: MCParticle.h:253
int Mother() const
Definition: MCParticle.h:213
const value_type & at(const size_type i) const
Definition: MCTrajectory.h:175
constexpr T pow(T x)
Definition: pow.h:72
std::string KeyToProcess(unsigned char const &key) const
std::vector< const sim::IDE * > TrackIdToSimIDEs_Ps(int const &id) const
STL namespace.
intermediate_table::const_iterator const_iterator
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
std::string Process() const
Definition: MCParticle.h:215
Particle class.
object containing MC flux information
art framework interface to geometry description
Definition: Run.h:17
truepionXsection(fhicl::ParameterSet const &pset)
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
std::vector< std::string > G4Process
RunNumber_t run() const
Definition: DataViewImpl.cc:71
void analyze(const art::Event &evt)
void beginRun(const art::Run &run)
ProcessMap const & TrajectoryProcesses() const
Definition: MCTrajectory.h:188
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
Definition of data types for geometry description.
verbose
Definition: train.py:477
const sim::ParticleList & ParticleList() const
Declaration of signal hit object.
ProtoDUNETruthUtils truthUtil
below are some addition to be able to use protodune utitilites
Provides recob::Track data product.
EventNumber_t event() const
Definition: EventID.h:116
Declaration of basic channel signal object.
TCEvent evt
Definition: DataStructs.cxx:7
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
int bool
Definition: qglobal.h:345
Utility functions to extract information from recob::Track
EventID id() const
Definition: Event.cc:34
QTextStream & endl(QTextStream &s)
Event finding and building.