14 fShowerEnergyAlg(pset.get<
fhicl::ParameterSet>(
"ShowerEnergyAlg")),
15 fCalorimetryAlg(pset.get<
fhicl::ParameterSet>(
"CalorimetryAlg")),
16 fProjectionMatchingAlg(pset.get<
fhicl::ParameterSet>(
"ProjectionMatchingAlg")) {
22 fNfithits = pset.
get<std::vector<unsigned int> >(
"Nfithits");
23 fToler = pset.
get<std::vector<double> >(
"Toler");
24 if (fNfitpass!=fNfithits.size() ||
25 fNfitpass!=fToler.size()) {
27 <<
"EMShowerAlg: fNfithits and fToler need to have size fNfitpass";
46 std::map<
int,std::vector<int> >& clusterToTracks,
47 std::map<
int,std::vector<int> >& trackToClusters) {
49 std::vector<int> clustersToIgnore = {-999};
59 std::vector<int>
const& clustersToIgnore,
60 std::map<
int,std::vector<int> >& clusterToTracks,
61 std::map<
int,std::vector<int> >& trackToClusters) {
67 std::vector<art::Ptr<recob::Hit> > clusterHits = fmh.at(clusterIt->key());
73 std::vector<art::Ptr<recob::Track> > clusterHitTracks = fmt.at(clusterHitIt->key());
74 if (clusterHitTracks.size() > 1) { std::cout <<
"More than one track associated with this hit!" << std::endl;
continue; }
75 if (clusterHitTracks.size() < 1)
continue;
78 std::cout <<
"Track " << clusterHitTracks.at(0)->ID() <<
" is too short! (" << clusterHitTracks.at(0)->Length() <<
")" << std::endl;
83 int track = clusterHitTracks.at(0).key();
85 int cluster = (*clusterIt).key();
86 if (std::find(clustersToIgnore.begin(), clustersToIgnore.end(), cluster) != clustersToIgnore.end())
88 if (std::find(trackToClusters[track].
begin(), trackToClusters[track].
end(), cluster) == trackToClusters[
track].end())
89 trackToClusters[track].push_back(cluster);
90 if (std::find(clusterToTracks[cluster].
begin(), clusterToTracks[cluster].
end(), track) == clusterToTracks[cluster].end())
91 clusterToTracks[cluster].push_back(track);
103 std::map<int,std::vector<int> > firstTPC;
105 firstTPC[showerHitsIt->second.at(0)->WireID().TPC].push_back(showerHitsIt->first);
108 if (firstTPC.size() == 1)
112 else if (firstTPC.size() > 2)
118 int problemPlane = -1;
119 for (std::map<
int,std::vector<int> >::
iterator firstTPCIt = firstTPC.begin(); firstTPCIt != firstTPC.end(); ++firstTPCIt)
120 if (firstTPCIt->second.size() == 1)
121 problemPlane = firstTPCIt->second.at(0);
124 if (showerHitsMap.at(problemPlane).size() < 3)
128 std::vector<int> otherPlanes;
130 if (plane != problemPlane and
131 showerHitsMap.count(plane) and
132 showerHitsMap.at(plane).size() >= 3)
133 otherPlanes.push_back(plane);
135 if (otherPlanes.size() == 0)
139 unsigned int wrongTPC = showerHitsMap.at(problemPlane).at(0)->WireID().TPC;
140 unsigned int nHits = 0;
142 hitIt != showerHitsMap.at(problemPlane).end() and (*hitIt)->WireID().TPC == wrongTPC;
151 std::map<int,int> otherTPCs;
153 hitIt != showerHitsMap.at(problemPlane).end() and std::distance(std::next(showerHitsMap.at(problemPlane).begin(),nHits),hitIt) < 4*nHits;
155 ++otherTPCs[(*hitIt)->WireID().TPC];
157 if (otherTPCs.size() > 1)
161 std::map<int,int> tpcCount;
164 hitIt != showerHitsMap.at(*otherPlaneIt).end() and hitIt != std::next(showerHitsMap.at(*otherPlaneIt).begin(),2);
166 ++tpcCount[(*hitIt)->WireID().TPC];
169 if (tpcCount.size() == 1 and tpcCount.begin()->first == (int)(*std::next(showerHitsMap.at(problemPlane).begin(),nHits))->WireID().TPC) {
170 std::vector<art::Ptr<recob::Hit> > naughty_hits;
172 naughty_hits.push_back(*hitIt);
173 showerHitsMap.at(problemPlane).erase(hitIt);
176 showerHitsMap.at(problemPlane).push_back(*naughty_hitIt);
185 bool consistencyCheck =
true;
187 if (showerHitsMap.size() < 2)
188 consistencyCheck =
true;
190 else if (showerHitsMap.size() == 2) {
196 std::vector<art::Ptr<recob::Hit> > startHits;
197 std::vector<int> planes;
199 startHits.push_back(showerHitsIt->second.front());
200 planes.push_back(showerHitsIt->first);
203 TVector3 showerStartPos =
Construct3DPoint(startHits.at(0), startHits.at(1));
207 double timingDifference = TMath::Abs( startHits.at(0)->PeakTime() - startHits.at(1)->PeakTime() );
208 double projectionDifference = ( (
HitPosition(startHits.at(0)) - proj1).Mod() + (
HitPosition(startHits.at(1)) - proj2).Mod() ) / (
double)2;
210 if (timingDifference > 40 or
211 projectionDifference > 5 or
212 showerStartPos.X() == -9999 or showerStartPos.Y() == -9999 or showerStartPos.Z() == -9999)
213 consistencyCheck =
false;
216 std::cout <<
"Timing difference is " << timingDifference <<
" and projection distance is " << projectionDifference <<
" (start is (" << showerStartPos.X() <<
", " << showerStartPos.Y() <<
", " << showerStartPos.Z() <<
")" << std::endl;
220 else if (showerHitsMap.size() == 3) {
226 std::map<int,art::Ptr<recob::Hit> > start2DMap;
228 start2DMap[showerHitIt->first] = showerHitIt->second.front();
230 std::map<int,double> projDiff;
231 std::map<int,double> timingDiff;
233 for (
int plane = 0; plane < 3; ++plane) {
235 std::vector<int> otherPlanes;
236 for (
int otherPlane = 0; otherPlane < 3; ++otherPlane)
237 if (otherPlane != plane)
238 otherPlanes.push_back(otherPlane);
240 TVector3 showerStartPos =
Construct3DPoint(start2DMap.at(otherPlanes.at(0)), start2DMap.at(otherPlanes.at(1)));
244 std::cout <<
"Plane... " << plane << std::endl;
245 std::cout <<
"Start position in this plane is " <<
HitPosition(start2DMap.at(plane)).
X() <<
", " <<
HitPosition(start2DMap.at(plane)).
Y() <<
")" << std::endl;
246 std::cout <<
"Shower start from other two planes is (" << showerStartPos.X() <<
", " << showerStartPos.Y() <<
", " << showerStartPos.Z() <<
")" << std::endl;
247 std::cout <<
"Projecting the other two planes gives position (" << showerStartProj.X() <<
", " << showerStartProj.Y() <<
")" << std::endl;
250 double projDiff = TMath::Abs((showerStartProj-
HitPosition(start2DMap.at(plane))).Mod());
251 double timeDiff = TMath::Max(TMath::Abs(start2DMap.at(plane)->PeakTime() - start2DMap.at(otherPlanes.at(0))->PeakTime()),
252 TMath::Abs(start2DMap.at(plane)->PeakTime() - start2DMap.at(otherPlanes.at(1))->PeakTime()));
255 std::cout <<
"Plane " << plane <<
" has projDiff " << projDiff <<
" and timeDiff " << timeDiff << std::endl;
257 if (projDiff > 5 or timeDiff > 40)
258 consistencyCheck =
false;
265 std::cout <<
"Consistency check is " << consistencyCheck << std::endl;
267 return consistencyCheck;
275 std::vector<int> clustersToIgnore;
308 for (
std::vector<std::vector<int> >::
const_iterator initialShowerIt = initialShowers.begin(); initialShowerIt != initialShowers.end(); ++initialShowerIt) {
310 if (std::distance(initialShowers.begin(),initialShowerIt) > 0)
314 std::map<int,std::vector<art::Ptr<recob::Cluster> > > planeClusters;
315 std::map<int,std::vector<art::Ptr<recob::Hit> > > planeHits;
318 std::vector<art::Ptr<recob::Hit> >
hits = fmh.at(cluster.
key());
319 planeClusters[cluster->
Plane().
Plane].push_back(cluster);
321 planeHits[(*hitIt)->WireID().Plane].push_back(*hitIt);
324 TFile* outFile =
new TFile(
"chargeDistributions.root",
"RECREATE");
325 std::map<int,TH1D*> chargeDist;
328 chargeDist[planeIt->first] =
new TH1D(std::string(
"chargeDist_Plane"+
std::to_string(planeIt->first)+
"_Cluster"+
std::to_string(clusterIt->key())).c_str(),
"",150,0,1000);
329 std::vector<art::Ptr<recob::Hit> >
hits = fmh.at(clusterIt->key());
331 chargeDist[planeIt->first]->Fill((*hitIt)->Integral());
333 chargeDist[planeIt->first]->Write();
340 if (planeClusters.size() < 3)
344 std::map<int,std::vector<double> > planeClusterSizes;
347 std::vector<art::Ptr<recob::Hit> >
hits = fmh.at(planeClusterIt->key());
348 planeClusterSizes[planeClustersIt->first].push_back((
double)hits.size()/(double)planeHits.at(planeClustersIt->first).size());
353 std::map<int,double> planeClustersAvSizes;
354 for (std::map<
int,std::vector<double> >::
iterator planeClusterSizesIt = planeClusterSizes.begin(); planeClusterSizesIt != planeClusterSizes.end(); ++planeClusterSizesIt) {
356 for (
std::vector<double>::iterator planeClusterSizeIt = planeClusterSizesIt->second.begin(); planeClusterSizeIt != planeClusterSizesIt->second.end(); ++planeClusterSizeIt)
357 average += *planeClusterSizeIt;
358 average /= planeClusterSizesIt->second.size();
359 planeClustersAvSizes[planeClusterSizesIt->first] = average;
365 for (
std::map<int,double>::iterator clusterAvSizeIt = planeClustersAvSizes.begin(); clusterAvSizeIt != planeClustersAvSizes.end(); ++clusterAvSizeIt) {
368 std::vector<double> otherAverages;
369 for (
std::map<int,double>::iterator otherClustersAvSizeIt = planeClustersAvSizes.begin(); otherClustersAvSizeIt != planeClustersAvSizes.end(); ++otherClustersAvSizeIt)
370 if (clusterAvSizeIt->first != otherClustersAvSizeIt->first)
371 otherAverages.push_back(otherClustersAvSizeIt->second);
372 double quadOtherPlanes = 0;
374 quadOtherPlanes += TMath::Power(*otherAvIt,2);
375 quadOtherPlanes = TMath::Sqrt(quadOtherPlanes);
378 if (clusterAvSizeIt->second >= quadOtherPlanes)
379 badPlane = clusterAvSizeIt->first;
383 if (badPlane != -1) {
385 std::cout <<
"Bad plane is " << badPlane << std::endl;
387 clustersToIgnore.push_back(clusterIt->key());
392 return clustersToIgnore;
405 return TVector3(x, intersection.
y, intersection.
z);
411 std::map<int,TVector2>
const& showerCentreMap) {
413 std::unique_ptr<recob::Track>
track;
415 std::vector<art::Ptr<recob::Hit> > track1, track2;
418 if ((*hits1.begin())->WireID().TPC != (*hits2.begin())->WireID().TPC) {
419 mf::LogWarning(
"EMShowerAlg") <<
"Warning: attempting to construct a track from two different TPCs. Returning a null track.";
424 std::map<int,int> tpcMap;
426 ++tpcMap[(*hitIt)->WireID().TPC];
428 ++tpcMap[(*hitIt)->WireID().TPC];
429 if (tpcMap.size() > 1) {
430 mf::LogWarning(
"EMShowerAlg") <<
"Warning: attempting to construct a track which crosses more than one TPC -- PMTrack can't handle this right now. Returning a track made just from hits in the first TPC it traverses.";
431 unsigned int firstTPC1 = hits1.at(0)->WireID().TPC, firstTPC2 = hits2.at(0)->WireID().TPC;
433 if ((*hitIt)->WireID().TPC == firstTPC1) track1.push_back(*hitIt);
435 if ((*hitIt)->WireID().TPC == firstTPC2) track2.push_back(*hitIt);
443 std::cout <<
"About to make a track from these hits:" << std::endl;
445 std::cout <<
"Hit (" <<
HitCoordinates(*hit1).X() <<
", " <<
HitCoordinates(*hit1).Y() <<
") (real wire " << (*hit1)->WireID().Wire <<
") in TPC " << (*hit1)->WireID().TPC << std::endl;
447 std::cout <<
"Hit (" <<
HitCoordinates(*hit2).X() <<
", " <<
HitCoordinates(*hit2).Y() <<
") (real wire " << (*hit2)->WireID().Wire <<
") in TPC " << (*hit2)->WireID().TPC << std::endl;
454 mf::LogInfo(
"EMShowerAlg") <<
"Skipping this event because not enough hits in two views";
458 std::vector<TVector3> xyz, dircos;
459 std::vector<std::vector<double> > dEdx;
461 for (
unsigned int i = 0; i < pmatrack->size(); i++) {
463 xyz.push_back((*pmatrack)[i]->
Point3D());
465 if (i < pmatrack->size()-1) {
468 TVector3 dc(0., 0., 0.);
469 while ((mag == 0.0) and (j < pmatrack->size())) {
470 dc = (*pmatrack)[j]->Point3D();
471 dc -= (*pmatrack)[i]->Point3D();
475 if (mag > 0.0) dc *= 1.0 / mag;
476 else if (!dircos.empty()) dc = dircos.back();
480 dircos.push_back(dc);
482 else dircos.push_back(dircos.back());
487 std::map<int,double> distanceToVertex, distanceToEnd;
488 TVector3
vertex = *xyz.begin(),
end = *xyz.rbegin();
498 distanceToVertex[showerCentreIt->first] = (vertexProj - showerCentreIt->second).Mod();
499 distanceToEnd[showerCentreIt->first] = (endProj - showerCentreIt->second).Mod();
504 double avDistanceToVertex = 0, avDistanceToEnd = 0;
505 for (
std::map<int,double>::iterator distanceToVertexIt = distanceToVertex.begin(); distanceToVertexIt != distanceToVertex.end(); ++distanceToVertexIt)
506 avDistanceToVertex += distanceToVertexIt->second;
507 avDistanceToVertex /= distanceToVertex.size();
510 avDistanceToEnd += distanceToEndIt->second;
511 if (distanceToEnd.size() != 0)
512 avDistanceToEnd /= distanceToEnd.size();
515 std::cout <<
"Distance to vertex is " << avDistanceToVertex <<
" and distance to end is " << avDistanceToEnd << std::endl;
518 if (avDistanceToEnd > avDistanceToVertex) {
519 std::reverse(xyz.begin(), xyz.end());
520 std::transform(dircos.begin(), dircos.end(), dircos.begin(), [](TVector3
const& vec){
return -1*vec;});
523 if (xyz.size() != dircos.size())
524 mf::LogError(
"EMShowerAlg") <<
"Problem converting pma::Track3D to recob::Track";
526 track = std::make_unique<recob::Track>(xyz, dircos, dEdx);
535 std::map<int,TVector2> showerCentreMap;
543 double totalCharge = 0, totalDistance = 0, avHitTime = 0;
544 unsigned int nHits = 0;
564 catch(...) { pitch = 0; }
574 totalDistance += pitch;
575 totalCharge += (*trackHitIt)->Integral();
576 avHitTime += (*trackHitIt)->PeakTime();
581 avHitTime /= (double)nHits;
583 double dQdx = totalCharge / totalDistance;
591 std::unique_ptr<recob::Track>& initialTrack,
608 std::cout <<
" ------------------ Finding initial track hits -------------------- " << std::endl;
611 std::cout <<
"Here are the initial shower hits... " << std::endl;
613 std::cout <<
" Plane " << initialTrackHitsIt->first << std::endl;
615 std::cout <<
" Hit is (" <<
HitCoordinates(*initialTrackHitIt).X() <<
" (real hit " << (*initialTrackHitIt)->WireID() <<
"), " <<
HitCoordinates(*initialTrackHitIt).Y() <<
")" << std::endl;
619 std::cout <<
" ------------------ End finding initial track hits -------------------- " << std::endl;
623 std::cout <<
" ------------------ Finding initial track -------------------- " << std::endl;
625 if (initialTrack and
fDebug > 1) {
626 std::cout <<
"The track start is (" << initialTrack->
Vertex().X() <<
", " << initialTrack->
Vertex().Y() <<
", " << initialTrack->
Vertex().Z() <<
")" << std::endl;
630 std::cout <<
" ------------------ End finding initial track -------------------- " << std::endl;
667 direction = direction.Rotate(TMath::Pi()/2);
671 std::map<double,art::Ptr<recob::Hit> > hitProjection;
674 hitProjection[direction*pos] = *
hit;
678 std::vector<art::Ptr<recob::Hit> > showerHits;
679 std::transform(hitProjection.begin(), hitProjection.end(), std::back_inserter(showerHits), [](std::pair<double,art::Ptr<recob::Hit> >
const&
hit) {
return hit.second; });
683 std::map<int,TGraph*> graphs;
685 int tpc = (*hitIt)->WireID().TPC;
686 if (graphs[tpc] ==
nullptr)
687 graphs[tpc] =
new TGraph();
691 TMultiGraph* multigraph =
new TMultiGraph();
693 graphIt->second->SetMarkerColor(graphIt->first);
694 graphIt->second->SetMarkerStyle(8);
695 graphIt->second->SetMarkerSize(2);
696 multigraph->Add(graphIt->second);
698 TCanvas* canvas =
new TCanvas();
699 multigraph->Draw(
"AP");
701 line.SetLineColor(2);
702 line.DrawLine(centre.X()-1000*direction.X(),centre.Y()-1000*direction.Y(),centre.X()+1000*direction.X(),centre.Y()+1000*direction.Y());
703 canvas->SaveAs(
"Gradient.png");
704 delete canvas;
delete multigraph;
714 std::vector<std::vector<int> > showers;
717 for (std::map<
int,std::vector<int> >::
const_iterator trackToClusterIt = trackToClusters.begin(); trackToClusterIt != trackToClusters.end(); ++ trackToClusterIt) {
720 std::vector<int> matchingShowers;
724 (std::find(matchingShowers.begin(), matchingShowers.end(),
shower)) == matchingShowers.end() )
725 matchingShowers.push_back(
shower);
734 if (matchingShowers.size() < 1)
735 showers.push_back(trackToClusterIt->second);
740 if (std::find(showers.at(matchingShowers.at(0)).
begin(), showers.at(matchingShowers.at(0)).
end(), *
cluster) == showers.at(matchingShowers.at(0)).
end())
741 showers.at(matchingShowers.at(0)).push_back(*
cluster);
751 std::map<int,std::vector<art::Ptr<recob::Hit> > > initialHitsMap;
755 std::vector<art::Ptr<recob::Hit> > initialHits;
756 const std::vector<art::Ptr<recob::Hit> > orderedShower = orderedShowerIt->second;
759 bool wireDirection =
true;
760 std::vector<int> wires;
763 std::sort(wires.begin(), wires.end());
764 if (TMath::Abs(*wires.begin()-std::round(
HitCoordinates(*orderedShower.begin()).
X())) > 3 and
765 TMath::Abs(*wires.rbegin()-std::round(
HitCoordinates(*orderedShower.begin()).
X())) > 3)
766 wireDirection =
false;
771 std::map<int,std::vector<art::Ptr<recob::Hit> > > wireHitMap;
772 int multipleWires = 0;
774 wireHitMap[std::round(
HitCoordinates(*hitIt).X())].push_back(*hitIt);
777 if (wireHitMap[wire].size() > 1) {
779 if (multipleWires > 5)
break;
782 else if ( (increasing and wireHitMap[wire+1].size() > 1 and (wireHitMap[wire+2].size() > 1 or wireHitMap[wire+3].size() > 1)) or
783 (!increasing and wireHitMap[wire-1].size() > 1 and (wireHitMap[wire-2].size() > 1 or wireHitMap[wire-3].size() > 1)) ) {
784 if ( (increasing and (wireHitMap[wire+4].size() < 2 and wireHitMap[wire+5].size() < 2 and wireHitMap[wire+6].size() < 2 and wireHitMap[wire+9].size() > 1)) or
785 (!increasing and (wireHitMap[wire-4].size() < 2 and wireHitMap[wire-5].size() < 2 and wireHitMap[wire-6].size() < 2) and wireHitMap[wire-9].size() > 1) )
786 initialHits.push_back(*hitIt);
791 initialHits.push_back(*hitIt);
793 if (!initialHits.size()) initialHits.push_back(*orderedShower.begin());
799 std::map<int,std::vector<art::Ptr<recob::Hit> > > tickHitMap;
801 tickHitMap[std::round(
HitCoordinates(*hitIt).Y())].push_back(*hitIt);
804 if ( (increasing and (tickHitMap[tick+1].size() or tickHitMap[tick+2].size() or tickHitMap[tick+3].size() or tickHitMap[tick+4].size() or tickHitMap[tick+5].size())) or
805 (!increasing and (tickHitMap[tick-1].size() or tickHitMap[tick-2].size() or tickHitMap[tick-3].size() or tickHitMap[tick-4].size() or tickHitMap[tick-5].size())) )
808 initialHits.push_back(*hitIt);
810 if (!initialHits.size()) initialHits.push_back(*orderedShower.begin());
814 if (initialHits.size() == 1 and orderedShower.size() > 2)
815 initialHits.push_back(orderedShower.at(1));
818 std::vector<art::Ptr<recob::Hit> > newInitialHits;
819 std::map<int,int> tpcHitMap;
820 std::vector<int> singleHitTPCs;
822 ++tpcHitMap[(*initialHitIt)->WireID().TPC];
824 if (tpcIt->second == 1) singleHitTPCs.push_back(tpcIt->first);
825 if (singleHitTPCs.size()) {
828 std::cout <<
"Removed hits in TPC " << *tpcIt << std::endl;
830 if (std::find(singleHitTPCs.begin(), singleHitTPCs.end(), (*initialHitIt)->WireID().TPC) == singleHitTPCs.end())
831 newInitialHits.push_back(*initialHitIt);
832 if (!newInitialHits.size()) newInitialHits.push_back(*orderedShower.begin());
835 newInitialHits = initialHits;
837 initialHitsMap[orderedShowerIt->first] = newInitialHits;
841 return initialHitsMap;
848 std::map<int,std::map<int,bool> > permutations;
858 std::map<int,double> planeRMSGradients, planeRMS;
860 planeRMS[showerHitsIt->first] =
ShowerHitRMS(showerHitsIt->second);
865 std::map<double,int> gradientMap;
867 gradientMap[TMath::Abs(planeRMSGradients.at(showerHitsIt->first))] = showerHitsIt->first;
873 std::cout <<
"Plane " << wireWidthIt->second <<
" has relative width in wire of " << wireWidthIt->first <<
"; and an RMS gradient of " << planeRMSGradients[wireWidthIt->second] << std::endl;
881 permutations[perm][showerHitsIt->first] = 0;
886 std::map<int,bool> permutation;
887 permutation[wireWidthIt->second] = 1;
889 if (wireWidthIt->second != wireWidth2It->second)
890 permutation[wireWidth2It->second] = 0;
891 if (std::find(usedPermutations.begin(), usedPermutations.end(), permutation) == usedPermutations.end()) {
892 permutations[perm] = permutation;
893 usedPermutations.push_back(permutation);
897 for (std::map<double,int>::reverse_iterator wireWidthIt = wireWidthMap.rbegin(); wireWidthIt != wireWidthMap.rend(); ++wireWidthIt) {
898 std::map<int,bool> permutation;
899 permutation[wireWidthIt->second] = 0;
901 if (wireWidthIt->second != wireWidth2It->second)
902 permutation[wireWidth2It->second] = 1;
903 if (std::find(usedPermutations.begin(), usedPermutations.end(), permutation) == usedPermutations.end()) {
904 permutations[perm] = permutation;
905 usedPermutations.push_back(permutation);
912 permutations[perm][showerHitsIt->first] = 1;
916 std::cout <<
"Here are the permutations!" << std::endl;
917 for (std::map<
int,std::map<int,bool> >::
iterator permIt = permutations.begin(); permIt != permutations.end(); ++permIt) {
918 std::cout <<
"Permutation " << permIt->first << std::endl;
920 std::cout <<
" Plane " << planePermIt->first <<
" has value " << planePermIt->second << std::endl;
932 if (initialHitsMap.size() < 2) {
933 mf::LogInfo(
"EMShowerAlg") <<
"Only one useful view for this shower; nothing can be done" << std::endl;
934 return std::unique_ptr<recob::Track>();
937 std::vector<std::pair<int,int> > initialHitsSize;
939 initialHitsSize.push_back(std::make_pair(initialHitIt->first, initialHitIt->second.size()));
942 std::sort(initialHitsSize.begin(), initialHitsSize.end(), [](std::pair<int,int>
const& size1, std::pair<int,int>
const& size2) {
return size1.second > size2.second; });
949 std::vector<int> planes;
952 int planeToIgnore =
WorstPlane(showerHitsMap);
954 std::cout <<
"Igoring plane " << planeToIgnore <<
" in creation of initial track" << std::endl;
955 for (
std::vector<std::pair<int,int> >::
iterator hitsSizeIt = initialHitsSize.begin(); hitsSizeIt != initialHitsSize.end() and planes.size() < 2; ++hitsSizeIt) {
956 if (hitsSizeIt->first == planeToIgnore)
958 planes.push_back(hitsSizeIt->first);
962 planes = {initialHitsSize.at(0).first, initialHitsSize.at(1).first};
964 return ConstructTrack(initialHitsMap.at(planes.at(0)), initialHitsMap.at(planes.at(1)));
969 std::unique_ptr<recob::Track>
const& initialTrack,
975 std::map<int,std::vector<art::Ptr<recob::Hit> > > planeHitsMap;
977 planeHitsMap[(*hit)->View()].push_back(*
hit);
980 unsigned int highestNumberOfHits = 0;
981 std::vector<double> totalEnergy, totalEnergyError, dEdx, dEdxError;
984 for (
unsigned int plane = 0; plane <
fGeom->
MaxPlanes(); ++plane) {
987 if (planeHitsMap.count(plane)) {
988 dEdx.push_back(
FinddEdx(initialHitsMap.at(plane), initialTrack));
990 if (planeHitsMap.at(plane).size() > highestNumberOfHits and initialHitsMap.count(plane)) {
992 highestNumberOfHits = planeHitsMap.at(plane).size();
999 totalEnergy.push_back(0);
1004 TVector3 direction, directionError, showerStart, showerStartError;
1007 showerStart = initialTrack->
Vertex();
1011 std::cout <<
"Best plane is " << bestPlane << std::endl;
1012 std::cout <<
"dE/dx for each plane is: " << dEdx[0] <<
", " << dEdx[1] <<
" and " << dEdx[2] << std::endl;
1013 std::cout <<
"Total energy for each plane is: " << totalEnergy[0] <<
", " << totalEnergy[1] <<
" and " << totalEnergy[2] << std::endl;
1014 std::cout <<
"The shower start is (" << showerStart.X() <<
", " << showerStart.Y() <<
", " << showerStart.Z() <<
")" << std::endl;
1015 std::cout <<
"The shower direction is (" << direction.X() <<
", " << direction.Y() <<
", " << direction.Z() <<
")" << std::endl;
1018 return recob::Shower(direction, directionError, showerStart, showerStartError, totalEnergy, totalEnergyError, dEdx, dEdxError, bestPlane);
1029 std::map<int,std::vector<art::Ptr<recob::Hit> > > planeHitsMap;
1031 planeHitsMap[(*hit)->WireID().Plane].push_back(*
hit);
1033 std::vector<std::vector<art::Ptr<recob::Hit> > > initialTrackHits(3);
1037 unsigned maxhits0 = 0;
1038 unsigned maxhits1 = 0;
1042 std::vector<art::Ptr<recob::Hit> > showerHits;
1046 if ((planeHits->second).size()>maxhits0){
1048 maxhits1 = maxhits0;
1051 pl0 = planeHits->first;
1052 maxhits0 = (planeHits->second).size();
1054 else if ((planeHits->second).size()>maxhits1){
1055 pl1 = planeHits->first;
1056 maxhits1 = (planeHits->second).size();
1065 if (pl0!=-1&&pl1!=-1
1066 &&initialTrackHits[pl0].size()>=2
1067 &&initialTrackHits[pl1].size()>=2
1068 &&initialTrackHits[pl0][0]->WireID().TPC==
1069 initialTrackHits[pl1][0]->WireID().TPC){
1085 std::vector<TVector3> spts;
1090 for (
size_t i = 0; i<pmatrack->
size(); ++i){
1091 if ((*pmatrack)[i]->IsEnabled()){
1092 TVector3 p3d = (*pmatrack)[i]->Point3D();
1095 spts.push_back(p3d);
1098 if (spts.size()>=2){
1099 TVector3 shwxyz, shwxyzerr;
1100 TVector3 shwdir, shwdirerr;
1101 std::vector<double> totalEnergy, totalEnergyError, dEdx, dEdxError;
1102 int bestPlane = pl0;
1103 double minpitch = 1000;
1104 std::vector<TVector3> dirs;
1105 if ((spts[0]-vtx).Mag()<(spts.back()-vtx).Mag()){
1108 if (spts.size()-1<5) i = spts.size()-1;
1109 shwdir = spts[i] - spts[0];
1110 shwdir = shwdir.Unit();
1113 shwxyz = spts.back();
1115 if (spts.size()>6) i = spts.size() - 6;
1116 shwdir = spts[i] - spts[spts.size()-1];
1117 shwdir = shwdir.Unit();
1121 for (
unsigned int plane = 0; plane <
fGeom->
MaxPlanes(); ++plane) {
1122 if (planeHitsMap.find(plane)!=planeHitsMap.end()){
1126 totalEnergy.push_back(0);
1128 if (initialTrackHits[plane].size()){
1133 double wirepitch =
fGeom->
WirePitch(initialTrackHits[plane][0]->WireID().planeID());
1135 double cosgamma = std::abs(sin(angleToVert)*shwdir.Y()+
1136 cos(angleToVert)*shwdir.Z());
1137 if (cosgamma>0) pitch = wirepitch/cosgamma;
1139 if (pitch<minpitch){
1145 std::vector<float> vQ;
1146 for (
auto const&
hit: initialTrackHits[plane]){
1148 int w1 =
hit->WireID().Wire;
1149 int w0 = initialTrackHits[plane][0]->WireID().Wire;
1151 vQ.push_back(
hit->Integral());
1152 totQ +=
hit->Integral();
1153 avgT+=
hit->PeakTime();
1162 double dQdx = TMath::Median(vQ.size(), &vQ[0])/pitch;
1166 dEdx.push_back(fdEdx);
1174 std::cout <<
"Best plane is " << bestPlane << std::endl;
1175 std::cout <<
"dE/dx for each plane is: " << dEdx[0] <<
", " << dEdx[1] <<
" and " << dEdx[2] << std::endl;
1176 std::cout <<
"Total energy for each plane is: " << totalEnergy[0] <<
", " << totalEnergy[1] <<
" and " << totalEnergy[2] << std::endl;
1177 std::cout <<
"The shower start is (" << shwxyz.X() <<
", " << shwxyz.Y() <<
", " << shwxyz.Z() <<
")" << std::endl;
1181 return recob::Shower(shwdir, shwdirerr, shwxyz, shwxyzerr, totalEnergy, totalEnergyError, dEdx, dEdxError, bestPlane);
1191 std::vector<recob::SpacePoint> spacePoints;
1208 std::vector<int> usedHits;
1214 std::vector<int> otherPlanes;
1215 for (
unsigned int otherPlane = 0; otherPlane <
fGeom->
MaxPlanes(); ++otherPlane)
1216 if ((
int)otherPlane != showerHitIt->first and showerHits.count(otherPlane))
1217 otherPlanes.push_back(otherPlane);
1220 if (otherPlanes.size() == 0)
1226 if (std::find(usedHits.begin(), usedHits.end(), planeHitIt->key()) != usedHits.end())
1230 const std::vector<art::Ptr<recob::Hit> > otherPlaneHits = showerHits.at(otherPlanes.at(0));
1232 otherPlaneHitIt != otherPlaneHits.end() and std::find(usedHits.begin(), usedHits.end(), planeHitIt->key()) == usedHits.end();
1233 ++otherPlaneHitIt) {
1235 if ((*otherPlaneHitIt)->WireID().TPC != (*planeHitIt)->WireID().TPC or
1236 std::find(usedHits.begin(), usedHits.end(), otherPlaneHitIt->key()) != usedHits.end())
1240 std::vector<art::Ptr<recob::Hit> > pointHits;
1241 bool truePoint =
false;
1243 if (otherPlanes.size() > 1) {
1246 const std::vector<art::Ptr<recob::Hit> > otherOtherPlaneHits = showerHits.at(otherPlanes.at(1));
1249 otherOtherPlaneHitIt != otherOtherPlaneHits.end() and !truePoint;
1250 ++otherOtherPlaneHitIt) {
1252 if ((*otherOtherPlaneHitIt)->WireID().TPC == (*planeHitIt)->WireID().TPC and
1258 usedHits.push_back(planeHitIt->key());
1259 usedHits.push_back(otherPlaneHitIt->key());
1260 usedHits.push_back(otherOtherPlaneHitIt->key());
1262 pointHits.push_back(*planeHitIt);
1263 pointHits.push_back(*otherPlaneHitIt);
1264 pointHits.push_back(*otherOtherPlaneHitIt);
1275 usedHits.push_back(planeHitIt->key());
1276 usedHits.push_back(otherPlaneHitIt->key());
1278 pointHits.push_back(*planeHitIt);
1279 pointHits.push_back(*otherPlaneHitIt);
1285 double xyz[3] = {point.X(), point.Y(), point.Z()};
1288 spacePoints.emplace_back(xyz, xyzerr, chisq);
1289 hitAssns.push_back(pointHits);
1299 std::cout <<
"-------------------- Space points -------------------" << std::endl;
1300 std::cout <<
"There are " << spacePoints.size() <<
" space points:" << std::endl;
1303 const double* xyz = spacePointIt->XYZ();
1304 std::cout <<
" Space point (" << xyz[0] <<
", " << xyz[1] <<
", " << xyz[2] <<
")" << std::endl;
1334 std::map<int,std::vector<art::Ptr<recob::Hit> > > showerHitsMap;
1336 showerHitsMap[(*hit)->WireID().Plane].push_back(*
hit);
1342 std::map<int,double> planeRMSGradients, planeRMS;
1344 if (plane != showerHitsIt->first and plane != -1)
1346 std::vector<art::Ptr<recob::Hit> > orderedHits =
FindOrderOfHits(showerHitsIt->second);
1347 planeRMS[showerHitsIt->first] =
ShowerHitRMS(orderedHits);
1350 showerHitsMap[showerHitsIt->first] = orderedHits;
1355 std::cout <<
"Plane " << planeRMSIt->first <<
" has RMS " << planeRMSIt->second <<
" and RMS gradient " << planeRMSGradients.at(planeRMSIt->first) << std::endl;
1358 std::cout << std::endl <<
"Hits in order; after ordering, before reversing..." << std::endl;
1360 std::cout <<
" Plane " << showerHitsIt->first << std::endl;
1370 std::map<int,double> planeOtherRMS, planeOtherRMSGradients;
1372 planeOtherRMS[planeRMSIt->first] = 0;
1373 planeOtherRMSGradients[planeRMSIt->first] = 0;
1374 int nOtherPlanes = 0;
1376 if (plane != planeRMSIt->first and planeRMS.count(plane)) {
1377 planeOtherRMS[planeRMSIt->first] += planeRMS.at(plane);
1378 planeOtherRMSGradients[planeRMSIt->first] += planeRMSGradients.at(plane);
1382 planeOtherRMS[planeRMSIt->first] /= (double)nOtherPlanes;
1383 planeOtherRMSGradients[planeRMSIt->first] /= (double)nOtherPlanes;
1388 if (planeRMS.at(showerHitsIt->first) > planeOtherRMS.at(showerHitsIt->first) * 2) {
1391 std::cout <<
"Plane " << showerHitsIt->first <<
" was perpendicular... recalculating" << std::endl;
1392 std::vector<art::Ptr<recob::Hit> > orderedHits = this->
FindOrderOfHits(showerHitsIt->second,
true);
1393 showerHitsMap[showerHitsIt->first] = orderedHits;
1401 std::cout <<
"Before reversing, here are the start and end points..." << std::endl;
1403 std::cout <<
" Plane " << showerHitsIt->first <<
" has start (" <<
HitCoordinates(showerHitsIt->second.front()).
X() <<
", " <<
HitCoordinates(showerHitsIt->second.front()).
Y() <<
") (real wire " << showerHitsIt->second.front()->WireID() <<
") and end (" <<
HitCoordinates(showerHitsIt->second.back()).
X() <<
", " <<
HitCoordinates(showerHitsIt->second.back()).
Y() <<
") (real wire " << showerHitsIt->second.back()->WireID() <<
")" << std::endl;
1408 double gradient = planeRMSGradients.at(showerHitsIt->first);
1410 std::reverse(showerHitsIt->second.begin(), showerHitsIt->second.end());
1414 std::cout << std::endl <<
"Hits in order; after reversing, before checking isolated hits..." << std::endl;
1416 std::cout <<
" Plane " << showerHitsIt->first << std::endl;
1425 std::cout << std::endl <<
"Hits in order; after checking isolated hits..." << std::endl;
1427 std::cout <<
" Plane " << showerHitsIt->first << std::endl;
1434 std::cout <<
"After reversing and checking isolated hits, here are the start and end points..." << std::endl;
1436 std::cout <<
" Plane " << showerHitsIt->first <<
" has start (" <<
HitCoordinates(showerHitsIt->second.front()).
X() <<
", " <<
HitCoordinates(showerHitsIt->second.front()).
Y() <<
") (real wire " << showerHitsIt->second.front()->WireID() <<
") and end (" <<
HitCoordinates(showerHitsIt->second.back()).
X() <<
", " <<
HitCoordinates(showerHitsIt->second.back()).
Y() <<
")" << std::endl;
1442 std::vector<int> badPlanes;
1444 std::cout <<
"Here are the relative wire widths... " << std::endl;
1447 std::cout <<
"Plane " << wireWidthIt->second <<
" has relative wire width " << wireWidthIt->first << std::endl;
1448 if (wireWidthIt->first < 1/(
double)wireWidths.size())
1449 badPlanes.push_back(wireWidthIt->second);
1452 std::map<int,std::vector<art::Ptr<recob::Hit> > > ignoredPlanes;
1453 if (badPlanes.size() == 1) {
1454 int badPlane = badPlanes.at(0);
1456 std::cout <<
"Ignoring plane " << badPlane <<
" when orientating" << std::endl;
1457 ignoredPlanes[badPlane] = showerHitsMap.at(badPlane);
1458 showerHitsMap.erase(showerHitsMap.find(badPlane));
1465 std::map<int,std::vector<art::Ptr<recob::Hit> > > originalShowerHitsMap = showerHitsMap;
1467 while (!
CheckShowerHits(showerHitsMap) and n < TMath::Power(2,(
int)showerHitsMap.size())) {
1469 std::cout <<
"Permutation " << n << std::endl;
1471 std::vector<art::Ptr<recob::Hit> >
hits = originalShowerHitsMap.at(showerHitsIt->first);
1472 if (permutations[n][showerHitsIt->first] == 1) {
1473 std::reverse(hits.begin(), hits.end());
1474 showerHitsMap[showerHitsIt->first] =
hits;
1477 showerHitsMap[showerHitsIt->first] =
hits;
1484 showerHitsMap = originalShowerHitsMap;
1487 std::cout <<
"End of OrderShowerHits: here are the order of hits:" << std::endl;
1489 std::cout <<
" Plane " << planeHitsIt->first << std::endl;
1495 if (ignoredPlanes.size())
1496 showerHitsMap[ignoredPlanes.begin()->first] = ignoredPlanes.begin()->second;
1498 return showerHitsMap;
1516 for (
auto &
hit: showerHits){
1517 if (
hit->WireID().TPC==tpc.
TPC){
1533 if ((coord1-coordvtx).Mod()<(coord0-coordvtx).Mod()){
1534 std::reverse(showerHits.begin(), showerHits.end());
1552 std::map<geo::TPCID, unsigned int> tpcmap;
1553 unsigned maxhits = 0;
1554 for (
auto const&
hit : showerHits){
1557 for (
auto const&t : tpcmap){
1558 if (t.second > maxhits){
1571 std::vector<double> wfit;
1572 std::vector<double> tfit;
1573 std::vector<double> cfit;
1578 unsigned int nhits = 0;
1579 for (
auto &
hit: showerHits){
1581 if (
hit->WireID().TPC==tpc.
TPC){
1584 if (i==0||(std::abs((coord.Y()-(parm[0]+coord.X()*parm[1]))*cos(atan(parm[1])))<
fToler[i-1])||fitok==1){
1587 wfit.push_back(coord.X());
1588 tfit.push_back(coord.Y());
1591 if (i==fNfitpass-1) {
1592 trackHits.push_back(
hit);
1601 if (i<fNfitpass-1&&wfit.size()){
1602 fitok =
WeightedFit(wfit.size(), &wfit[0], &tfit[0], &cfit[0], &parm[0]);
1635 double globalWire = -999;
1639 double wireCentre[3];
1651 if (wireID.
TPC == 0 or wireID.
TPC == 1) globalWire = wireID.
Wire;
1652 else if (wireID.
TPC == 2 or wireID.
TPC == 3 or wireID.
TPC == 4 or wireID.
TPC == 5) globalWire = nwires + wireID.
Wire;
1653 else if (wireID.
TPC == 6 or wireID.
TPC == 7) globalWire = (2*nwires) + wireID.
Wire;
1654 else mf::LogError(
"BlurredClusterAlg") <<
"Error when trying to find a global induction plane coordinate for TPC " << wireID.
TPC <<
" (geometry" <<
fDetector <<
")";
1659 int block = wireID.
TPC / 4;
1660 globalWire = (nwires*block) + wireID.
Wire;
1663 double wireCentre[3];
1677 std::map<int,int> planeWireLength;
1679 planeWireLength[showerHitsIt->first] = TMath::Abs(
HitCoordinates(showerHitsIt->second.front()).
X() -
HitCoordinates(showerHitsIt->second.back()).
X());
1682 std::map<int,double> planeOtherWireLengths;
1683 for (
std::map<int,int>::iterator planeWireLengthIt = planeWireLength.begin(); planeWireLengthIt != planeWireLength.end(); ++planeWireLengthIt) {
1686 if (plane != planeWireLengthIt->first and planeWireLength.count(plane))
1687 quad += TMath::Power(planeWireLength[plane],2);
1688 quad = TMath::Sqrt(quad);
1689 planeOtherWireLengths[planeWireLengthIt->first] = planeWireLength[planeWireLengthIt->first] / (double)quad;
1693 std::map<double,int> wireWidthMap;
1695 wireWidthMap[planeOtherWireLengths.at(showerHitsIt->first)] = showerHitsIt->first;
1697 return wireWidthMap;
1707 double sumx=0., sumy=0., sumx2=0., sumxy=0., sumweight = 0.;
1711 weight = TMath::Power((*hit)->Integral(),2);
1713 sumx += weight * pos.X();
1714 sumy += weight * pos.Y();
1715 sumx2 += weight * pos.X() * pos.X();
1716 sumxy += weight * pos.X() * pos.Y();
1719 double gradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
1720 TVector2 direction = TVector2(1,gradient).Unit();
1728 TVector2 pos, chargePoint = TVector2(0,0);
1729 double totalCharge = 0;
1732 chargePoint += (*hit)->Integral() * pos;
1733 totalCharge += (*hit)->Integral();
1735 TVector2 centre = chargePoint / totalCharge;
1746 std::vector<double> distanceToAxis;
1748 TVector2
proj = (
HitPosition(*showerHitsIt) - centre).Proj(direction) + centre;
1749 distanceToAxis.push_back((
HitPosition(*showerHitsIt) - proj).Mod());
1751 double RMS = TMath::RMS(distanceToAxis.begin(), distanceToAxis.end());
2026 double lengthOfSegment = lengthOfShower / (double)nShowerSegments;
2027 std::map<int,std::vector<art::Ptr<recob::Hit> > > showerSegments;
2028 std::map<int,double> segmentCharge;
2030 showerSegments[(int)(
HitPosition(*showerHitsIt)-
HitPosition(showerHits.front())).Mod() / lengthOfSegment].push_back(*showerHitsIt);
2031 segmentCharge[(int)(
HitPosition(*showerHitsIt)-
HitPosition(showerHits.front())).Mod() / lengthOfSegment] += (*showerHitsIt)->Integral();
2034 TGraph* graph =
new TGraph();
2035 std::vector<std::pair<int,double> > binVsRMS;
2041 TVector2 meanPosition(0,0);
2044 meanPosition /= (double)showerSegmentIt->second.size();
2047 std::vector<double> distanceToAxisBin;
2049 TVector2
proj = (
HitPosition(*hitInSegmentIt) - meanPosition).Proj(direction) + meanPosition;
2050 distanceToAxisBin.push_back((
HitPosition(*hitInSegmentIt) - proj).Mod());
2053 double RMSBin = TMath::RMS(distanceToAxisBin.begin(), distanceToAxisBin.end());
2054 binVsRMS.push_back(std::make_pair(showerSegmentIt->first, RMSBin));
2056 graph->SetPoint(graph->GetN(), showerSegmentIt->first, RMSBin);
2061 double sumx=0., sumy=0., sumx2=0., sumxy=0., sumweight = 0.;
2062 for (
std::vector<std::pair<int,double> >::
iterator binVsRMSIt = binVsRMS.begin(); binVsRMSIt != binVsRMS.end(); ++binVsRMSIt) {
2065 double weight = segmentCharge.at(binVsRMSIt->first);
2067 sumx += weight * binVsRMSIt->first;
2068 sumy += weight * binVsRMSIt->second;
2069 sumx2 += weight * binVsRMSIt->first * binVsRMSIt->first;
2070 sumxy += weight * binVsRMSIt->first * binVsRMSIt->second;
2072 double RMSgradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
2075 TVector2 direction = TVector2(1,RMSgradient).Unit();
2076 TCanvas* canv =
new TCanvas();
2078 graph->GetXaxis()->SetTitle(
"Shower segment");
2079 graph->GetYaxis()->SetTitle(
"RMS of hit distribution");
2080 TVector2 centre = TVector2(graph->GetMean(1), graph->GetMean(2));
2082 line.SetLineColor(2);
2083 line.DrawLine(centre.X()-1000*direction.X(),centre.Y()-1000*direction.Y(),centre.X()+1000*direction.X(),centre.Y()+1000*direction.Y());
2084 canv->SaveAs(
"RMSGradient.png");
2095 TVector2 wireTickPos = TVector2(-999., -999.);
2097 double pointPosition[3] = {point.X(), point.Y(), point.Z()};
2130 std::map<int,int> planeWireLength;
2131 std::map<int,double> planeOtherWireLengths;
2133 planeWireLength[showerHitsIt->first] = TMath::Abs(
HitCoordinates(showerHitsIt->second.front()).
X() -
HitCoordinates(showerHitsIt->second.back()).
X());
2134 for (
std::map<int,int>::iterator planeWireLengthIt = planeWireLength.begin(); planeWireLengthIt != planeWireLength.end(); ++planeWireLengthIt) {
2137 if (plane != planeWireLengthIt->first and planeWireLength.count(plane))
2138 quad += TMath::Power(planeWireLength[plane],2);
2139 quad = TMath::Sqrt(quad);
2140 planeOtherWireLengths[planeWireLengthIt->first] = planeWireLength[planeWireLengthIt->first] / (double)quad;
2144 for (
std::map<int,double>::const_iterator planeOtherWireLengthIt = planeOtherWireLengths.begin(); planeOtherWireLengthIt != planeOtherWireLengths.end(); ++planeOtherWireLengthIt)
2145 std::cout <<
"Plane " << planeOtherWireLengthIt->first <<
" has " << planeWireLength[planeOtherWireLengthIt->first] <<
" wire width and therefore has relative width in wire of " << planeOtherWireLengthIt->second << std::endl;
2147 std::map<double,int> wireWidthMap;
2149 double wireWidth = planeWireLength.at(showerHitsIt->first);
2150 wireWidthMap[wireWidth] = showerHitsIt->first;
2153 return wireWidthMap.begin()->second;
2172 for (Int_t i=0; i<
n; i++) {
2174 sumx2 += x[i]*x[i]*w[i];
2176 sumy2 += y[i]*y[i]*w[i];
2177 sumxy += x[i]*y[i]*w[i];
2181 if (sumx2*sumw-sumx*sumx==0.)
return 1;
2182 if (sumx2-sumx*sumx/sumw==0.)
return 1;
2184 parm[0] = (sumy*sumx2-sumx*sumxy)/(sumx2*sumw-sumx*sumx);
2185 parm[1] = (sumxy-sumx*sumy/sumw)/(sumx2-sumx*sumx/sumw);
2187 eparm[0] = sumx2*(sumx2*sumw-sumx*sumx);
2188 eparm[1] = (sumx2-sumx*sumx/sumw);
2190 if (eparm[0]<0. || eparm[1]<0.)
return 1;
2192 eparm[0] = sqrt(eparm[0])/(sumx2*sumw-sumx*sumx);
2193 eparm[1] = sqrt(eparm[1])/(sumx2-sumx*sumx/sumw);
2201 if (!
hits.size())
return false;
2202 if (
hits.size()>2000)
return true;
2203 if (
hits.size()<20)
return true;
2204 std::map<int, int> hitmap;
2209 ++hitmap[
hit->WireID().Wire];
2210 if (nhits==20)
break;
2213 if (
float(nhits-2)/hitmap.size()>1.4)
return false;
2306 std::map<int,double> trackMap;
2309 int trackID = FindParticleID(hit);
2310 trackMap[trackID] += hit->
Integral();
2314 double highestCharge = 0;
2315 int showerTrack = 0;
2317 if (trackIt->second > highestCharge) {
2318 highestCharge = trackIt->second;
2319 showerTrack = trackIt->first;
2331 double particleEnergy = 0;
2332 int likelyTrackID = 0;
2333 std::vector<sim::TrackIDE> trackIDs = bt_serv->HitToTrackIDEs(hit);
2334 for (
unsigned int idIt = 0; idIt < trackIDs.size(); ++idIt) {
2335 if (trackIDs.at(idIt).energy > particleEnergy) {
2336 particleEnergy = trackIDs.at(idIt).energy;
2337 likelyTrackID = TMath::Abs(trackIDs.at(idIt).trackID);
2341 return likelyTrackID;
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
void XYZ(double *xyz) const
Legacy method to access vertex position, preserved to avoid breaking code. Please try to use Vertex::...
double GlobalWire(const geo::WireID &wireID)
Find the global wire position.
PlaneID const & planeID() const
double z
z position of intersection
std::vector< double > fToler
double ShowerEnergy(std::vector< art::Ptr< recob::Hit > > const &hits, int plane)
Finds the total energy deposited by the shower in this view.
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
Int_t WeightedFit(const Int_t n, const Double_t *x, const Double_t *y, const Double_t *w, Double_t *parm)
<Tingjun to="" document>="">
void FindInitialTrackHits(std::vector< art::Ptr< recob::Hit > >const &showerHits, art::Ptr< recob::Vertex > const &vertex, std::vector< art::Ptr< recob::Hit > > &trackHits)
<Tingjun to="" document>="">
EMShowerAlg(fhicl::ParameterSet const &pset)
double dEdx_AREA(art::Ptr< recob::Hit > hit, double pitch, double T0=0) const
TVector3 VertexDirection() const
Covariance matrices are either set or not.
std::vector< recob::SpacePoint > MakeSpacePoints(std::map< int, std::vector< art::Ptr< recob::Hit > > > hits, std::vector< std::vector< art::Ptr< recob::Hit > > > &hitAssns)
Makes space points from the shower hits in each plane.
T::provider_type const * providerFrom()
Returns a constant pointer to the provider of specified service.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::map< int, std::vector< art::Ptr< recob::Hit > > > FindShowerStart(std::map< int, std::vector< art::Ptr< recob::Hit > > > const &orderedShowerMap)
auto coord(Vector &v, unsigned int n) noexcept
Returns an object to manage the coordinate n of a vector.
geo::WireID WireID() const
Initial tdc tick for hit.
TVector3 Construct3DPoint(art::Ptr< recob::Hit > const &hit1, art::Ptr< recob::Hit > const &hit2)
Constructs a 3D point (in [cm]) to represent the hits given in two views.
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
The data type to uniquely identify a Plane.
bool isValid
Whether this ID points to a valid element.
TVector2 Project3DPointOntoPlane(TVector3 const &point, int plane, int cryostat=0)
bool CheckShowerHits(std::map< int, std::vector< art::Ptr< recob::Hit > > > const &showerHitsMap)
std::map< int, std::vector< art::Ptr< recob::Hit > > > OrderShowerHits(const art::PtrVector< recob::Hit > &shower, int plane)
Takes the hits associated with a shower and orders them so they follow the direction of the shower...
CryostatID_t Cryostat
Index of cryostat.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
WireID_t Wire
Index of the wire within its plane.
geo::PlaneID Plane() const
Returns the plane ID this cluster lies on.
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
Cluster finding and building.
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
int FindParticleID(const art::Ptr< recob::Hit > &hit)
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
TVector2 ShowerDirection(const std::vector< art::Ptr< recob::Hit > > &showerHits)
Returns a rough charge-weighted shower 'direction' given the hits in the shower.
bool isCleanShower(std::vector< art::Ptr< recob::Hit > > const &hits)
<Tingjun to="" document>="">
calo::CalorimetryAlg fCalorimetryAlg
TVector2 ShowerCentre(const std::vector< art::Ptr< recob::Hit > > &showerHits)
Returns the charge-weighted shower centre.
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
std::unique_ptr< recob::Track > MakeInitialTrack(std::map< int, std::vector< art::Ptr< recob::Hit > > > const &initialHitsMap, std::map< int, std::vector< art::Ptr< recob::Hit > > > const &showerHitsMap)
Takes initial track hits from multiple views and forms a track object which best represents the start...
View_t View() const
Which coordinate does this plane measure.
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
std::vector< std::vector< int > > FindShowers(std::map< int, std::vector< int > > const &trackToClusters)
Makes showers given a map between tracks and all clusters associated with them.
Signal from induction planes.
bool fMakeRMSGradientPlot
int WorstPlane(const std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
Returns the plane which is determined to be the least likely to be correct.
T get(std::string const &key) const
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
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 AssociateClustersAndTracks(std::vector< art::Ptr< recob::Cluster > > const &clusters, art::FindManyP< recob::Hit > const &fmh, art::FindManyP< recob::Track > const &fmt, std::map< int, std::vector< int > > &clusterToTracks, std::map< int, std::vector< int > > &trackToClusters)
Map associated tracks and clusters together given their associated hits.
shower::ShowerEnergyAlg fShowerEnergyAlg
pma::ProjectionMatchingAlg fProjectionMatchingAlg
std::map< int, std::map< int, bool > > GetPlanePermutations(const std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
General LArSoft Utilities.
double ShowerHitRMS(const std::vector< art::Ptr< recob::Hit > > &showerHits)
Returns the RMS of the hits from the central shower 'axis' along the length of the shower...
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
art::ServiceHandle< geo::Geometry > fGeom
std::unique_ptr< recob::Track > ConstructTrack(std::vector< art::Ptr< recob::Hit > > const &track1, std::vector< art::Ptr< recob::Hit > > const &track2, std::map< int, TVector2 > const &showerCentreMap)
double FinddEdx(std::vector< art::Ptr< recob::Hit > > const &trackHits, std::unique_ptr< recob::Track > const &track)
Finds dE/dx for the track given a set of hits.
Detector simulation of raw signals on wires.
double ShowerHitRMSGradient(const std::vector< art::Ptr< recob::Hit > > &showerHits, TVector2 trueStart=TVector2(0, 0))
Returns the gradient of the RMS vs shower segment graph.
void FindInitialTrack(const std::map< int, std::vector< art::Ptr< recob::Hit > > > &hits, std::unique_ptr< recob::Track > &initialTrack, std::map< int, std::vector< art::Ptr< recob::Hit > > > &initialTrackHits, int plane)
Finds the initial track-like part of the shower and the hits in all views associated with it...
data_t::const_iterator const_iterator
void CheckIsolatedHits(std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
Checks the hits across the views in a given shower to determine if there is one in the incorrect TPC...
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
float PeakTime() const
Time of the signal peak, in tick units.
T * make(ARGS...args) const
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
art::ServiceHandle< art::TFileService > tfs
LArSoft-specific namespace.
TProfile * hNumHitsInSegment
double y
y position of intersection
TVector3 Vertex() const
Covariance matrices are either set or not.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< art::Ptr< recob::Hit > > FindOrderOfHits(std::vector< art::Ptr< recob::Hit > > const &hits, bool perpendicular=false)
detinfo::DetectorProperties const * fDetProp
Exception thrown on invalid wire number.
recob::Shower MakeShower(art::PtrVector< recob::Hit > const &hits, std::unique_ptr< recob::Track > const &initialTrack, std::map< int, std::vector< art::Ptr< recob::Hit > > > const &initialTrackHits)
Makes a recob::Shower object given the hits in the shower and the initial track-like part...
geo::WireID NearestWireID(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the ID of wire closest to position in the specified TPC.
std::vector< int > CheckShowerPlanes(std::vector< std::vector< int > > const &initialShowers, std::vector< art::Ptr< recob::Cluster > > const &clusters, art::FindManyP< recob::Hit > const &fmh)
Takes the initial showers found and tries to resolve issues where one bad view ruins the event...
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in global wire/tick space.
double TrackPitchInView(recob::Track const &track, geo::View_t view, size_t trajectory_point=0)
Provides projected wire pitch for the view.
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
std::vector< unsigned int > fNfithits
TPCID_t TPC
Index of the TPC within its cryostat.
geo::WireID suggestedWireID() const
Returns a better wire ID.
recob::tracking::Plane Plane
Namespace collecting geometry-related classes utilities.
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
std::map< double, int > RelativeWireWidth(const std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
WireGeo const & WireIDToWireGeo(geo::WireID const &wireid) const
Returns the specified wire.
int FindTrueParticle(const std::vector< art::Ptr< recob::Hit > > &showerHits)