LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
MergeEMShower3D_module.cc
Go to the documentation of this file.
1 // Class: MergeEMShower3D
3 // Module Type: producer
4 // File: MergeEMShower3D_module.cc
5 // Authors: dorota.stefan@cern.ch robert.sulej@cern.ch
7 
15 #include "fhiclcpp/ParameterSet.h"
20 
22 
30 
35 
36 #include <memory>
37 
39 
40 // ROOT includes
41 #include "TTree.h"
42 #include "TLorentzVector.h"
43 #include "TMathBase.h"
44 
45 namespace ems
46 {
47  class MergeEMShower3D;
48  class ShowerInfo;
49  class bDistLess;
50  class ShowersCollection;
51 }
52 
54 {
55  public:
56  ShowerInfo(int key, int gid, bool hasvtx, std::vector<double> vensum, recob::Track const& trk);
57  double Pointsto(ems::ShowerInfo const& s1) const;
58  double Angleto(TVector3 const& pmapoint) const;
59 
60  bool HasConPoint(void) const {return fHasVtx;}
61  int GetKey(void) const {return fKey;}
62  int GetGid(void) const {return fGId;}
63  int GetPlaneId(void) const {return fPlaneId;}
64  double GetAdcSum(void) const {return fAdcSum;}
65  std::vector<double> GetEnTot(void) const {return fVentot; }
66 
67  TVector3 GetFront(void) const {return fFront;}
68  TVector3 GetEnd(void) const {return fEnd;}
69  TVector3 GetDir(void) const {return fDir;}
70  std::vector<double> GetDedx(void) const { return fVdqdx; }
71 
72  double GetP0Dist(void) const { return fP0Dist; }
73  void SetP0Dist(const TVector3 p)
74  {
75  if (fHasVtx) fP0Dist = std::sqrt( pma::Dist2(p, fFront) );
76  else fP0Dist = std::sqrt( pma::Dist2(p, 0.5 * (fFront + fEnd)) );
77  }
78 
79  private:
80  int fKey;
81  int fGId;
82  int fPlaneId;
83  bool fHasVtx;
84  double fAdcSum;
85  std::vector<double> fVentot;
86  double fP0Dist;
87 
88  TVector3 fFront;
89  TVector3 fEnd;
90  TVector3 fDir;
91 
92  std::vector<double> fVdqdx;
93 
94 };
95 
96 ems::ShowerInfo::ShowerInfo(int key, int gid, bool hasvtx, std::vector<double> vensum, recob::Track const& trk) :
97 fKey(key),
98 fGId(gid),
99 fVentot(vensum),
100 fP0Dist(0)
101 {
102  fDir = trk.VertexDirection<TVector3>();
103  fFront = trk.Vertex<TVector3>();
104  fEnd = trk.End<TVector3>();
105  fHasVtx = hasvtx;
106 
108  /*fVdqdx.push_back(trk.DQdxAtPoint(0, geo::kU));
109  fVdqdx.push_back(trk.DQdxAtPoint(0, geo::kV));
110  fVdqdx.push_back(trk.DQdxAtPoint(0, geo::kZ));*/
111 
112 
113  /*************************************************************/
114  /* WARNING */
115  /*************************************************************/
116  /* The dQdx information in recob::Track has been deprecated */
117  /* since 2016 and in 11/2018 the recob::Track interface was */
118  /* changed and DQdxAtPoint and NumberdQdx were removed. */
119  /* Therefore the code below is now commented out */
120  /* (note that it was most likely not functional anyways). */
121  /* For any issue please contact: larsoft-team@fnal.gov */
122  /*************************************************************/
123  /*
124  bool isplane = false;
125  unsigned int nplanes = geom->Nplanes();
126  for (unsigned int p = 0; p < nplanes; ++p)
127  {
128  geo::View_t view = geom->View(p);
129  fVdqdx.push_back(trk.DQdxAtPoint(0, view));
130  if (trk.DQdxAtPoint(1, view) > 0)
131  {fPlaneId = int(p); isplane = true;}
132  }
133  if (!isplane) fPlaneId = -1;
134  */
135  /*************************************************************/
136 
137  /*if (trk.DQdxAtPoint(1, geo::kU) > 0) fPlaneId = geo::kU;
138  else if (trk.DQdxAtPoint(1, geo::kV) > 0) fPlaneId = geo::kV;
139  else if (trk.DQdxAtPoint(1, geo::kZ) > 0) fPlaneId = geo::kZ;
140  else fPlaneId = -1;*/
141 }
142 
144 {
145  double cosine0 = (this->fFront - s1.fFront) * (1.0 / (this->fFront - s1.fFront).Mag()) * s1.fDir;
146  double th0 = 180.0F * (std::acos(cosine0)) / TMath::Pi();
147 
148  std::vector< std::pair<TVector3, TVector3> > lines;
149  lines.push_back(std::pair<TVector3, TVector3>(this->fFront, this->fFront + this->fDir));
150  lines.push_back(std::pair<TVector3, TVector3>(s1.fFront, s1.fFront + s1.fDir));
151 
152  TVector3 isect, pm;
153  pma::SolveLeastSquares3D(lines, isect);
154  pm = pma::GetProjectionToSegment(isect, this->fFront, this->fFront + this->fDir);
155  double cosine1 = (pm - s1.fFront) * (1.0/(pm - s1.fFront).Mag()) * s1.fDir;
156  double th1 = 180.0F * (std::acos(cosine1)) / TMath::Pi();
157 
158  double thmin = th0;
159  if (th1 < th0) thmin = th1;
160 
161  return thmin;
162 }
163 
164 double ems::ShowerInfo::Angleto(TVector3 const& pmapoint) const
165 {
166  double cosine = (pmapoint - this->fFront) * (1.0 / (pmapoint - this->fFront).Mag()) * this->fDir;
167  double th = 180.0F * (std::acos(cosine)) / TMath::Pi();
168 
169  return th;
170 }
171 
173  public std::binary_function<const ems::ShowerInfo&, const ems::ShowerInfo&, bool>
174 {
175  public:
176  bool operator() (const ems::ShowerInfo& s1, const ems::ShowerInfo& s2)
177  {
178  return (s1.GetP0Dist() < s2.GetP0Dist());
179  }
180 };
181 
183 {
184  public:
186 
187  double MinAngle(ShowersCollection const& col2);
188  void Merge(ShowersCollection const& col2);
189  void Merge(ShowerInfo const& src);
190 
191  double Angle(TVector3 p0, TVector3 test);
192 
193  double Angle(TVector3 test);
194 
195  size_t Size() {return fParts.size();}
196 
197  std::vector< ShowerInfo > const & GetParts(void) const { return fParts; }
198 
199  bool IsClean() {return Clean;}
200 
201  int PlaneId();
202  TVector3 Front();
203  TVector3 Dir();
204  std::vector<double> DeDx(void);
205  std::vector<double> TotEn(void);
206 
208 
209  private:
210  bool Clean;
211  int GId;
212  std::vector< ShowerInfo > fParts;
213 };
214 
216 first(part)
217 {
218  Clean = true;
219  GId = part.GetGid();
220  if (GId == 9999)
221  Clean = false;
222 
223  fParts.push_back(part);
224 }
225 
227 {
228  if (fParts.size()) return fParts.front().GetPlaneId();
229  else return 0;
230 }
231 
233 {
234  if (fParts.size()) return fParts.front().GetFront();
235  else return TVector3(0, 0, 0);
236 }
237 
239 {
240  if (fParts.size()) return fParts.front().GetDir();
241  else return TVector3(0, 0, 0);
242 }
243 
244 std::vector<double> ems::ShowersCollection::DeDx()
245 {
246  if (fParts.size()) return fParts.front().GetDedx();
247  else return std::vector<double>(0.0);
248 }
249 
250 std::vector<double> ems::ShowersCollection::TotEn()
251 {
252  std::vector<double> en;
253 
254  double enkU = 0.0; double enkV = 0.0; double enkZ = 0.0;
255  for (size_t i = 0; i < fParts.size(); ++i)
256  {
257  std::vector<double> showeren = fParts[i].GetEnTot();
258  enkU += showeren[0];
259  enkV += showeren[1];
260  enkZ += showeren[2];
261  }
262 
263  en.push_back(enkU);
264  en.push_back(enkV);
265  en.push_back(enkZ);
266 
267  return en;
268 }
269 
270 double ems::ShowersCollection::Angle(TVector3 p0, TVector3 test)
271 {
272  p0 = Front() - p0;
273  p0 *= 1.0 / p0.Mag();
274  test -= Front();
275  test *= 1.0 / test.Mag();
276  double c = p0 * test;
277  if (c > 1.0) c = 1.0;
278  return 180.0 * acos(c) / TMath::Pi();
279 }
280 
282 {
283  test -= Front();
284  test *= 1.0 / test.Mag();
285  double c = Dir() * test;
286  if (c > 1.0) c = 1.0;
287  return 180.0 * acos(c) / TMath::Pi();
288 }
289 
290 
292 {
293  double a, a_min = 360.0;
294  for (size_t i = 0; i < fParts.size(); ++i)
295  {
296  const ShowerInfo& temp = fParts[i];
297  a = col2.first.Pointsto(temp);
298  if (a < a_min) a_min = a;
299  }
300  return a_min;
301 }
302 
304 {
305  for (size_t i = 0; i < col2.fParts.size(); ++i)
306  for (size_t j = 0; j < fParts.size(); ++j)
307  if (fParts[j].GetGid() != col2.fParts[i].GetGid())
308  {
309  Clean = false;
310  break;
311  }
312 
313  for (size_t i = 0; i < col2.fParts.size(); ++i)
314  fParts.push_back(col2.fParts[i]);
315 
316 }
317 
319 {
320  if (fParts.size())
321  {
322  for (auto const & p : fParts)
323  if (p.GetGid() != src.GetGid())
324  {
325  Clean = false;
326  break;
327  }
328  }
329  else
330  {
331  Clean = true;
332  GId = src.GetGid();
333  }
334  fParts.push_back(src);
335 }
336 
338 public:
339  explicit MergeEMShower3D(fhicl::ParameterSet const & p);
340 
341  MergeEMShower3D(MergeEMShower3D const &) = delete;
342  MergeEMShower3D(MergeEMShower3D &&) = delete;
343  MergeEMShower3D & operator = (MergeEMShower3D const &) = delete;
344  MergeEMShower3D & operator = (MergeEMShower3D &&) = delete;
345 
346  void beginJob() override;
347 
348  void produce(art::Event & e) override;
349 
350  void reconfigure(fhicl::ParameterSet const& p);
351 
352  void mcinfo(art::Event & evt);
353 
354  int getClusterBestId(const std::vector< art::Ptr<recob::Hit> >& v);
355 
356  int getGammaId(art::Event & evt, const size_t t);
357 
358  double getCos3D(const TVector3& p0, const recob::Track& trk);
359 
360  double getClusterAdcSum(const std::vector< art::Ptr<recob::Hit> >& v);
361 
362  std::vector< ems::ShowersCollection > collectshowers(art::Event & evt, std::vector< ems::ShowerInfo > & showers, bool refpoint);
363 
364  TVector3 getBestPoint(
365  const std::vector<recob::Track>& tracks,
366  const std::vector< ShowerInfo >& showers,
367  const TVector3& p0, const TVector3& p1,
368  double step);
369 
370 private:
371 
372  TTree* fEvTree;
373 // TTree* fClTree;
374 
376 
377  int fNParts[2];
378  int fNPMA; int fNConv; int fNTot;
379 // int fHasConvPt;
380  int fWhat, fEvWhat;
381  int fNMerged, fNCleanMerged;
382 
384  double fMcMom /*, fTrkLen *//*, fAdcSum */;
386 
387  TVector3 fPi0vtx;
388  TVector3 fRefPoint;
389 
390  std::string fHitsModuleLabel;
391  std::string fCluModuleLabel;
392  std::string fTrk3DModuleLabel;
393  std::string fVtxModuleLabel;
394 
397 
399 
400 };
401 
403  : fShowerEnergyAlg(p.get<fhicl::ParameterSet>("ShowerEnergyAlg"))
404 {
405  reconfigure(p);
406 
407  produces< std::vector<recob::Shower> >();
408  produces< std::vector<recob::Vertex> >();
409 
410  produces< art::Assns<recob::Shower, recob::Vertex> >();
411  produces< art::Assns<recob::Shower, recob::Cluster> >();
412  produces< art::Assns<recob::Shower, recob::Hit> >();
413 }
414 
416 {
418 
419  fEvTree = tfs->make<TTree>("ShowerTestEv", "pi0 tests");
420  fEvTree->Branch("fEvNumber", &fEvNumber, "fEvNumber/I");
421  fEvTree->Branch("fNPartsA", &fNParts[0], "fNPartsA/I");
422  fEvTree->Branch("fNPartsB", &fNParts[1], "fNPartsB/I");
423  fEvTree->Branch("fNTot", &fNTot, "fNTot/I");
424  fEvTree->Branch("fNPMA", &fNPMA, "fNPMA/I");
425  fEvTree->Branch("fNConv", &fNConv, "fNConv/I");
426  fEvTree->Branch("fEvWhat", &fEvWhat, "fEvWhat/I");
427  fEvTree->Branch("fMcMom", &fMcMom, "fMcMom/D");
428 
429  fEvTree->Branch("fDistvtxmcreco", &fDistvtxmcreco, "fDistvtxmcreco/D");
430  fEvTree->Branch("fNMerged", &fNMerged, "fNMerged/I");
431  fEvTree->Branch("fNCleanMerged", &fNCleanMerged, "fNCleanMerged/I");
432 }
433 
435 {
436  fHitsModuleLabel = p.get< std::string >("HitsModuleLabel");
437  fCluModuleLabel = p.get< std::string >("ClustersModuleLabel");
438  fTrk3DModuleLabel = p.get< std::string >("Trk3DModuleLabel");
439  fVtxModuleLabel = p.get< std::string >("VtxModuleLabel");
440 
441  fNarrowConeAngle = p.get< double >("NarrowConeAngle");
442  fWideConeAngle = p.get< double >("WideConeAngle");
443 
444  return;
445 }
446 
448 {
449  std::unique_ptr< std::vector< recob::Shower > > cascades(new std::vector< recob::Shower >);
450  std::unique_ptr< std::vector< recob::Vertex > > vertices(new std::vector< recob::Vertex >);
451 
452  std::unique_ptr< art::Assns< recob::Shower, recob::Vertex > > shs2vtx(new art::Assns< recob::Shower, recob::Vertex >);
453  std::unique_ptr< art::Assns< recob::Shower, recob::Cluster > > shs2cl(new art::Assns< recob::Shower, recob::Cluster >);
454  std::unique_ptr< art::Assns< recob::Shower, recob::Hit > > shs2hit(new art::Assns< recob::Shower, recob::Hit >);
455 
456  std::vector< ShowersCollection > gammawithconv;
457 
461  art::Handle< std::vector<recob::Hit> > hitListHandle;
462  if (evt.getByLabel(fTrk3DModuleLabel, trkListHandle) &&
463  evt.getByLabel(fVtxModuleLabel, vtxListHandle) &&
464  evt.getByLabel(fCluModuleLabel, cluListHandle) &&
465  evt.getByLabel(fHitsModuleLabel, hitListHandle))
466  {
467 
468  fEvNumber = evt.id().event();
469  fNMerged = 0; fNCleanMerged = 0; fNParts[0] = 0; fNParts[1] = 0;
470  fNPMA = 0; fNConv = 0; fNTot = 0; fMcMom = 0; fWhat = 0;
471  fDistvtxmcreco = -10.0;
472 
473  art::FindManyP< recob::Cluster > cluFromTrk(trkListHandle, evt, fTrk3DModuleLabel);
474  art::FindManyP< recob::Vertex > vtxFromTrk(trkListHandle, evt, fVtxModuleLabel);
475  art::FindManyP< recob::Hit > hitFromClu(cluListHandle, evt, fCluModuleLabel);
476 
477  // all reconstructed shower fragments
478  std::vector< ShowerInfo > showers;
479  for (size_t t = 0; t < trkListHandle->size(); ++t)
480  {
481  const recob::Track& trk = (*trkListHandle)[t];
482 
483  auto src_clu_list = cluFromTrk.at(t);
484  double adcsum = 0.0;
485  std::vector<double> ensum(3, 0.0);
486 
487  for (size_t c = 0; c < src_clu_list.size(); ++c)
488  {
489  std::vector< art::Ptr<recob::Hit> > v = hitFromClu.at(src_clu_list[c].key());
490  adcsum += getClusterAdcSum(v);
491 
492  if (src_clu_list[c]->View() == geo::kU) { ensum[0] += adcsum; }
493  else if (src_clu_list[c]->View() == geo::kV) { ensum[1] += adcsum; }
494  else if (src_clu_list[c]->View() == geo::kZ) { ensum[2] += adcsum; }
495  }
496 
497  auto cnv = vtxFromTrk.at(t);
498  if (cnv.size())
499  {
500  int gid = getGammaId(evt, t);
501  ShowerInfo si(t, gid, true, ensum, trk);
502  showers.push_back(si);
503  }
504  else
505  {
506  int gid = getGammaId(evt, t);
507  ShowerInfo si(t, gid, false, ensum, trk);
508  showers.push_back(si);
509  }
510  }
511 
512  fNTot = showers.size();
513 
515  gammawithconv = collectshowers(evt, showers, true); // true switches on refpoint
516 
517  // with pma segments reconstructed
518  // procceed with pma segments when two conversions
519  std::vector< ShowerInfo > pmaseg;
520  for (size_t i = 0; i < showers.size(); ++i)
521  if (!showers[i].HasConPoint())
522  pmaseg.push_back(showers[i]);
523 
524  fNPMA = pmaseg.size();
525 
526  const double bigcone = fWideConeAngle; // degree.
527 
528  if (gammawithconv.size())
529  for (size_t i = 0; i < pmaseg.size(); i++)
530  {
531  double a_min = bigcone; size_t best = 0;
532  for (size_t j = 0; j < gammawithconv.size(); j++)
533  {
534  TVector3 halfpoint = (pmaseg[i].GetFront() + pmaseg[i].GetEnd()) * 0.5;
535  double a = gammawithconv[j].first.Angleto(halfpoint);
536  if (a < a_min)
537  {
538  a_min = a; best = j;
539  }
540  }
541  if (a_min < bigcone)
542  gammawithconv[best].Merge(pmaseg[i]);
543  }
544 
545  mcinfo(evt);
546 
547 
548  for (size_t i = 0; i < gammawithconv.size(); ++i)
549  if (gammawithconv[i].IsClean()) fNCleanMerged++;
550 
551  fNMerged = gammawithconv.size();
552  if (gammawithconv.size() == 2)
553  {
554  fNParts[0] = gammawithconv[0].Size();
555  fNParts[1] = gammawithconv[1].Size();
556  }
557 
558  fDistvtxmcreco = std::sqrt(pma::Dist2(fRefPoint, fPi0vtx));
559  fEvTree->Fill();
560 
561  fVtxIndex = 0;
562  for (size_t i = 0; i < gammawithconv.size(); ++i)
563  {
564  int id = i;
565  TVector3 v0(0., 0., 0.);
566  TVector3 dir = gammawithconv[i].Dir();
567  TVector3 front = gammawithconv[i].Front();
568 
569  std::vector<double> dedx = gammawithconv[i].DeDx();
570  std::vector< double > vd;
571  recob::Shower cas(
572  dir, v0, front, v0,
573  vd, vd, dedx, vd, gammawithconv[i].PlaneId(), id);
574 
575 
576  std::vector< art::Ptr<recob::Cluster> > cls;
577  std::vector< art::Ptr<recob::Hit> > hits;
578  for (size_t p = 0; p < gammawithconv[i].Size(); p++)
579  {
580  int trkKey = gammawithconv[i].GetParts()[p].GetKey();
581  auto src_clu_list = cluFromTrk.at(trkKey);
582 
583  for (size_t c = 0; c < src_clu_list.size(); c++)
584  {
585  cls.push_back(src_clu_list[c]);
586 
587  auto v = hitFromClu.at(src_clu_list[c].key());
588  for (size_t h = 0; h < v.size(); h++) hits.push_back(v[h]);
589  }
590 
591  auto ver_list = vtxFromTrk.at(trkKey);
592  }
593 
594  std::vector<double> totE;
595  std::vector<double> totEerr;
596  for (int i = 0; i<3; ++i){
597  totE.push_back(fShowerEnergyAlg.ShowerEnergy(hits,i));
598  totEerr.push_back(0);
599  }
600  cas.set_total_energy(totE);
601  cas.set_total_energy_err(totEerr);
602  cascades->push_back(cas);
603 
604  double vtx_pos[3] = {front.X(), front.Y(), front.Z()};
605  vertices->push_back(recob::Vertex(vtx_pos, fVtxIndex));
606  fVtxIndex++;
607 
608  if (vertices->size())
609  {
610  size_t vtx_idx = (size_t)(vertices->size() - 1);
611  util::CreateAssn(*this, evt, *cascades, *vertices, *shs2vtx, vtx_idx, vtx_idx + 1);
612  }
613 
614  util::CreateAssn(*this, evt, *cascades, cls, *shs2cl);
615  util::CreateAssn(*this, evt, *cascades, hits, *shs2hit);
616 
617  }
618 
619  }
620 
621  evt.put(std::move(cascades));
622  evt.put(std::move(vertices));
623 
624  evt.put(std::move(shs2vtx));
625  evt.put(std::move(shs2cl));
626  evt.put(std::move(shs2hit));
627 }
628 
629 std::vector< ems::ShowersCollection > ems::MergeEMShower3D::collectshowers(art::Event & evt, std::vector< ems::ShowerInfo > & showers, bool refpoint)
630 {
631  std::vector< ems::ShowersCollection > gammawithconv;
632 
633  const double smallcone = fNarrowConeAngle; // degree.
634  bool merge = true;
635  if (refpoint)
636  {
639  if (evt.getByLabel(fTrk3DModuleLabel, trkListHandle))
640  {
641  double dsize[6];
642  geom->CryostatBoundaries(dsize, 0);
643  TVector3 geoP0(dsize[0], dsize[2], dsize[4]), geoP1(dsize[1], dsize[3], dsize[5]);
644  TVector3 pov = getBestPoint(*trkListHandle, showers, geoP0, geoP1, 5.0);
645  fRefPoint = pov;
646 
647  for (size_t is = 0; is < showers.size(); is++)
648  showers[is].SetP0Dist(pov);
649  std::sort(showers.begin(), showers.end(), ems::bDistLess());
650 
651  for (size_t is = 0; is < showers.size(); is++)
652  {
653  size_t m_idx = 0;
654  double a, a_min = 360.0;
655  for (size_t m = 0; m < gammawithconv.size(); ++m)
656  {
657  a = gammawithconv[m].Angle(showers[is].GetFront());
658  if ((a < fNarrowConeAngle) && (a < a_min))
659  {
660  m_idx = m; a_min = a;
661  }
662 
663  std::vector< std::pair<TVector3, TVector3> > lines;
664  lines.push_back(std::pair<TVector3, TVector3>(
665  showers[is].GetFront(), showers[is].GetFront() + showers[is].GetDir()));
666  lines.push_back(std::pair<TVector3, TVector3>(
667  gammawithconv[m].Front(), gammawithconv[m].Front() + gammawithconv[m].Dir()));
668 
669  TVector3 isect, pm;
670  pma::SolveLeastSquares3D(lines, isect);
671  pm = pma::GetProjectionToSegment(isect,
672  gammawithconv[m].Front(), gammawithconv[m].Front() + gammawithconv[m].Dir());
673 
674  if (pma::Dist2(pov, gammawithconv[m].Front()) < pma::Dist2(pov, pm))
675  {
676  a = gammawithconv[m].Angle(isect);
677  if ((a < fNarrowConeAngle) && (a < a_min))
678  {
679  m_idx = m; a_min = a;
680  }
681  }
682  }
683  if (a_min < fNarrowConeAngle)
684  {
685  gammawithconv[m_idx].Merge(showers[is]);
686  }
687  else if (showers[is].HasConPoint())
688  {
689  ems::ShowersCollection sc(showers[is]);
690  gammawithconv.push_back(sc);
691  }
692 
693  }
694  }
695  }
696  else
697  {
698  for (size_t i = 0; i < showers.size(); ++i)
699  if (showers[i].HasConPoint())
700  {
701  ems::ShowersCollection sc(showers[i]);
702  gammawithconv.push_back(sc);
703  }
704 
705  fNConv = gammawithconv.size();
706  while (merge)
707  {
708  merge = false;
709  size_t i = 0;
710  while (i < gammawithconv.size())
711  {
712  size_t best = 0; double a_min = smallcone;
713  for (size_t j = 0; j < gammawithconv.size(); j++)
714  if (i != j)
715  {
716  double a = gammawithconv[i].MinAngle(gammawithconv[j]);
717  if (a < a_min)
718  {
719  a_min = a; best = j; merge = true;
720  }
721  }
722  if (merge)
723  {
724  gammawithconv[i].Merge(gammawithconv[best]);
725  gammawithconv.erase(gammawithconv.begin() + best);
726  break;
727  }
728  i++;
729  }
730  }
731  }
732  return gammawithconv;
733 }
734 
735 
737 {
739 
740  std::map< int, size_t > ids;
741  for (auto ptr : v)
742  {
743  auto hid = bt_serv->HitToTrackIDEs(ptr);
744  if (hid.size()) ids[hid.front().trackID]++;
745  }
746 
747  int best_id = 9999;
748  size_t max = 0;
749  for (auto p : ids)
750  {
751  if ((p.second > (int)(0.8 * v.size())) && (p.second > max))
752  {
753  max = p.second; best_id = p.first;
754  }
755  }
756 
757  return best_id;
758 }
759 
761 {
762  int pi0_idx = -1;
763 
764  art::Handle< std::vector<simb::MCTruth> > mctruthListHandle;
765  std::vector< art::Ptr<simb::MCTruth> > mclist;
766  if (evt.getByLabel("generator", mctruthListHandle))
767  {
768  art::fill_ptr_vector(mclist, mctruthListHandle);
769  if (mclist.size())
770  {
771  size_t np = mclist[0]->NParticles();
772  for (size_t i = 0; i < np; ++i)
773  if (mclist[0]->GetParticle(i).PdgCode() == 111)
774  {pi0_idx = i; break;}
775  }
776  }
777 
778  if (pi0_idx < 0) return;
779 
780  const simb::MCParticle & pi0 = mclist[0]->GetParticle(pi0_idx);
781  TVector3 pi0_vtx(pi0.Vx(), pi0.Vy(), pi0.Vz());
782  fPi0vtx = pi0_vtx;
783  fMcMom = pi0.P();
784 }
785 
787 {
788  fWhat = 0;
789  int cid = 0, gid = 0;
793  art::Handle< std::vector<recob::Hit> > hitListHandle;
794  if (evt.getByLabel(fTrk3DModuleLabel, trkListHandle) &&
795  evt.getByLabel(fVtxModuleLabel, vtxListHandle) &&
796  evt.getByLabel(fCluModuleLabel, cluListHandle) &&
797  evt.getByLabel(fHitsModuleLabel, hitListHandle))
798  {
799  art::FindManyP< recob::Cluster > cluFromTrk(trkListHandle, evt, fTrk3DModuleLabel);
800  art::FindManyP< recob::Vertex > vtxFromTrk(trkListHandle, evt, fVtxModuleLabel);
801  art::FindManyP< recob::Hit > hitFromClu(cluListHandle, evt, fCluModuleLabel);
802 
803  auto src_clu_list = cluFromTrk.at(t);
804  for (size_t c = 0; c < src_clu_list.size(); ++c)
805  {
806  std::vector< art::Ptr<recob::Hit> > v = hitFromClu.at(src_clu_list[c].key());
807  cid = getClusterBestId(v);
808 
809  if ((fWhat == 0) && (cid == 9999)) fWhat = 1; // confused 2D
810  if ((fWhat == 0) && (gid == 0)) gid = cid;
811  if ((fWhat == 0) && (cid != gid)) fWhat = 2; // confused 3D
812  }
813  }
814 
815  if (fWhat == 0) return gid;
816  else return 9999;
817 }
818 
820  const std::vector< recob::Track >& tracks,
821  const std::vector< ShowerInfo >& showers,
822  const TVector3& p0, const TVector3& p1, double step)
823 {
824  TVector3 best, p;
825 
826  double f, fmin = 1.0e10;
827 
828  double dx = step;
829  double dy = step;
830  double dz = step;
831 
832  double x0 = p0.X();
833  while (x0 < p1.X())
834  {
835  double y0 = p0.Y();
836  while (y0 < p1.Y())
837  {
838  double z0 = p0.Z();
839  while (z0 < p1.Z())
840  {
841  f = 0.0;
842  //size_t nOK = 0;
843  TVector3 mid(0., 0., 0.);
844 
845  p.SetXYZ(x0, y0, z0);
846  for (size_t t = 0; t < tracks.size(); t++)
847  // if (showers[t].OK)
848  {
849  auto const & trk = tracks[t];
850 
851  double cos = -acos( getCos3D(p, trk) ) / (0.5*TMath::Pi());
852  //double cos = getCos3D(p, trk);
853 
854  if (showers[t].HasConPoint()) cos *= 3.0;
855  cos *= sqrt( showers[t].GetAdcSum() );
856 
857  mid += 0.5 * (trk.Vertex<TVector3>() + trk.End<TVector3>());
858 
859  f += cos;
860  // nOK++;
861  }
862  //if (!nOK) return best;
863 
864  // f /= nOK;
865  // mid *= 1.0 / nOK;
866 
867  f = -f + 0.0001 * sqrt(pma::Dist2(p, mid));
868  if (f < fmin)
869  {
870  fmin = f; best = p;
871  }
872 
873  z0 += dz;
874  }
875  y0 += dy;
876  }
877  x0 += dx;
878  }
879  return best;
880 }
881 
882 double ems::MergeEMShower3D::getCos3D(const TVector3& p0, const recob::Track& trk)
883 {
884  TVector3 p1, dir;
885 
886  if (pma::Dist2(p0, trk.Vertex()) < pma::Dist2(p0, trk.End()))
887  p1 = trk.Vertex<TVector3>();
888  else
889  p1 = trk.End<TVector3>();
890 
891  p1 -= p0;
892  double m = p1.Mag();
893  if (m > 0.0)
894  {
895  p1 *= 1.0 / m;
896  double c = fabs(p1 * trk.VertexDirection<TVector3>());
897  if (c > 1.0) c = 1.0;
898  return c;
899  }
900  else return 0.0;
901 }
902 
904 {
905  double sum = 0.0;
906  for (auto ptr : v)
907  {
908  sum += ptr->SummedADC();
909  }
910  return sum;
911 }
912 
double ShowerEnergy(std::vector< art::Ptr< recob::Hit > > const &hits, int plane)
Finds the total energy deposited by the shower in this view.
void reconfigure(fhicl::ParameterSet const &p)
TVector3 GetDir(void) const
Implementation of the Projection Matching Algorithm.
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:19
const std::vector< sim::TrackIDE > HitToTrackIDEs(recob::Hit const &hit)
TVector3 GetEnd(void) const
double Pointsto(ems::ShowerInfo const &s1) const
ShowersCollection(ShowerInfo const &part)
Planes which measure V.
Definition: geo_types.h:77
Declaration of signal hit object.
void set_total_energy(const std::vector< double > &q)
Definition: Shower.h:129
Vector_t VertexDirection() const
Access to track direction at different points.
Definition: Track.h:135
Planes which measure Z direction.
Definition: geo_types.h:79
double GetP0Dist(void) const
shower::ShowerEnergyAlg fShowerEnergyAlg
std::vector< double > fVentot
std::vector< double > GetDedx(void) const
ShowerInfo(int key, int gid, bool hasvtx, std::vector< double > vensum, recob::Track const &trk)
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
void set_total_energy_err(const std::vector< double > &q)
Definition: Shower.h:130
double getCos3D(const TVector3 &p0, const recob::Track &trk)
void CryostatBoundaries(double *boundaries, geo::CryostatID const &cid) const
Returns the boundaries of the specified cryostat.
int getGammaId(art::Event &evt, const size_t t)
TFile f
Definition: plotHisto.C:6
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
int getClusterBestId(const std::vector< art::Ptr< recob::Hit > > &v)
double Angleto(TVector3 const &pmapoint) const
Planes which measure U.
Definition: geo_types.h:76
Int_t max
Definition: plot.C:27
void hits()
Definition: readHits.C:15
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
Provides recob::Track data product.
double MinAngle(ShowersCollection const &col2)
void beginJob()
Definition: Breakpoints.cc:14
TVector2 GetProjectionToSegment(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
Definition: Utilities.cxx:156
parameter set interface
double P(const int i=0) const
Definition: MCParticle.h:238
T get(std::string const &key) const
Definition: ParameterSet.h:231
TString part[npart]
Definition: Style.C:32
Point_t const & Vertex() const
Access to track position at different points.
Definition: Track.h:127
std::vector< ShowerInfo > const & GetParts(void) const
std::vector< ems::ShowersCollection > collectshowers(art::Event &evt, std::vector< ems::ShowerInfo > &showers, bool refpoint)
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
double SolveLeastSquares3D(const std::vector< std::pair< TVector3, TVector3 > > &lines, TVector3 &result)
Definition: Utilities.cxx:176
std::vector< double > DeDx(void)
void mcinfo(art::Event &evt)
double Angle(TVector3 p0, TVector3 test)
Declaration of cluster object.
std::vector< double > fVdqdx
double GetAdcSum(void) const
TVector3 getBestPoint(const std::vector< recob::Track > &tracks, const std::vector< ShowerInfo > &showers, const TVector3 &p0, const TVector3 &p1, double step)
Definition: DirOfGamma.h:18
MergeEMShower3D(fhicl::ParameterSet const &p)
int GetKey(void) const
double Vx(const int i=0) const
Definition: MCParticle.h:225
int GetGid(void) const
Implementation of the Projection Matching Algorithm.
T * make(ARGS...args) const
Utility object to perform functions of association.
int GetPlaneId(void) const
TDirectory * dir
Definition: macro.C:5
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
void Merge(ShowersCollection const &col2)
double Vz(const int i=0) const
Definition: MCParticle.h:227
EventNumber_t event() const
Definition: EventID.h:117
std::vector< ShowerInfo > fParts
Point_t const & End() const
Access to track position at different points.
Definition: Track.h:128
double getClusterAdcSum(const std::vector< art::Ptr< recob::Hit > > &v)
TCEvent evt
Definition: DataStructs.cxx:5
void SetP0Dist(const TVector3 p)
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:464
Float_t e
Definition: plot.C:34
TVector3 GetFront(void) const
std::vector< double > TotEn(void)
bool HasConPoint(void) const
EventID id() const
Definition: Event.h:56
double Vy(const int i=0) const
Definition: MCParticle.h:226
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:52
std::vector< double > GetEnTot(void) const
void produce(art::Event &e) override