All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MultiEMShowers_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: MultiEMShowers
3 // Module Type: analyzer
4 // File: MultiEMShowers_module.cc
5 // Author: dorota.stefan@cern.ch robert.sulej@cern.ch
6 ////////////////////////////////////////////////////////////////////////
7 
8 #include "art/Framework/Core/EDAnalyzer.h"
9 #include "art/Framework/Core/ModuleMacros.h"
10 #include "art/Framework/Principal/Event.h"
11 #include "art/Framework/Principal/Handle.h"
12 #include "art/Framework/Services/Registry/ServiceHandle.h"
13 #include "art_root_io/TFileService.h"
14 #include "canvas/Persistency/Common/FindManyP.h"
15 #include "canvas/Utilities/InputTag.h"
16 #include "fhiclcpp/ParameterSet.h"
17 #include "messagefacility/MessageLogger/MessageLogger.h"
18 
28 
29 #include <memory>
30 
31 // ROOT includes
32 #include "TLorentzVector.h"
33 #include "TTree.h"
34 
35 namespace ems {
36  class MCinfo;
37  class MultiEMShowers;
38 }
39 
40 class ems::MCinfo {
41 public:
42  MCinfo(const art::Event& evt);
43  void Info(const art::Event& evt);
44  void Findtpcborders(const art::Event& evt);
45 
46  int
47  GetNgammas() const
48  {
49  return fNgammas;
50  }
51 
52  double
53  GetMompi0() const
54  {
55  return fMompi0;
56  }
57  double
58  GetMomGamma1() const
59  {
60  return fGammamom1;
61  }
62  double
63  GetMomGamma2() const
64  {
65  return fGammamom2;
66  }
67 
68  double
70  {
71  return fCosine;
72  }
73 
74  TVector3 const&
75  GetPrimary() const
76  {
77  return fPrimary;
78  }
79  TVector3 const&
80  GetPospi0() const
81  {
82  return fPi0pos;
83  }
84  TVector3 const&
85  GetPosgamma1() const
86  {
87  return fConvgamma1;
88  }
89  TVector3 const&
90  GetPosgamma2() const
91  {
92  return fConvgamma2;
93  }
94 
95  TVector3 const&
96  GetDirgamma1() const
97  {
98  return fDirgamma1;
99  }
100  TVector3 const&
101  GetDirgamma2() const
102  {
103  return fDirgamma2;
104  }
105 
106  bool const&
107  IsInside1() const
108  {
109  return fInside1;
110  }
111  bool const&
112  IsInside2() const
113  {
114  return fInside2;
115  }
116 
117  bool const&
118  IsCompton() const
119  {
120  return fCompton;
121  }
122 
123 private:
124  bool insideFidVol(const TLorentzVector& pvtx) const;
125  double fMinx;
126  double fMaxx;
127  double fMiny;
128  double fMaxy;
129  double fMinz;
130  double fMaxz;
131 
132  double fFidVolCut;
133 
134  int fNgammas;
135 
136  double fMompi0;
137  double fGammamom1;
138  bool fInside1;
139  double fGammamom2;
140  bool fInside2;
141 
142  double fCosine;
143 
144  bool fCompton;
145 
146  TVector3 fPrimary;
147  TVector3 fPi0pos;
148  TVector3 fConvgamma1;
149  TVector3 fConvgamma2;
150  TVector3 fDirgamma1;
151  TVector3 fDirgamma2;
152 };
153 
154 ems::MCinfo::MCinfo(const art::Event& evt) : fFidVolCut(2.0)
155 {
156  Info(evt);
157  Findtpcborders(evt);
158 }
159 
160 void
162 {
163  art::ServiceHandle<geo::Geometry const> geom;
164 
165  fMinx = geom->IterateTPCs().begin()->MinX();
166  fMiny = geom->IterateTPCs().begin()->MinY();
167  fMinz = geom->IterateTPCs().begin()->MinZ();
168  fMaxx = geom->IterateTPCs().begin()->MaxX();
169  fMaxy = geom->IterateTPCs().begin()->MaxY();
170  fMaxz = geom->IterateTPCs().begin()->MaxZ();
171 
172  for (const geo::TPCGeo& tpcg : geom->IterateTPCs()) {
173  if (tpcg.MinX() < fMinx) fMinx = tpcg.MinX();
174  if (tpcg.MaxX() > fMaxx) fMaxx = tpcg.MaxX();
175  if (tpcg.MinY() < fMiny) fMiny = tpcg.MinY();
176  if (tpcg.MaxY() > fMaxy) fMaxy = tpcg.MaxY();
177  if (tpcg.MinZ() < fMinz) fMinz = tpcg.MinZ();
178  if (tpcg.MaxZ() > fMaxz) fMaxz = tpcg.MaxZ();
179  }
180 }
181 
182 void
183 ems::MCinfo::Info(const art::Event& evt)
184 {
185  fMompi0 = 0.0;
186  fPi0pos.SetXYZ(0, 0, 0);
187  fNgammas = 0;
188  fCosine = 0.0;
189  fInside1 = false;
190  fInside2 = false;
191  fCompton = false;
192 
193  fGammamom1 = 0.0;
194  fGammamom2 = 0.0;
195  fConvgamma1.SetXYZ(0, 0, 0);
196  fConvgamma2.SetXYZ(0, 0, 0);
197  fDirgamma1.SetXYZ(0, 0, 0);
198  fDirgamma2.SetXYZ(0, 0, 0);
199 
200  art::ServiceHandle<cheat::ParticleInventoryService const> pi_serv;
201  const sim::ParticleList& plist = pi_serv->ParticleList();
202  for (sim::ParticleList::const_iterator ipar = plist.begin(); ipar != plist.end(); ++ipar) {
203  const simb::MCParticle* particle = ipar->second;
204 
205  if (particle->Process() != "primary") continue;
206 
207  TLorentzVector posvec = particle->Position();
208  TVector3 pose(posvec.X(), posvec.Y(), posvec.Z());
209  fPrimary = pose;
210 
211  if (particle->PdgCode() == 111) {
212  fMompi0 = particle->P();
213 
214  TLorentzVector posvec3 = particle->Position();
215  TVector3 pospi0(posvec3.X(), posvec3.Y(), posvec3.Z());
216  fPi0pos = pospi0;
217 
218  if (particle->NumberDaughters() != 2) continue;
219 
220  const simb::MCParticle* daughter1 = pi_serv->TrackIdToParticle_P(particle->Daughter(0));
221  if (daughter1->PdgCode() != 22) continue;
222 
223  const simb::MCParticle* daughter2 = pi_serv->TrackIdToParticle_P(particle->Daughter(1));
224  if (daughter2->PdgCode() != 22) continue;
225 
226  fNgammas = particle->NumberDaughters();
227  TLorentzVector mom1 = pi_serv->TrackIdToParticle_P(particle->Daughter(0))->Momentum();
228  TLorentzVector mom2 = pi_serv->TrackIdToParticle_P(particle->Daughter(1))->Momentum();
229 
230  // compton process
231  if (daughter1->EndProcess() == "phot") fCompton = true;
232  if (daughter2->EndProcess() == "phot") fCompton = true;
233 
234  TVector3 mom1vec3(mom1.Px(), mom1.Py(), mom1.Pz());
235  fGammamom1 = pi_serv->TrackIdToParticle_P(particle->Daughter(0))->P();
236  TVector3 mom2vec3(mom2.Px(), mom2.Py(), mom2.Pz());
237  fGammamom2 = pi_serv->TrackIdToParticle_P(particle->Daughter(1))->P();
238 
239  TLorentzVector pos1 = pi_serv->TrackIdToParticle_P(particle->Daughter(0))->EndPosition();
240  TLorentzVector pos2 = pi_serv->TrackIdToParticle_P(particle->Daughter(1))->EndPosition();
241 
242  if (insideFidVol(pos1)) fInside1 = true;
243  if (insideFidVol(pos2)) fInside2 = true;
244 
245  fConvgamma1.SetXYZ(pos1.X(), pos1.Y(), pos1.Z());
246  fConvgamma2.SetXYZ(pos2.X(), pos2.Y(), pos2.Z());
247 
248  TVector3 vecnorm1 = mom1vec3.Unit();
249  fDirgamma1 = vecnorm1;
250  TVector3 vecnorm2 = mom2vec3.Unit();
251  fDirgamma2 = vecnorm2;
252 
253  fCosine = fDirgamma1 * fDirgamma2;
254  }
255  else {
256  fNgammas = particle->NumberDaughters();
257  }
258  }
259 }
260 
261 bool
262 ems::MCinfo::insideFidVol(const TLorentzVector& pvtx) const
263 {
264 
265  bool inside = false;
266  //x
267  double dista = fabs(fMinx - pvtx.X());
268  double distb = fabs(pvtx.X() - fMaxx);
269  if ((pvtx.X() > fMinx) && (pvtx.X() < fMaxx) && (dista > fFidVolCut) && (distb > fFidVolCut))
270  inside = true;
271  //y
272  dista = fabs(fMaxy - pvtx.Y());
273  distb = fabs(pvtx.Y() - fMiny);
274  if (inside && (pvtx.Y() > fMiny) && (pvtx.Y() < fMaxy) && (dista > fFidVolCut) &&
275  (distb > fFidVolCut))
276  inside = true;
277  else
278  inside = false;
279 
280  //z
281  dista = fabs(fMaxz - pvtx.Z());
282  distb = fabs(pvtx.Z() - fMinz);
283  if (inside && (pvtx.Z() > fMinz) && (pvtx.Z() < fMaxz) && (dista > fFidVolCut) &&
284  (distb > fFidVolCut))
285  inside = true;
286  else
287  inside = false;
288 
289  return inside;
290 }
291 
292 class ems::MultiEMShowers : public art::EDAnalyzer {
293 public:
294  explicit MultiEMShowers(fhicl::ParameterSet const& p);
295 
296  MultiEMShowers(MultiEMShowers const&) = delete;
297  MultiEMShowers(MultiEMShowers&&) = delete;
298  MultiEMShowers& operator=(MultiEMShowers const&) = delete;
299  MultiEMShowers& operator=(MultiEMShowers&&) = delete;
300 
301 private:
302  void beginJob() override;
303  void endJob() override;
304 
305  void analyze(art::Event const& e) override;
306 
307  bool convCluster(art::Event const& evt);
308  double getMinDist(detinfo::DetectorPropertiesData const& detProp,
309  std::vector<art::Ptr<recob::Hit>> const& v,
310  TVector3 const& convmc,
311  size_t view,
312  size_t tpc,
313  size_t cryo);
318 
319  // ROOT
320  TTree* fEvTree;
322  int fNGroups;
323 
324  // mc
325  double fPi0mom;
326  double fGmom1;
327  double fGmom2;
328  double fMcth;
329  int fNgammas;
331  int fEvComp;
333  int fEvInput;
334  TVector3 fGdir1;
335  TVector3 fGdir2;
336  TVector3 fPrimary;
337 
338  //reco
339  int fEvReco;
341  int fEv2Good;
342  int fCountph;
344 
345  TTree* fShTree;
346  TTree* fRecoTree;
347  double fStartX;
348  double fStartY;
349  double fStartZ;
350  double fDedxZ;
351  double fDedxV;
352  double fDedxU;
353  double fMCrecovtx;
354  double fMCrecoTh;
357  double fRecth;
358  double fRecthgood;
361  double fGdirmcreco1;
362  double fGdirmcreco2;
365 
366  art::InputTag fHitsModuleLabel;
367  art::InputTag fCluModuleLabel;
368  art::InputTag fTrk3DModuleLabel;
369  art::InputTag fVtxModuleLabel;
370  art::InputTag fShsModuleLabel;
371 };
372 
373 ems::MultiEMShowers::MultiEMShowers(fhicl::ParameterSet const& p) : EDAnalyzer(p)
374 {
375  fConvGood = 0;
376  fConvWrong = 0;
377  fConvBothGood = 0;
378  fEvFidVol = 0;
379  fEvComp = 0;
380  fEvGMomCut = 0;
381  fEvReco = 0;
382  fEvInput = 0;
383  fEv2Groups = 0;
384  fEv2Good = 0;
385  fHitsModuleLabel = p.get<art::InputTag>("HitsModuleLabel");
386  fCluModuleLabel = p.get<art::InputTag>("ClustersModuleLabel");
387  fTrk3DModuleLabel = p.get<art::InputTag>("Trk3DModuleLabel");
388  fVtxModuleLabel = p.get<art::InputTag>("VtxModuleLabel");
389  fShsModuleLabel = p.get<art::InputTag>("ShsModuleLabel");
390 }
391 
392 void
394 {
395  art::ServiceHandle<art::TFileService const> tfs;
396 
397  fEvTree = tfs->make<TTree>("MultiShowers", "showers3d");
398  fEvTree->Branch("fEvNumber", &fEvNumber, "fEvNumber/I");
399  fEvTree->Branch("fNGroups", &fNGroups, "fNGroups/I");
400  fEvTree->Branch("fPi0mom", &fPi0mom, "fPi0mom/D");
401  fEvTree->Branch("fNgammas", &fNgammas, "fNgammas/I");
402  fEvTree->Branch("fGmom1", &fGmom1, "fGmom1/D");
403  fEvTree->Branch("fGmom2", &fGmom2, "fGmom2/D");
404  fEvTree->Branch("fMcth", &fMcth, "fMcth/D");
405  fEvTree->Branch("fRecth", &fRecth, "fRecth/D");
406  fEvTree->Branch("fMCrecovtx", &fMCrecovtx, "fMCrecovtx/D");
407  fEvTree->Branch("fMCrecoTh", &fMCrecoTh, "fMCrecoTh/D");
408  fEvTree->Branch("fConvGood", &fConvGood, "fConvGood/I");
409  fEvTree->Branch("fConvWrong", &fConvWrong, "fConvWrong/I");
410  fEvTree->Branch("fConvBothGood", &fConvBothGood, "fConvBothGood/I");
411  fEvTree->Branch("fGammasInside", &fGammasInside, "fGammasInside/I");
412  fEvTree->Branch("fCountph", &fCountph, "fCountph/I");
413  fEvTree->Branch("fCountreco", &fCountreco, "fCountreco/I");
414 
415  fRecoTree = tfs->make<TTree>("Cascades", "conv points");
416  fRecoTree->Branch("fRecth", &fRecth, "fRecth/D");
417  fRecoTree->Branch("fMCrecovtx", &fMCrecovtx, "fMCrecovtx/D");
418  fRecoTree->Branch("fMCrecoTh", &fMCrecoTh, "fMCrecoTh/D");
419  fRecoTree->Branch("fRecthgood", &fRecthgood, "fRecthgood/D");
420  fRecoTree->Branch("fMCrecovtxgood", &fMCrecovtxgood, "fMCrecovtxgood/D");
421  fRecoTree->Branch("fMCrecoThgood", &fMCrecoThgood, "fMCrecoThgood/D");
422  fRecoTree->Branch("fGdirmcreco1", &fGdirmcreco1, "fGdirmcreco1/D");
423  fRecoTree->Branch("fGdirmcreco2", &fGdirmcreco2, "fGdirmcreco2/D");
424  fRecoTree->Branch("fGdirmcreco1good", &fGdirmcreco1good, "fGdirmcreco1good/D");
425  fRecoTree->Branch("fGdirmcreco2good", &fGdirmcreco2good, "fGdirmcreco2good/D");
426 
427  fShTree = tfs->make<TTree>("Shower", "conv point");
428 
429  fShTree->Branch("fStartX", &fStartX, "fStartX/D");
430  fShTree->Branch("fStartY", &fStartY, "fStartY/D");
431  fShTree->Branch("fStartZ", &fStartZ, "fStartZ/D");
432  fShTree->Branch("fDedxZ", &fDedxZ, "fDedxZ/D");
433  fShTree->Branch("fDedxV", &fDedxV, "fDedxV/D");
434  fShTree->Branch("fDedxU", &fDedxU, "fDedxU/D");
435 }
436 
437 void
439 {
440  mf::LogInfo log("MultiEMShower");
441  log << "******************** fEvFidVol = " << fEvFidVol << "\n";
442  log << "******************** fEvGMomCut = " << fEvGMomCut << "\n";
443  log << "******************** fEvComp = " << fEvComp << "\n";
444  log << "******************** fEvReco = " << fEvReco << "\n";
445  log << "******************** fEvInput = " << fEvInput << "\n";
446  log << "******************** fEv2Groups = " << fEv2Groups << "\n";
447  log << "******************** fEv2Good = " << fEv2Good << "\n";
448  if (fEvInput)
449  log << "******************** reco % = " << double(fEvReco) / double(fEvInput) << "\n";
450 }
451 
452 void
453 ems::MultiEMShowers::analyze(art::Event const& e)
454 {
455  fEvNumber = e.id().event();
456  fNGroups = 0;
457  fStartX = 0.0;
458  fStartY = 0.0;
459  fStartZ = 0.0;
460  fPi0mom = 0.0;
461  fNgammas = 0;
462  fDistConvrecomc1 = 0.0;
463  fDistConvrecomc2 = 0.0;
464  fMCrecovtx = -400.0;
465  fMCrecovtxgood = -400.0;
466  fRecth = -400.0;
467  fRecthgood = -400.0;
468  fMCrecoTh = -400.0;
469  fMCrecoThgood = -400.0;
470  fGammasInside = 0;
471  fCountph = 0;
472  fCountreco = 0;
473  fGdirmcreco1 = 0.0;
474  fGdirmcreco2 = 0.0;
475  fGdirmcreco1good = 0.0;
476  fGdirmcreco2good = 0.0;
477  fDedxZ = 0.0;
478  fDedxV = 0.0;
479  fDedxU = 0.0;
480 
481  ems::MCinfo mc(e);
482  fPrimary = mc.GetPrimary();
483  fPi0mom = mc.GetMompi0();
484  fGmom1 = mc.GetMomGamma1();
485  fGmom2 = mc.GetMomGamma2();
486  fGdir1 = mc.GetDirgamma1();
487  fGdir2 = mc.GetDirgamma2();
488  fNgammas = mc.GetNgammas();
489  TVector3 pospi0 = mc.GetPospi0();
490 
491  double cosinemc = mc.GetCosine();
492  fMcth = 180.0F * (std::acos(cosinemc)) / TMath::Pi();
493  TVector3 convp[2];
494  convp[0] = mc.GetPosgamma1();
495  convp[1] = mc.GetPosgamma2();
496  const double maxdist = 2.0; //cm
497 
498  // check whether two photons are inside fid vol
499  if (mc.IsInside1() && mc.IsInside2()) {
500  fGammasInside = 1;
501  fEvFidVol++;
502  }
503 
504  if ((fGmom1 > 0.1) && (fGmom2 > 0.1)) fEvGMomCut++;
505 
506  if (mc.IsCompton()) fEvComp++;
507 
508  art::Handle<std::vector<recob::Shower>> shsListHandle;
509  art::Handle<std::vector<recob::Track>> trkListHandle;
510  art::Handle<std::vector<recob::Vertex>> vtxListHandle;
511  art::Handle<std::vector<recob::Cluster>> cluListHandle;
512  art::Handle<std::vector<recob::Hit>> hitListHandle;
513  if (e.getByLabel(fShsModuleLabel, shsListHandle) &&
514  e.getByLabel(fTrk3DModuleLabel, trkListHandle) &&
515  e.getByLabel(fVtxModuleLabel, vtxListHandle) &&
516  e.getByLabel(fCluModuleLabel, cluListHandle) &&
517  e.getByLabel(fHitsModuleLabel, hitListHandle)) {
518  art::FindManyP<recob::Cluster> cluFromShs(shsListHandle, e, fShsModuleLabel);
519  art::FindManyP<recob::Cluster> cluFromTrk(trkListHandle, e, fTrk3DModuleLabel);
520  art::FindManyP<recob::Vertex> vtxFromTrk(trkListHandle, e, fVtxModuleLabel);
521  art::FindManyP<recob::Hit> hitFromClu(cluListHandle, e, fCluModuleLabel);
522 
523  fNGroups = shsListHandle->size();
524 
525  fCountph = 0;
526  if (fNgammas == 2) // pi0
527  {
528  int idph = -1;
529  for (size_t s = 0; s < shsListHandle->size(); ++s) {
530  const recob::Shower& sh = (*shsListHandle)[s];
531  double mindist = maxdist;
532  bool found = false;
533 
534  for (int i = 0; i < fNgammas; ++i) {
535  double dist = sqrt(pma::Dist2(sh.ShowerStart(), convp[i]));
536  if ((dist < mindist) && (idph != i)) {
537  mindist = dist;
538  idph = i;
539  found = true;
540  }
541  }
542  if (found) {
543  fConvGood++;
544  fCountph++;
545  }
546  else {
547  fConvWrong++;
548  }
549  }
550  if (fCountph == 2) fConvBothGood++;
551 
552  // plot a few variables if there are 2 showers
553  if (fCountph == 2)
554  for (size_t s = 0; s < shsListHandle->size(); ++s) {
555  const recob::Shower& sh = (*shsListHandle)[s];
556  TVector3 pos = sh.ShowerStart();
557  fStartX = pos.X();
558  fStartY = pos.Y();
559  fStartZ = pos.Z();
560  std::vector<double> const& vecdedx = sh.dEdx();
561 
562  if (vecdedx.size() == 3) {
563  fDedxZ = vecdedx[0];
564  fDedxV = vecdedx[1];
565  fDedxU = vecdedx[2];
566  }
567 
568  fShTree->Fill();
569  }
570  }
571  else // other than pi0
572  {
573  for (size_t s = 0; s < shsListHandle->size(); ++s) {
574  const recob::Shower& sh = (*shsListHandle)[s];
575  double mindist = maxdist;
576 
577  double dist = sqrt(pma::Dist2(sh.ShowerStart(), fPrimary));
578  if (dist < mindist) {
579  TVector3 pos = sh.ShowerStart();
580  fStartX = pos.X();
581  fStartY = pos.Y();
582  fStartZ = pos.Z();
583  std::vector<double> vecdedx = sh.dEdx();
584  if (vecdedx.size() == 3) {
585  fDedxZ = vecdedx[0];
586  fDedxV = vecdedx[1];
587  fDedxU = vecdedx[2];
588  }
589  }
590 
591  fShTree->Fill();
592  }
593  }
594  // compute the crossing point
595 
596  //cut from mc and clusters
597 
598  if (mc.IsInside1() && mc.IsInside2() && (fGmom1 > 0.1) && (fGmom2 > 0.1) && (!mc.IsCompton()) &&
599  convCluster(e)) {
600  fCountreco = 1;
601  if (fNGroups == 2) fEv2Groups++;
602  if ((fNGroups == 2) && (fCountph == 2)) fEv2Good++;
603  // cut from reco
604  //if (countph == 2)
605  if (fNGroups == 2) {
606  std::vector<std::pair<TVector3, TVector3>> lines;
607  const recob::Shower& sh1 = (*shsListHandle)[0];
608  const recob::Shower& sh2 = (*shsListHandle)[1];
609 
610  std::pair<TVector3, TVector3> frontback1(sh1.ShowerStart(),
611  sh1.ShowerStart() + sh1.Direction());
612  std::pair<TVector3, TVector3> frontback2(sh2.ShowerStart(),
613  sh2.ShowerStart() + sh2.Direction());
614  lines.push_back(frontback1);
615  lines.push_back(frontback2);
616 
617  TVector3 result;
618  pma::SolveLeastSquares3D(lines, result); // mse.
619 
620  double dist1_0 = pma::Dist2(result, sh1.ShowerStart());
621  double dist2_0 = pma::Dist2(result, sh1.ShowerStart() + sh1.Direction());
622  double dist1_1 = pma::Dist2(result, sh2.ShowerStart());
623  double dist2_1 = pma::Dist2(result, sh2.ShowerStart() + sh2.Direction());
624  if ((dist1_0 > dist2_0) || (dist1_1 > dist2_1)) {}
625  else {
626  fMCrecovtx = std::sqrt(pma::Dist2(pospi0, result));
627 
628  if (fCountph == 2) fMCrecovtxgood = fMCrecovtx;
629 
630  double cosine_reco = sh1.Direction() * sh2.Direction();
631  fRecth = 180.0F * (std::acos(cosine_reco)) / TMath::Pi();
632 
633  fGdirmcreco1 = fGdir1 * sh1.Direction();
634  fGdirmcreco2 = fGdir2 * sh2.Direction();
635  if (fCountph == 2) {
636  fGdirmcreco1good = fGdirmcreco1;
637  fGdirmcreco2good = fGdirmcreco2;
638  }
639 
640  if (fCountph == 2) fRecthgood = fRecth;
641 
642  fMCrecoTh = fRecth - fMcth;
643 
644  if (fCountph == 2) fMCrecoThgood = fMCrecoTh;
645 
646  fEvReco++;
647  fRecoTree->Fill();
648  }
649  }
650  fEvInput++;
651  //fRecoTree->Fill();
652  }
653  }
654 
655  fEvTree->Fill();
656 }
657 
658 // true if there are clusters corresponding to mc conversion points
659 bool
661 {
662  ems::MCinfo mc(evt);
663  TVector3 convp[2];
664  convp[0] = mc.GetPosgamma1();
665  convp[1] = mc.GetPosgamma2();
666 
667  double vtx[3] = {convp[0].X(), convp[0].Y(), convp[0].Z()};
668 
669  art::ServiceHandle<geo::Geometry const> geom;
670  geo::TPCID idtpc = geom->FindTPCAtPosition(vtx);
671  size_t cryoid = geom->FindCryostatAtPosition(vtx);
672 
673  art::Handle<std::vector<recob::Hit>> hitListHandle;
674  art::Handle<std::vector<recob::Cluster>> cluListHandle;
675 
676  //map: conversion point, vec of id clusters in each view
677  std::map<size_t, std::vector<size_t>> used;
678 
679  art::FindManyP<recob::Hit> fbc(cluListHandle, evt, fCluModuleLabel);
680 
681  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt);
682  double maxdist = 1.0; // 1 cm
683  if (geom->HasTPC(idtpc)) {
684  const geo::CryostatGeo& cryostat = geom->Cryostat(cryoid);
685  if (evt.getByLabel(fHitsModuleLabel, hitListHandle) &&
686  evt.getByLabel(fCluModuleLabel, cluListHandle)) {
687  size_t conv = 0;
688  while (conv < 2) {
689  for (size_t view = 0; view < cryostat.MaxPlanes(); view++) {
690 
691  double mindist = maxdist;
692  int clid = 0;
693  for (size_t c = 0; c < cluListHandle->size(); ++c) {
694 
695  bool exist = false;
696  for (auto const& ids : used)
697  for (auto i : ids.second)
698  if (i == c) exist = true;
699  if (exist) continue;
700 
701  std::vector<art::Ptr<recob::Hit>> hits = fbc.at(c);
702  if (hits.size() < 20) continue;
703  if (hits[0]->WireID().Plane != view) continue;
704 
705  double dist = getMinDist(detProp, hits, convp[conv], view, idtpc.TPC, cryoid);
706  if (dist < mindist) {
707  mindist = dist;
708  clid = c;
709  }
710  }
711  if (mindist < maxdist) used[conv].push_back(clid);
712  }
713  conv++;
714  }
715  }
716  }
717  bool result = false;
718 
719  if (used.size() > 1)
720  for (auto const& ids : used) {
721  if (ids.second.size() > 1)
722  result = true;
723  else {
724  result = false;
725  break;
726  }
727  }
728 
729  return result;
730 }
731 
732 double
734  std::vector<art::Ptr<recob::Hit>> const& v,
735  TVector3 const& convmc,
736  size_t view,
737  size_t tpc,
738  size_t cryo)
739 {
740  double mindist = 9999;
741  // MC vertex projected to view
742  TVector2 proj = pma::GetProjectionToPlane(convmc, view, tpc, cryo);
743 
744  // loop over hits to find the closest to MC 2d vtx
745  for (size_t h = 0; h < v.size(); ++h) {
746  if ((v[h]->WireID().Plane == view) && (v[h]->WireID().TPC == tpc)) {
747  TVector2 hpoint =
748  pma::WireDriftToCm(detProp, v[h]->WireID().Wire, v[h]->PeakTime(), view, tpc, cryo);
749 
750  double dist = pma::Dist2(proj, hpoint);
751  if (dist < mindist) { mindist = dist; }
752  }
753  }
754 
755  return mindist;
756 }
757 
758 DEFINE_ART_MODULE(ems::MultiEMShowers)
process_name opflashCryo1 flashfilter analyze
TVector3 const & GetDirgamma2() const
double SolveLeastSquares3D(const std::vector< std::pair< TVector3, TVector3 >> &lines, TVector3 &result)
BEGIN_PROLOG true icarus_rawdigitfilter FilterTools FilterPlane1 Plane
unsigned int MaxPlanes() const
Returns the largest number of planes among the TPCs in this cryostat.
double Dist2(const TVector2 &v1, const TVector2 &v2)
bool const & IsInside2() const
void Findtpcborders(const art::Event &evt)
MultiEMShowers(fhicl::ParameterSet const &p)
const TVector3 & Direction() const
Definition: Shower.h:189
Declaration of signal hit object.
pdgs p
Definition: selectors.fcl:22
const std::vector< double > & dEdx() const
Definition: Shower.h:203
Geometry information for a single TPC.
Definition: TPCGeo.h:38
void analyze(art::Event const &e) override
bool convCluster(art::Event const &evt)
TVector2 WireDriftToCm(detinfo::DetectorPropertiesData const &detProp, unsigned int wire, float drift, unsigned int plane, unsigned int tpc, unsigned int cryo)
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
bool const & IsCompton() const
double GetMomGamma2() const
double GetMompi0() const
while getopts h
double getMinDist(detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &v, TVector3 const &convmc, size_t view, size_t tpc, size_t cryo)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
TVector3 const & GetPosgamma1() const
int GetNgammas() const
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
Declaration of cluster object.
TVector3 const & GetPrimary() const
TVector3 const & GetDirgamma1() const
Provides recob::Track data product.
TVector3 const & GetPospi0() const
double GetMomGamma1() const
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
MCinfo(const art::Event &evt)
TVector2 GetProjectionToPlane(const TVector3 &p, unsigned int plane, unsigned int tpc, unsigned int cryo)
do i e
bool const & IsInside1() const
const TVector3 & ShowerStart() const
Definition: Shower.h:192
art::ServiceHandle< art::TFileService > tfs
TCEvent evt
Definition: DataStructs.cxx:8
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
void Info(const art::Event &evt)
TVector3 const & GetPosgamma2() const
art framework interface to geometry description
auto const detProp
bool insideFidVol(const TLorentzVector &pvtx) const