42 #include "TLorentzVector.h" 43 #include "TMathBase.h" 57 std::vector< art::Ptr< recob::Hit > >
hits1;
58 std::vector< art::Ptr< recob::Hit > >
hits2;
59 std::vector< art::Ptr< recob::Hit > >
hits3;
88 std::vector< ems::DirOfGamma* > CollectShower2D(
art::Event const & e);
90 void Link(
art::Event const & e, std::vector< ems::DirOfGamma* > input);
95 void Make3DSeg(
art::Event const & e, std::vector< ems::DirOfGamma* > pair);
98 bool Validate(std::vector< ems::DirOfGamma* > input,
size_t id1,
size_t id2,
size_t c1,
size_t c2,
size_t plane3);
100 void FilterOutSmallParts(
108 std::vector<size_t>& used,
111 bool Has(
const std::vector<size_t>& v,
size_t idx);
113 size_t LinkCandidates(
art::Event const & e, std::vector< ems::DirOfGamma* > input,
size_t id);
119 std::vector< std::vector< art::Ptr<recob::Hit> > >
fClusters;
138 : fProjectionMatchingAlg(p.get<
fhicl::ParameterSet >(
"ProjectionMatchingAlg")),
139 fCalorimetryAlg(p.get<
fhicl::ParameterSet >(
"CalorimetryAlg"))
143 produces< std::vector<recob::Track> >();
144 produces< std::vector<recob::Vertex> >();
145 produces< std::vector<recob::Cluster> >();
146 produces< std::vector<recob::SpacePoint> >();
147 produces< art::Assns<recob::Track, recob::Hit> >();
148 produces< art::Assns<recob::Track, recob::Vertex> >();
149 produces< art::Assns<recob::Cluster, recob::Hit> >();
150 produces< art::Assns<recob::Track, recob::SpacePoint> >();
151 produces< art::Assns<recob::SpacePoint, recob::Hit> >();
152 produces< art::Assns<recob::Track, recob::Cluster> >();
171 return recob::Cluster(0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, src.size(), 0.0F, 0.0F,
fClIndex, src[0]->View(), src[0]->WireID().planeID());
176 auto const* geom = lar::providerFrom<geo::Geometry>();
177 auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
181 size_t nusedhitsmax = 0;
int bestplane = -1;
182 for (
unsigned int p = 0; p < nplanes; ++p)
184 unsigned int nusedP = 0;
187 if (nusedP > nusedhitsmax)
189 nusedhitsmax = nusedP;
194 std::vector< std::vector< double > > vdedx;
195 std::vector< double > dedx;
197 for (
unsigned int p = 0; p < nplanes; ++p)
199 unsigned int nusedP = 0;
201 double timeP = detprop->ConvertXToTicks(avdrift,
206 dedx.push_back(dEdxplane);
207 if (
int(p) == bestplane) dedx.push_back(1);
208 else dedx.push_back(0);
209 vdedx.push_back(dedx);
212 std::vector< TVector3 > xyz, dircos;
214 for (
size_t i = 0; i < src.
size(); i++)
216 xyz.push_back(src[i]->
Point3D());
218 if (i < src.
size() - 1)
220 TVector3 dc(src[i + 1]->
Point3D());
221 dc -= src[i]->Point3D();
222 dc *= 1.0 / dc.Mag();
223 dircos.push_back(dc);
225 else dircos.push_back(dircos.back());
234 auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
235 auto const* geom = lar::providerFrom<geo::Geometry>();
239 size_t nusedhitsmax = 0;
int bestplane = -1;
240 for (
unsigned int p = 0; p < nplanes; ++p)
242 unsigned int nusedP = 0;
245 if (nusedP > nusedhitsmax)
247 nusedhitsmax = nusedP;
252 std::vector< std::vector< double > > vdedx;
253 std::vector< double > dedx;
255 for (
unsigned int p = 0; p < nplanes; ++p)
257 unsigned int nusedP = 0;
259 double timeP = detprop->ConvertXToTicks(avdrift,
264 dedx.push_back(dEdxplane);
265 if (
int(p) == bestplane) dedx.push_back(1);
266 else dedx.push_back(0);
267 vdedx.push_back(dedx);
270 std::vector< TVector3 > xyz, dircos;
272 for (
size_t i = 0; i < src.
size(); i++)
274 xyz.push_back(src[i]->
Point3D());
276 if (i < src.
size() - 1)
278 TVector3 dc(src[i + 1]->
Point3D());
279 dc -= src[i]->Point3D();
280 dc *= 1.0 / dc.Mag();
281 dircos.push_back(dc);
283 else dircos.push_back(dircos.back());
298 std::unique_ptr< std::vector< recob::Track > > tracks(
new std::vector< recob::Track >);
299 std::unique_ptr< std::vector< recob::Vertex > > vertices(
new std::vector< recob::Vertex >);
300 std::unique_ptr< std::vector< recob::Cluster > > clusters(
new std::vector< recob::Cluster >);
301 std::unique_ptr< std::vector< recob::SpacePoint > > allsp(
new std::vector< recob::SpacePoint >);
319 std::vector< art::Ptr<recob::Hit> > hitlist;
322 if (hitlist.size() > 5)
328 Link(e, showernviews);
340 size_t spStart = 0, spEnd = 0;
341 double sp_pos[3], sp_err[6], vtx_pos[3];
342 for (
size_t i = 0; i < 6; i++) sp_err[i] = 1.0;
350 vtx_pos[0] =
trk.track->front()->Point3D().X();
351 vtx_pos[1] =
trk.track->front()->Point3D().Y();
352 vtx_pos[2] =
trk.track->front()->Point3D().Z();
357 std::vector< art::Ptr< recob::Cluster > > cl2d;
361 std::vector< art::Ptr< recob::Hit > > hits2d;
364 spStart = allsp->size();
365 for (
int h =
trk.track->size() - 1; h >= 0; h--)
371 (sp_pos[0] != h3d->
Point3D().X()) ||
372 (sp_pos[1] != h3d->
Point3D().Y()) ||
373 (sp_pos[2] != h3d->
Point3D().Z()))
380 sp_pos[0] = h3d->
Point3D().X();
381 sp_pos[1] = h3d->
Point3D().Y();
382 sp_pos[2] = h3d->
Point3D().Z();
391 spEnd = allsp->size();
393 if (vertices->size())
395 size_t vtx_idx = (size_t)(vertices->size() - 1);
396 util::CreateAssn(*
this, e, *tracks, *vertices, *trk2vtx, vtx_idx, vtx_idx + 1);
418 std::vector< art::Ptr< recob::Cluster > > cl2d;
422 std::vector< art::Ptr< recob::Hit > > hits2d;
425 spStart = allsp->size();
426 for (
int h =
trk.track->size() - 1; h >= 0; h--)
432 (sp_pos[0] != h3d->
Point3D().X()) ||
433 (sp_pos[1] != h3d->
Point3D().Y()) ||
434 (sp_pos[2] != h3d->
Point3D().Z()))
441 sp_pos[0] = h3d->
Point3D().X();
442 sp_pos[1] = h3d->
Point3D().Y();
443 sp_pos[2] = h3d->
Point3D().Z();
452 spEnd = allsp->size();
479 for (
unsigned int i = 0; i < showernviews.size(); i++)
480 delete showernviews[i];
482 for (
unsigned int i = 0; i < fSeltracks.size(); i++)
483 delete fSeltracks[i].
track;
485 for (
unsigned int i = 0; i <
fInisegs.size(); i++)
488 for (
unsigned int i = 0; i < fPMA3D.size(); i++)
489 delete fPMA3D[i].
track;
493 e.
put(std::move(tracks));
494 e.
put(std::move(vertices));
495 e.
put(std::move(clusters));
496 e.
put(std::move(allsp));
498 e.
put(std::move(trk2hit));
499 e.
put(std::move(trk2vtx));
500 e.
put(std::move(cl2hit));
501 e.
put(std::move(trk2cl));
502 e.
put(std::move(trk2sp));
503 e.
put(std::move(sp2hit));
510 const float min_dist = 3.0F;
518 if (ta == tb) {tb++;
continue;}
520 TVector3 p1 =
fSeltracks[ta].track->front()->Point3D();
521 TVector3 p2 =
fSeltracks[tb].track->front()->Point3D();
530 std::vector< art::Ptr< recob::Hit > > hits3 =
fSeltracks[ta].hits1;
531 std::vector< art::Ptr< recob::Hit > >
hits =
fSeltracks[ta].hits1;
532 for (
size_t h = 0; h <
fSeltracks[ta].hits2.size(); ++h)
538 for (
size_t h = 0; h <
fSeltracks[tb].hits1.size(); ++h)
544 for (
size_t h = 0; h <
fSeltracks[tb].hits2.size(); ++h)
589 std::vector< ems::DirOfGamma* > input;
596 std::vector< art::Ptr<recob::Hit> > hitlist;
599 if (hitlist.size() > 5)
601 std::vector< art::Ptr<recob::Hit> > hits_out;
604 if (hits_out.size() > 5)
622 auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
624 std::vector< std::vector< size_t > > saveids;
625 std::vector< size_t > saveidsnotusedcls;
628 while (i < input.size())
630 if (!input[i]->GetCandidates().size()){i++;
continue;}
632 double mindist = 1.0;
633 std::vector< ems::DirOfGamma* > pairs;
635 size_t startview = input[i]->GetFirstHit()->WireID().Plane;
636 size_t tpc = input[i]->GetFirstHit()->WireID().TPC;
637 size_t cryo = input[i]->GetFirstHit()->WireID().Cryostat;
639 float t1 = detprop->ConvertTicksToX(input[i]->GetFirstHit()->PeakTime(), startview, tpc, cryo);
641 unsigned int idsave = 0;
642 for (
unsigned int j = 0; j < input.size(); j++)
644 if (!input[j]->GetCandidates().size())
continue;
646 size_t secondview = input[j]->GetFirstHit()->WireID().Plane;
647 size_t tpc_j = input[j]->GetFirstHit()->WireID().TPC;
648 size_t cryo_j = input[j]->GetFirstHit()->WireID().Cryostat;
650 if ((i != j) && (secondview != startview) && (tpc == tpc_j) && (cryo == cryo_j))
652 float t2 = detprop->ConvertTicksToX(input[j]->GetFirstHit()->PeakTime(), secondview, tpc_j, cryo_j);
653 float dist = fabs(t2 - t1);
659 pairs.push_back(input[i]); pairs.push_back(input[j]);
667 for (
unsigned int v = 0; v < saveids.size(); v++)
668 if ((saveids[v][0] == i) || (saveids[v][0] == idsave))
669 if ((saveids[v][1] == i) || (saveids[v][1] == idsave))
677 std::vector< size_t > ids;
678 ids.push_back(i); ids.push_back(idsave);
679 saveids.push_back(ids);
683 saveidsnotusedcls.push_back(i);
690 while(i < saveidsnotusedcls.size())
701 size_t index = id;
bool found =
false;
703 if (input[
id]->GetCandidates().size() < 2) {
return index; }
705 double mindist = 3.0;
706 std::vector< ems::DirOfGamma* > pairs;
708 size_t idcsave = 0;
size_t idcjsave = 0;
709 size_t c = 0;
size_t idsave = 0;
710 while (c < input[
id]->GetCandidates().size())
713 size_t startview = input[id]->GetCandidates()[c].GetPlane();
714 size_t tpc = input[id]->GetCandidates()[c].GetTPC();
715 size_t cryo = input[id]->GetCandidates()[c].GetCryo();
717 float t1 = input[id]->GetCandidates()[c].GetPosition().Y();
720 for (
size_t j = 0; j < input.size(); ++j)
722 if (!input[j]->GetCandidates().size())
continue;
723 if (j ==
id)
continue;
726 for (
size_t cj = 0; cj < input[j]->GetCandidates().size(); ++cj)
728 size_t secondview = input[j]->GetCandidates()[cj].GetPlane();
729 size_t tpc_j = input[j]->GetCandidates()[cj].GetTPC();
730 size_t cryo_j = input[j]->GetCandidates()[cj].GetCryo();
732 size_t thirdview = startview;
735 for (
size_t p = 0; p < cryostat.
MaxPlanes(); p++)
736 if ((p == startview) || (p == secondview)) {
continue;}
737 else {thirdview = p;
break;}
740 if ((startview != secondview) && (tpc == tpc_j) && (cryo == cryo_j))
742 float t2 = input[j]->GetCandidates()[cj].GetPosition().Y();
743 float dist = fabs(t2 - t1);
745 if ((dist < mindist) &&
Validate(input,
id, j, c, cj, thirdview))
749 pairs.push_back(input[
id]); pairs.push_back(input[j]);
750 idsave = j; index = j;
751 idcsave = c; idcjsave = cj;
761 if (found && pairs.size())
763 input[id]->SetIdCandidate(idcsave);
764 input[idsave]->SetIdCandidate(idcjsave);
773 if (pair.size() < 2)
return;
776 size_t tpc1 = pair[0]->GetFirstHit()->WireID().TPC;
777 size_t tpc2 = pair[1]->GetFirstHit()->WireID().TPC;
779 std::vector< art::Ptr< recob::Hit > > vec1 = pair[0]->GetIniHits();
780 std::vector< art::Ptr< recob::Hit > > vec2 = pair[1]->GetIniHits();
782 if ((vec1.size() < 3) && (vec2.size() < 3))
return;
784 std::vector< art::Ptr<recob::Hit> > hitscl1uniquetpc;
785 std::vector< art::Ptr<recob::Hit> > hitscl2uniquetpc;
788 for (
size_t i = 0; i < vec1.size(); ++i)
789 for (
size_t j = 0; j < vec2.size(); ++j)
790 if ((vec1[i]->WireID().TPC == vec2[j]->WireID().TPC) && (tpc1 == vec2[j]->WireID().TPC))
792 hitscl1uniquetpc.push_back(vec1[i]);
793 hitscl2uniquetpc.push_back(vec2[j]);
796 if ((hitscl1uniquetpc.size() > 2) && (hitscl2uniquetpc.size() > 2))
808 initrack.
idcl1 = pair[0]->GetIdCl();
809 initrack.
view1 = pair[0]->GetFirstHit()->WireID().Plane;
810 initrack.
hits1 = hitscl1uniquetpc;
811 initrack.
idcl2 = pair[1]->GetIdCl();
812 initrack.
view2 = pair[1]->GetFirstHit()->WireID().Plane;
813 initrack.
hits2 = hitscl2uniquetpc;
814 initrack.
track = trk;
825 if (id1 == id2)
return false;
827 std::vector< art::Ptr< recob::Hit > > vec1 = input[id1]->GetCandidates()[
c1].GetIniHits();
828 std::vector< art::Ptr< recob::Hit > > vec2 = input[id2]->GetCandidates()[
c2].GetIniHits();
830 if ((vec1.size() < 3) || (vec2.size() < 3))
return false;
832 std::vector< art::Ptr<recob::Hit> > hitscl1uniquetpc;
833 std::vector< art::Ptr<recob::Hit> > hitscl2uniquetpc;
835 size_t tpc = vec1[0]->WireID().TPC;
836 for (
size_t i = 0; i < vec1.size(); ++i)
837 for (
size_t j = 0; j < vec2.size(); ++j)
838 if ((vec1[i]->WireID().TPC == tpc) && (vec2[j]->WireID().TPC == tpc))
840 hitscl1uniquetpc.push_back(vec1[i]);
841 hitscl2uniquetpc.push_back(vec2[j]);
844 if ((hitscl1uniquetpc.size() < 3) || (hitscl2uniquetpc.size() < 3))
return false;
847 for (
size_t i = 0; i < input.size(); ++i)
849 std::vector< Hit2D* > hits2dcl = input[i]->GetHits2D();
850 for (
size_t h = 0; h < hits2dcl.size(); ++h)
854 if ( (
pma::Dist2(hits2dcl[h]->GetPointCm(), pfront) < 1.0F) &&
855 (
pma::Dist2(hits2dcl[h]->GetPointCm(), pback) < 1.0F) )
856 {result =
true;
break;}
870 std::vector< art::Ptr<recob::Hit> > hitscl;
874 for (
size_t i = 0; i < hits.size(); i++) hitscl.push_back(hits[i]);
885 for (
auto c : v)
if (c == idx)
return true;
892 std::vector<size_t>& used,
898 const double gapMargin = 5.0;
901 while ((idx < hits_in.size()) &&
Has(used, idx)) idx++;
903 if (idx < hits_in.size())
905 hits_out.push_back(hits_in[idx]);
909 double r2d2 = r2d*r2d;
910 double gapMargin2 = sqrt(2 * gapMargin*gapMargin);
911 gapMargin2 = (gapMargin2 + r2d)*(gapMargin2 + r2d);
917 for (
size_t i = 0; i < hits_in.size(); i++)
925 for (
size_t idx_o = 0; idx_o < hits_out.size(); idx_o++)
934 if (d2 < r2d2) { accept =
true;
break; }
938 if (d2 < gapMargin2) { accept =
true;
break; }
944 hits_out.push_back(hi);
960 size_t min_size = hits_in.size() / 5;
961 if (min_size < 3) min_size = 3;
963 std::vector<size_t> used;
964 std::vector< art::Ptr<recob::Hit> > close_hits;
968 if (close_hits.size() > min_size)
969 for (
auto h : close_hits) hits_out.push_back(h);
size_t LinkCandidates(art::Event const &e, std::vector< ems::DirOfGamma * > input, size_t id)
unsigned int TPC(void) const
void Link(art::Event const &e, std::vector< ems::DirOfGamma * > input)
unsigned int Cryo(void) const
unsigned int MaxPlanes() const
Returns the largest number of planes among the TPCs in this cryostat.
Implementation of the Projection Matching Algorithm.
double Dist2(const TVector2 &v1, const TVector2 &v2)
unsigned int FrontTPC(void) const
double dEdx_AREA(art::Ptr< recob::Hit > hit, double pitch, double T0=0) const
unsigned int BackTPC(void) const
bool Flip(std::vector< pma::Track3D * > &allTracks)
geo::WireID WireID() const
Initial tdc tick for hit.
Declaration of signal hit object.
std::vector< IniSeg > fPMA3D
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
CryostatID_t Cryostat
Index of cryostat.
Set of hits with a 2D structure.
WireID_t Wire
Index of the wire within its plane.
void reconfigure(fhicl::ParameterSet const &p)
Geometry information for a single cryostat.
art::Ptr< recob::Hit > const & Hit2DPtr(void) const
Definition of vertex object for LArSoft.
std::vector< size_t > fClustersNotUsed
ProductID put(std::unique_ptr< PROD > &&product)
art::Handle< std::vector< recob::Cluster > > fCluListHandle
void produce(art::Event &e) override
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
std::vector< size_t > fTracksNotUsed
double selectInitialHits(pma::Track3D &trk, unsigned int view=geo::kZ, unsigned int *nused=0) const
EMShower3D(fhicl::ParameterSet const &p)
#define DEFINE_ART_MODULE(klass)
void push_back(Ptr< U > const &p)
std::string fTrk3DModuleLabel
std::vector< art::Ptr< recob::Hit > > hits3
recob::Track ConvertFrom2(pma::Track3D &src)
unsigned int BackCryo(void) const
T get(std::string const &key) const
pma::Track3D * buildSegment(const std::vector< art::Ptr< recob::Hit > > &hits_1, const std::vector< art::Ptr< recob::Hit > > &hits_2=std::vector< art::Ptr< recob::Hit > >()) const
void FilterOutSmallParts(double r2d, const std::vector< art::Ptr< recob::Hit > > &hits_in, std::vector< art::Ptr< recob::Hit > > &hits_out)
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
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.
PlaneID_t Plane
Index of the plane within its TPC.
Declaration of cluster object.
Provides recob::Track data product.
calo::CalorimetryAlg fCalorimetryAlg
unsigned int FrontCryo(void) const
bool Validate(art::Event const &e, const pma::Track3D &src, size_t plane)
bool GetCloseHits(double r2d, const std::vector< art::Ptr< recob::Hit > > &hits_in, std::vector< size_t > &used, std::vector< art::Ptr< recob::Hit > > &hits_out)
TVector3 const & Point3D(void) const
std::vector< std::vector< art::Ptr< recob::Hit > > > fClusters
Implementation of the Projection Matching Algorithm.
float PeakTime() const
Time of the signal peak, in tick units.
Utility object to perform functions of association.
void Make3DSeg(art::Event const &e, std::vector< ems::DirOfGamma * > pair)
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
pma::ProjectionMatchingAlg fProjectionMatchingAlg
TVector2 WireDriftToCm(unsigned int wire, float drift, unsigned int plane, unsigned int tpc, unsigned int cryo)
TVector2 GetProjectionToPlane(const TVector3 &p, unsigned int plane, unsigned int tpc, unsigned int cryo)
bool Has(const std::vector< size_t > &v, size_t idx)
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
std::vector< art::Ptr< recob::Hit > > hits2
constexpr double kBogusD
obviously bogus double value
std::vector< art::Ptr< recob::Hit > > hits1
std::vector< IniSeg > fSeltracks
TPCID_t TPC
Index of the TPC within its cryostat.
recob::Track ConvertFrom(pma::Track3D &src)
std::string fCluModuleLabel
std::vector< Hit2D * > const & GetHits2D(void) const
double validate(const pma::Track3D &trk, const std::vector< art::Ptr< recob::Hit > > &hits) const
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
std::vector< IniSeg > fInisegs
std::vector< ems::DirOfGamma * > CollectShower2D(art::Event const &e)