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;
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";
538 std::map<int,TVector2> showerCentreMap;
546 double totalCharge = 0, totalDistance = 0, avHitTime = 0;
547 unsigned int nHits = 0;
567 catch(...) { pitch = 0; }
577 totalDistance += pitch;
578 totalCharge += (*trackHitIt)->Integral();
579 avHitTime += (*trackHitIt)->PeakTime();
584 avHitTime /= (double)nHits;
586 double dQdx = totalCharge / totalDistance;
594 std::unique_ptr<recob::Track>& initialTrack,
611 std::cout <<
" ------------------ Finding initial track hits -------------------- " << std::endl;
614 std::cout <<
"Here are the initial shower hits... " << std::endl;
616 std::cout <<
" Plane " << initialTrackHitsIt->first << std::endl;
618 std::cout <<
" Hit is (" <<
HitCoordinates(*initialTrackHitIt).X() <<
" (real hit " << (*initialTrackHitIt)->WireID() <<
"), " <<
HitCoordinates(*initialTrackHitIt).Y() <<
")" << std::endl;
622 std::cout <<
" ------------------ End finding initial track hits -------------------- " << std::endl;
626 std::cout <<
" ------------------ Finding initial track -------------------- " << std::endl;
628 if (initialTrack and
fDebug > 1) {
629 std::cout <<
"The track start is (" << initialTrack->
Vertex().X() <<
", " << initialTrack->
Vertex().Y() <<
", " << initialTrack->
Vertex().Z() <<
")" << std::endl;
633 std::cout <<
" ------------------ End finding initial track -------------------- " << std::endl;
670 direction = direction.Rotate(TMath::Pi()/2);
674 std::map<double,art::Ptr<recob::Hit> > hitProjection;
677 hitProjection[direction*pos] = *
hit;
681 std::vector<art::Ptr<recob::Hit> > showerHits;
682 std::transform(hitProjection.begin(), hitProjection.end(), std::back_inserter(showerHits), [](std::pair<double,art::Ptr<recob::Hit> >
const&
hit) {
return hit.second; });
686 std::map<int,TGraph*> graphs;
688 int tpc = (*hitIt)->WireID().TPC;
689 if (graphs[tpc] ==
nullptr)
690 graphs[tpc] =
new TGraph();
694 TMultiGraph* multigraph =
new TMultiGraph();
696 graphIt->second->SetMarkerColor(graphIt->first);
697 graphIt->second->SetMarkerStyle(8);
698 graphIt->second->SetMarkerSize(2);
699 multigraph->Add(graphIt->second);
701 TCanvas* canvas =
new TCanvas();
702 multigraph->Draw(
"AP");
704 line.SetLineColor(2);
705 line.DrawLine(centre.X()-1000*direction.X(),centre.Y()-1000*direction.Y(),centre.X()+1000*direction.X(),centre.Y()+1000*direction.Y());
706 canvas->SaveAs(
"Gradient.png");
707 delete canvas;
delete multigraph;
717 std::vector<std::vector<int> > showers;
720 for (std::map<
int,std::vector<int> >::
const_iterator trackToClusterIt = trackToClusters.begin(); trackToClusterIt != trackToClusters.end(); ++ trackToClusterIt) {
723 std::vector<int> matchingShowers;
727 (std::find(matchingShowers.begin(), matchingShowers.end(),
shower)) == matchingShowers.end() )
728 matchingShowers.push_back(
shower);
737 if (matchingShowers.size() < 1)
738 showers.push_back(trackToClusterIt->second);
743 if (std::find(showers.at(matchingShowers.at(0)).
begin(), showers.at(matchingShowers.at(0)).
end(), *
cluster) == showers.at(matchingShowers.at(0)).
end())
744 showers.at(matchingShowers.at(0)).push_back(*
cluster);
754 std::map<int,std::vector<art::Ptr<recob::Hit> > > initialHitsMap;
758 std::vector<art::Ptr<recob::Hit> > initialHits;
759 const std::vector<art::Ptr<recob::Hit> > orderedShower = orderedShowerIt->second;
762 bool wireDirection =
true;
763 std::vector<int> wires;
766 std::sort(wires.begin(), wires.end());
767 if (TMath::Abs(*wires.begin()-std::round(
HitCoordinates(*orderedShower.begin()).
X())) > 3 and
768 TMath::Abs(*wires.rbegin()-std::round(
HitCoordinates(*orderedShower.begin()).
X())) > 3)
769 wireDirection =
false;
774 std::map<int,std::vector<art::Ptr<recob::Hit> > > wireHitMap;
775 int multipleWires = 0;
777 wireHitMap[std::round(
HitCoordinates(*hitIt).X())].push_back(*hitIt);
780 if (wireHitMap[wire].size() > 1) {
782 if (multipleWires > 5)
break;
785 else if ( (increasing and wireHitMap[wire+1].size() > 1 and (wireHitMap[wire+2].size() > 1 or wireHitMap[wire+3].size() > 1)) or
786 (!increasing and wireHitMap[wire-1].size() > 1 and (wireHitMap[wire-2].size() > 1 or wireHitMap[wire-3].size() > 1)) ) {
787 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
788 (!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) )
789 initialHits.push_back(*hitIt);
794 initialHits.push_back(*hitIt);
796 if (!initialHits.size()) initialHits.push_back(*orderedShower.begin());
802 std::map<int,std::vector<art::Ptr<recob::Hit> > > tickHitMap;
804 tickHitMap[std::round(
HitCoordinates(*hitIt).Y())].push_back(*hitIt);
807 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
808 (!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())) )
811 initialHits.push_back(*hitIt);
813 if (!initialHits.size()) initialHits.push_back(*orderedShower.begin());
817 if (initialHits.size() == 1 and orderedShower.size() > 2)
818 initialHits.push_back(orderedShower.at(1));
821 std::vector<art::Ptr<recob::Hit> > newInitialHits;
822 std::map<int,int> tpcHitMap;
823 std::vector<int> singleHitTPCs;
825 ++tpcHitMap[(*initialHitIt)->WireID().TPC];
827 if (tpcIt->second == 1) singleHitTPCs.push_back(tpcIt->first);
828 if (singleHitTPCs.size()) {
831 std::cout <<
"Removed hits in TPC " << *tpcIt << std::endl;
833 if (std::find(singleHitTPCs.begin(), singleHitTPCs.end(), (*initialHitIt)->WireID().TPC) == singleHitTPCs.end())
834 newInitialHits.push_back(*initialHitIt);
835 if (!newInitialHits.size()) newInitialHits.push_back(*orderedShower.begin());
838 newInitialHits = initialHits;
840 initialHitsMap[orderedShowerIt->first] = newInitialHits;
844 return initialHitsMap;
851 std::map<int,std::map<int,bool> > permutations;
861 std::map<int,double> planeRMSGradients, planeRMS;
863 planeRMS[showerHitsIt->first] =
ShowerHitRMS(showerHitsIt->second);
868 std::map<double,int> gradientMap;
870 gradientMap[TMath::Abs(planeRMSGradients.at(showerHitsIt->first))] = showerHitsIt->first;
876 std::cout <<
"Plane " << wireWidthIt->second <<
" has relative width in wire of " << wireWidthIt->first <<
"; and an RMS gradient of " << planeRMSGradients[wireWidthIt->second] << std::endl;
884 permutations[perm][showerHitsIt->first] = 0;
889 std::map<int,bool> permutation;
890 permutation[wireWidthIt->second] = 1;
892 if (wireWidthIt->second != wireWidth2It->second)
893 permutation[wireWidth2It->second] = 0;
894 if (std::find(usedPermutations.begin(), usedPermutations.end(), permutation) == usedPermutations.end()) {
895 permutations[perm] = permutation;
896 usedPermutations.push_back(permutation);
900 for (std::map<double,int>::reverse_iterator wireWidthIt = wireWidthMap.rbegin(); wireWidthIt != wireWidthMap.rend(); ++wireWidthIt) {
901 std::map<int,bool> permutation;
902 permutation[wireWidthIt->second] = 0;
904 if (wireWidthIt->second != wireWidth2It->second)
905 permutation[wireWidth2It->second] = 1;
906 if (std::find(usedPermutations.begin(), usedPermutations.end(), permutation) == usedPermutations.end()) {
907 permutations[perm] = permutation;
908 usedPermutations.push_back(permutation);
915 permutations[perm][showerHitsIt->first] = 1;
919 std::cout <<
"Here are the permutations!" << std::endl;
920 for (std::map<
int,std::map<int,bool> >::
iterator permIt = permutations.begin(); permIt != permutations.end(); ++permIt) {
921 std::cout <<
"Permutation " << permIt->first << std::endl;
923 std::cout <<
" Plane " << planePermIt->first <<
" has value " << planePermIt->second << std::endl;
935 if (initialHitsMap.size() < 2) {
936 mf::LogInfo(
"EMShowerAlg") <<
"Only one useful view for this shower; nothing can be done" << std::endl;
937 return std::unique_ptr<recob::Track>();
940 std::vector<std::pair<int,int> > initialHitsSize;
942 initialHitsSize.push_back(std::make_pair(initialHitIt->first, initialHitIt->second.size()));
945 std::sort(initialHitsSize.begin(), initialHitsSize.end(), [](std::pair<int,int>
const& size1, std::pair<int,int>
const& size2) {
return size1.second > size2.second; });
952 std::vector<int> planes;
955 int planeToIgnore =
WorstPlane(showerHitsMap);
957 std::cout <<
"Igoring plane " << planeToIgnore <<
" in creation of initial track" << std::endl;
958 for (
std::vector<std::pair<int,int> >::
iterator hitsSizeIt = initialHitsSize.begin(); hitsSizeIt != initialHitsSize.end() and planes.size() < 2; ++hitsSizeIt) {
959 if (hitsSizeIt->first == planeToIgnore)
961 planes.push_back(hitsSizeIt->first);
965 planes = {initialHitsSize.at(0).first, initialHitsSize.at(1).first};
967 return ConstructTrack(initialHitsMap.at(planes.at(0)), initialHitsMap.at(planes.at(1)));
972 std::unique_ptr<recob::Track>
const& initialTrack,
978 std::map<int,std::vector<art::Ptr<recob::Hit> > > planeHitsMap;
980 planeHitsMap[(*hit)->View()].push_back(*
hit);
983 unsigned int highestNumberOfHits = 0;
984 std::vector<double> totalEnergy, totalEnergyError, dEdx, dEdxError;
987 for (
unsigned int plane = 0; plane <
fGeom->
MaxPlanes(); ++plane) {
990 if (planeHitsMap.count(plane)) {
991 dEdx.push_back(
FinddEdx(initialHitsMap.at(plane), initialTrack));
993 if (planeHitsMap.at(plane).size() > highestNumberOfHits and initialHitsMap.count(plane)) {
995 highestNumberOfHits = planeHitsMap.at(plane).size();
1002 totalEnergy.push_back(0);
1007 TVector3 direction, directionError, showerStart, showerStartError;
1010 showerStart = initialTrack->
Vertex<TVector3>();
1014 std::cout <<
"Best plane is " << bestPlane << std::endl;
1015 std::cout <<
"dE/dx for each plane is: " << dEdx[0] <<
", " << dEdx[1] <<
" and " << dEdx[2] << std::endl;
1016 std::cout <<
"Total energy for each plane is: " << totalEnergy[0] <<
", " << totalEnergy[1] <<
" and " << totalEnergy[2] << std::endl;
1017 std::cout <<
"The shower start is (" << showerStart.X() <<
", " << showerStart.Y() <<
", " << showerStart.Z() <<
")" << std::endl;
1018 std::cout <<
"The shower direction is (" << direction.X() <<
", " << direction.Y() <<
", " << direction.Z() <<
")" << std::endl;
1021 return recob::Shower(direction, directionError, showerStart, showerStartError, totalEnergy, totalEnergyError, dEdx, dEdxError, bestPlane);
1032 std::map<int,std::vector<art::Ptr<recob::Hit> > > planeHitsMap;
1034 planeHitsMap[(*hit)->WireID().Plane].push_back(*
hit);
1036 std::vector<std::vector<art::Ptr<recob::Hit> > > initialTrackHits(3);
1040 unsigned maxhits0 = 0;
1041 unsigned maxhits1 = 0;
1045 std::vector<art::Ptr<recob::Hit> > showerHits;
1049 if ((planeHits->second).size()>maxhits0){
1051 maxhits1 = maxhits0;
1054 pl0 = planeHits->first;
1055 maxhits0 = (planeHits->second).size();
1057 else if ((planeHits->second).size()>maxhits1){
1058 pl1 = planeHits->first;
1059 maxhits1 = (planeHits->second).size();
1068 if (pl0!=-1&&pl1!=-1
1069 &&initialTrackHits[pl0].size()>=2
1070 &&initialTrackHits[pl1].size()>=2
1071 &&initialTrackHits[pl0][0]->WireID().TPC==
1072 initialTrackHits[pl1][0]->WireID().TPC){
1088 std::vector<TVector3> spts;
1093 for (
size_t i = 0; i<pmatrack->
size(); ++i){
1094 if ((*pmatrack)[i]->IsEnabled()){
1095 TVector3 p3d = (*pmatrack)[i]->Point3D();
1098 spts.push_back(p3d);
1101 if (spts.size()>=2){
1102 TVector3 shwxyz, shwxyzerr;
1103 TVector3 shwdir, shwdirerr;
1104 std::vector<double> totalEnergy, totalEnergyError, dEdx, dEdxError;
1105 int bestPlane = pl0;
1106 double minpitch = 1000;
1107 std::vector<TVector3> dirs;
1108 if ((spts[0]-vtx).Mag()<(spts.back()-vtx).Mag()){
1111 if (spts.size()-1<5) i = spts.size()-1;
1112 shwdir = spts[i] - spts[0];
1113 shwdir = shwdir.Unit();
1116 shwxyz = spts.back();
1118 if (spts.size()>6) i = spts.size() - 6;
1119 shwdir = spts[i] - spts[spts.size()-1];
1120 shwdir = shwdir.Unit();
1124 for (
unsigned int plane = 0; plane <
fGeom->
MaxPlanes(); ++plane) {
1125 if (planeHitsMap.find(plane)!=planeHitsMap.end()){
1129 totalEnergy.push_back(0);
1131 if (initialTrackHits[plane].size()){
1136 double wirepitch =
fGeom->
WirePitch(initialTrackHits[plane][0]->WireID().planeID());
1138 double cosgamma = std::abs(sin(angleToVert)*shwdir.Y()+
1139 cos(angleToVert)*shwdir.Z());
1140 if (cosgamma>0) pitch = wirepitch/cosgamma;
1142 if (pitch<minpitch){
1148 std::vector<float> vQ;
1149 for (
auto const&
hit: initialTrackHits[plane]){
1151 int w1 =
hit->WireID().Wire;
1152 int w0 = initialTrackHits[plane][0]->WireID().Wire;
1154 vQ.push_back(
hit->Integral());
1155 totQ +=
hit->Integral();
1156 avgT+=
hit->PeakTime();
1165 double dQdx = TMath::Median(vQ.size(), &vQ[0])/pitch;
1169 dEdx.push_back(fdEdx);
1177 std::cout <<
"Best plane is " << bestPlane << std::endl;
1178 std::cout <<
"dE/dx for each plane is: " << dEdx[0] <<
", " << dEdx[1] <<
" and " << dEdx[2] << std::endl;
1179 std::cout <<
"Total energy for each plane is: " << totalEnergy[0] <<
", " << totalEnergy[1] <<
" and " << totalEnergy[2] << std::endl;
1180 std::cout <<
"The shower start is (" << shwxyz.X() <<
", " << shwxyz.Y() <<
", " << shwxyz.Z() <<
")" << std::endl;
1184 return recob::Shower(shwdir, shwdirerr, shwxyz, shwxyzerr, totalEnergy, totalEnergyError, dEdx, dEdxError, bestPlane);
1194 std::vector<recob::SpacePoint> spacePoints;
1211 std::vector<int> usedHits;
1217 std::vector<int> otherPlanes;
1218 for (
unsigned int otherPlane = 0; otherPlane <
fGeom->
MaxPlanes(); ++otherPlane)
1219 if ((
int)otherPlane != showerHitIt->first and showerHits.count(otherPlane))
1220 otherPlanes.push_back(otherPlane);
1223 if (otherPlanes.size() == 0)
1229 if (std::find(usedHits.begin(), usedHits.end(), planeHitIt->key()) != usedHits.end())
1233 const std::vector<art::Ptr<recob::Hit> > otherPlaneHits = showerHits.at(otherPlanes.at(0));
1235 otherPlaneHitIt != otherPlaneHits.end() and std::find(usedHits.begin(), usedHits.end(), planeHitIt->key()) == usedHits.end();
1236 ++otherPlaneHitIt) {
1238 if ((*otherPlaneHitIt)->WireID().TPC != (*planeHitIt)->WireID().TPC or
1239 std::find(usedHits.begin(), usedHits.end(), otherPlaneHitIt->key()) != usedHits.end())
1243 std::vector<art::Ptr<recob::Hit> > pointHits;
1244 bool truePoint =
false;
1246 if (otherPlanes.size() > 1) {
1249 const std::vector<art::Ptr<recob::Hit> > otherOtherPlaneHits = showerHits.at(otherPlanes.at(1));
1252 otherOtherPlaneHitIt != otherOtherPlaneHits.end() and !truePoint;
1253 ++otherOtherPlaneHitIt) {
1255 if ((*otherOtherPlaneHitIt)->WireID().TPC == (*planeHitIt)->WireID().TPC and
1261 usedHits.push_back(planeHitIt->key());
1262 usedHits.push_back(otherPlaneHitIt->key());
1263 usedHits.push_back(otherOtherPlaneHitIt->key());
1265 pointHits.push_back(*planeHitIt);
1266 pointHits.push_back(*otherPlaneHitIt);
1267 pointHits.push_back(*otherOtherPlaneHitIt);
1278 usedHits.push_back(planeHitIt->key());
1279 usedHits.push_back(otherPlaneHitIt->key());
1281 pointHits.push_back(*planeHitIt);
1282 pointHits.push_back(*otherPlaneHitIt);
1288 double xyz[3] = {point.X(), point.Y(), point.Z()};
1291 spacePoints.emplace_back(xyz, xyzerr, chisq);
1292 hitAssns.push_back(pointHits);
1302 std::cout <<
"-------------------- Space points -------------------" << std::endl;
1303 std::cout <<
"There are " << spacePoints.size() <<
" space points:" << std::endl;
1306 const double* xyz = spacePointIt->XYZ();
1307 std::cout <<
" Space point (" << xyz[0] <<
", " << xyz[1] <<
", " << xyz[2] <<
")" << std::endl;
1337 std::map<int,std::vector<art::Ptr<recob::Hit> > > showerHitsMap;
1339 showerHitsMap[(*hit)->WireID().Plane].push_back(*
hit);
1345 std::map<int,double> planeRMSGradients, planeRMS;
1347 if (plane != showerHitsIt->first and plane != -1)
1349 std::vector<art::Ptr<recob::Hit> > orderedHits =
FindOrderOfHits(showerHitsIt->second);
1350 planeRMS[showerHitsIt->first] =
ShowerHitRMS(orderedHits);
1353 showerHitsMap[showerHitsIt->first] = orderedHits;
1358 std::cout <<
"Plane " << planeRMSIt->first <<
" has RMS " << planeRMSIt->second <<
" and RMS gradient " << planeRMSGradients.at(planeRMSIt->first) << std::endl;
1361 std::cout << std::endl <<
"Hits in order; after ordering, before reversing..." << std::endl;
1363 std::cout <<
" Plane " << showerHitsIt->first << std::endl;
1373 std::map<int,double> planeOtherRMS, planeOtherRMSGradients;
1375 planeOtherRMS[planeRMSIt->first] = 0;
1376 planeOtherRMSGradients[planeRMSIt->first] = 0;
1377 int nOtherPlanes = 0;
1379 if (plane != planeRMSIt->first and planeRMS.count(plane)) {
1380 planeOtherRMS[planeRMSIt->first] += planeRMS.at(plane);
1381 planeOtherRMSGradients[planeRMSIt->first] += planeRMSGradients.at(plane);
1385 planeOtherRMS[planeRMSIt->first] /= (double)nOtherPlanes;
1386 planeOtherRMSGradients[planeRMSIt->first] /= (double)nOtherPlanes;
1391 if (planeRMS.at(showerHitsIt->first) > planeOtherRMS.at(showerHitsIt->first) * 2) {
1394 std::cout <<
"Plane " << showerHitsIt->first <<
" was perpendicular... recalculating" << std::endl;
1395 std::vector<art::Ptr<recob::Hit> > orderedHits = this->
FindOrderOfHits(showerHitsIt->second,
true);
1396 showerHitsMap[showerHitsIt->first] = orderedHits;
1404 std::cout <<
"Before reversing, here are the start and end points..." << std::endl;
1406 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;
1411 double gradient = planeRMSGradients.at(showerHitsIt->first);
1413 std::reverse(showerHitsIt->second.begin(), showerHitsIt->second.end());
1417 std::cout << std::endl <<
"Hits in order; after reversing, before checking isolated hits..." << std::endl;
1419 std::cout <<
" Plane " << showerHitsIt->first << std::endl;
1428 std::cout << std::endl <<
"Hits in order; after checking isolated hits..." << std::endl;
1430 std::cout <<
" Plane " << showerHitsIt->first << std::endl;
1437 std::cout <<
"After reversing and checking isolated hits, here are the start and end points..." << std::endl;
1439 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;
1445 std::vector<int> badPlanes;
1447 std::cout <<
"Here are the relative wire widths... " << std::endl;
1450 std::cout <<
"Plane " << wireWidthIt->second <<
" has relative wire width " << wireWidthIt->first << std::endl;
1451 if (wireWidthIt->first < 1/(
double)wireWidths.size())
1452 badPlanes.push_back(wireWidthIt->second);
1455 std::map<int,std::vector<art::Ptr<recob::Hit> > > ignoredPlanes;
1456 if (badPlanes.size() == 1) {
1457 int badPlane = badPlanes.at(0);
1459 std::cout <<
"Ignoring plane " << badPlane <<
" when orientating" << std::endl;
1460 ignoredPlanes[badPlane] = showerHitsMap.at(badPlane);
1461 showerHitsMap.erase(showerHitsMap.find(badPlane));
1468 std::map<int,std::vector<art::Ptr<recob::Hit> > > originalShowerHitsMap = showerHitsMap;
1470 while (!
CheckShowerHits(showerHitsMap) and n < TMath::Power(2,(
int)showerHitsMap.size())) {
1472 std::cout <<
"Permutation " << n << std::endl;
1474 std::vector<art::Ptr<recob::Hit> >
hits = originalShowerHitsMap.at(showerHitsIt->first);
1475 if (permutations[n][showerHitsIt->first] == 1) {
1476 std::reverse(hits.begin(), hits.end());
1477 showerHitsMap[showerHitsIt->first] =
hits;
1480 showerHitsMap[showerHitsIt->first] =
hits;
1487 showerHitsMap = originalShowerHitsMap;
1490 std::cout <<
"End of OrderShowerHits: here are the order of hits:" << std::endl;
1492 std::cout <<
" Plane " << planeHitsIt->first << std::endl;
1498 if (ignoredPlanes.size())
1499 showerHitsMap[ignoredPlanes.begin()->first] = ignoredPlanes.begin()->second;
1501 return showerHitsMap;
1519 for (
auto &
hit: showerHits){
1520 if (
hit->WireID().TPC==tpc.
TPC){
1536 if ((coord1-coordvtx).Mod()<(coord0-coordvtx).Mod()){
1537 std::reverse(showerHits.begin(), showerHits.end());
1555 std::map<geo::TPCID, unsigned int> tpcmap;
1556 unsigned maxhits = 0;
1557 for (
auto const&
hit : showerHits){
1560 for (
auto const&t : tpcmap){
1561 if (t.second > maxhits){
1574 std::vector<double> wfit;
1575 std::vector<double> tfit;
1576 std::vector<double> cfit;
1581 unsigned int nhits = 0;
1582 for (
auto &
hit: showerHits){
1584 if (
hit->WireID().TPC==tpc.
TPC){
1587 if (i==0||(std::abs((coord.Y()-(parm[0]+coord.X()*parm[1]))*cos(atan(parm[1])))<
fToler[i-1])||fitok==1){
1590 wfit.push_back(coord.X());
1591 tfit.push_back(coord.Y());
1594 if (i==fNfitpass-1) {
1595 trackHits.push_back(
hit);
1604 if (i<fNfitpass-1&&wfit.size()){
1605 fitok =
WeightedFit(wfit.size(), &wfit[0], &tfit[0], &cfit[0], &parm[0]);
1638 double globalWire = -999;
1642 double wireCentre[3];
1654 if (wireID.
TPC == 0 or wireID.
TPC == 1) globalWire = wireID.
Wire;
1655 else if (wireID.
TPC == 2 or wireID.
TPC == 3 or wireID.
TPC == 4 or wireID.
TPC == 5) globalWire = nwires + wireID.
Wire;
1656 else if (wireID.
TPC == 6 or wireID.
TPC == 7) globalWire = (2*nwires) + wireID.
Wire;
1657 else mf::LogError(
"BlurredClusterAlg") <<
"Error when trying to find a global induction plane coordinate for TPC " << wireID.
TPC <<
" (geometry" <<
fDetector <<
")";
1662 int block = wireID.
TPC / 4;
1663 globalWire = (nwires*block) + wireID.
Wire;
1666 double wireCentre[3];
1680 std::map<int,int> planeWireLength;
1682 planeWireLength[showerHitsIt->first] = TMath::Abs(
HitCoordinates(showerHitsIt->second.front()).
X() -
HitCoordinates(showerHitsIt->second.back()).
X());
1685 std::map<int,double> planeOtherWireLengths;
1686 for (
std::map<int,int>::iterator planeWireLengthIt = planeWireLength.begin(); planeWireLengthIt != planeWireLength.end(); ++planeWireLengthIt) {
1689 if (plane != planeWireLengthIt->first and planeWireLength.count(plane))
1690 quad += TMath::Power(planeWireLength[plane],2);
1691 quad = TMath::Sqrt(quad);
1692 planeOtherWireLengths[planeWireLengthIt->first] = planeWireLength[planeWireLengthIt->first] / (double)quad;
1696 std::map<double,int> wireWidthMap;
1698 wireWidthMap[planeOtherWireLengths.at(showerHitsIt->first)] = showerHitsIt->first;
1700 return wireWidthMap;
1710 double sumx=0., sumy=0., sumx2=0., sumxy=0., sumweight = 0.;
1714 weight = TMath::Power((*hit)->Integral(),2);
1716 sumx += weight * pos.X();
1717 sumy += weight * pos.Y();
1718 sumx2 += weight * pos.X() * pos.X();
1719 sumxy += weight * pos.X() * pos.Y();
1722 double gradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
1723 TVector2 direction = TVector2(1,gradient).Unit();
1731 TVector2 pos, chargePoint = TVector2(0,0);
1732 double totalCharge = 0;
1735 chargePoint += (*hit)->Integral() * pos;
1736 totalCharge += (*hit)->Integral();
1738 TVector2 centre = chargePoint / totalCharge;
1749 std::vector<double> distanceToAxis;
1751 TVector2
proj = (
HitPosition(*showerHitsIt) - centre).Proj(direction) + centre;
1752 distanceToAxis.push_back((
HitPosition(*showerHitsIt) - proj).Mod());
1754 double RMS = TMath::RMS(distanceToAxis.begin(), distanceToAxis.end());
2029 double lengthOfSegment = lengthOfShower / (double)nShowerSegments;
2030 std::map<int,std::vector<art::Ptr<recob::Hit> > > showerSegments;
2031 std::map<int,double> segmentCharge;
2033 showerSegments[(int)(
HitPosition(*showerHitsIt)-
HitPosition(showerHits.front())).Mod() / lengthOfSegment].push_back(*showerHitsIt);
2034 segmentCharge[(int)(
HitPosition(*showerHitsIt)-
HitPosition(showerHits.front())).Mod() / lengthOfSegment] += (*showerHitsIt)->Integral();
2037 TGraph* graph =
new TGraph();
2038 std::vector<std::pair<int,double> > binVsRMS;
2044 TVector2 meanPosition(0,0);
2047 meanPosition /= (double)showerSegmentIt->second.size();
2050 std::vector<double> distanceToAxisBin;
2052 TVector2
proj = (
HitPosition(*hitInSegmentIt) - meanPosition).Proj(direction) + meanPosition;
2053 distanceToAxisBin.push_back((
HitPosition(*hitInSegmentIt) - proj).Mod());
2056 double RMSBin = TMath::RMS(distanceToAxisBin.begin(), distanceToAxisBin.end());
2057 binVsRMS.push_back(std::make_pair(showerSegmentIt->first, RMSBin));
2059 graph->SetPoint(graph->GetN(), showerSegmentIt->first, RMSBin);
2064 double sumx=0., sumy=0., sumx2=0., sumxy=0., sumweight = 0.;
2065 for (
std::vector<std::pair<int,double> >::
iterator binVsRMSIt = binVsRMS.begin(); binVsRMSIt != binVsRMS.end(); ++binVsRMSIt) {
2068 double weight = segmentCharge.at(binVsRMSIt->first);
2070 sumx += weight * binVsRMSIt->first;
2071 sumy += weight * binVsRMSIt->second;
2072 sumx2 += weight * binVsRMSIt->first * binVsRMSIt->first;
2073 sumxy += weight * binVsRMSIt->first * binVsRMSIt->second;
2075 double RMSgradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
2078 TVector2 direction = TVector2(1,RMSgradient).Unit();
2079 TCanvas* canv =
new TCanvas();
2081 graph->GetXaxis()->SetTitle(
"Shower segment");
2082 graph->GetYaxis()->SetTitle(
"RMS of hit distribution");
2083 TVector2 centre = TVector2(graph->GetMean(1), graph->GetMean(2));
2085 line.SetLineColor(2);
2086 line.DrawLine(centre.X()-1000*direction.X(),centre.Y()-1000*direction.Y(),centre.X()+1000*direction.X(),centre.Y()+1000*direction.Y());
2087 canv->SaveAs(
"RMSGradient.png");
2098 TVector2 wireTickPos = TVector2(-999., -999.);
2100 double pointPosition[3] = {point.X(), point.Y(), point.Z()};
2133 std::map<int,int> planeWireLength;
2134 std::map<int,double> planeOtherWireLengths;
2136 planeWireLength[showerHitsIt->first] = TMath::Abs(
HitCoordinates(showerHitsIt->second.front()).
X() -
HitCoordinates(showerHitsIt->second.back()).
X());
2137 for (
std::map<int,int>::iterator planeWireLengthIt = planeWireLength.begin(); planeWireLengthIt != planeWireLength.end(); ++planeWireLengthIt) {
2140 if (plane != planeWireLengthIt->first and planeWireLength.count(plane))
2141 quad += TMath::Power(planeWireLength[plane],2);
2142 quad = TMath::Sqrt(quad);
2143 planeOtherWireLengths[planeWireLengthIt->first] = planeWireLength[planeWireLengthIt->first] / (double)quad;
2147 for (
std::map<int,double>::const_iterator planeOtherWireLengthIt = planeOtherWireLengths.begin(); planeOtherWireLengthIt != planeOtherWireLengths.end(); ++planeOtherWireLengthIt)
2148 std::cout <<
"Plane " << planeOtherWireLengthIt->first <<
" has " << planeWireLength[planeOtherWireLengthIt->first] <<
" wire width and therefore has relative width in wire of " << planeOtherWireLengthIt->second << std::endl;
2150 std::map<double,int> wireWidthMap;
2152 double wireWidth = planeWireLength.at(showerHitsIt->first);
2153 wireWidthMap[wireWidth] = showerHitsIt->first;
2156 return wireWidthMap.begin()->second;
2175 for (Int_t i=0; i<
n; i++) {
2177 sumx2 += x[i]*x[i]*w[i];
2179 sumy2 += y[i]*y[i]*w[i];
2180 sumxy += x[i]*y[i]*w[i];
2184 if (sumx2*sumw-sumx*sumx==0.)
return 1;
2185 if (sumx2-sumx*sumx/sumw==0.)
return 1;
2187 parm[0] = (sumy*sumx2-sumx*sumxy)/(sumx2*sumw-sumx*sumx);
2188 parm[1] = (sumxy-sumx*sumy/sumw)/(sumx2-sumx*sumx/sumw);
2190 eparm[0] = sumx2*(sumx2*sumw-sumx*sumx);
2191 eparm[1] = (sumx2-sumx*sumx/sumw);
2193 if (eparm[0]<0. || eparm[1]<0.)
return 1;
2195 eparm[0] = sqrt(eparm[0])/(sumx2*sumw-sumx*sumx);
2196 eparm[1] = sqrt(eparm[1])/(sumx2-sumx*sumx/sumw);
2204 if (!
hits.size())
return false;
2205 if (
hits.size()>2000)
return true;
2206 if (
hits.size()<20)
return true;
2207 std::map<int, int> hitmap;
2212 ++hitmap[
hit->WireID().Wire];
2213 if (nhits==20)
break;
2216 if (
float(nhits-2)/hitmap.size()>1.4)
return false;
2309 std::map<int,double> trackMap;
2312 int trackID = FindParticleID(hit);
2313 trackMap[trackID] += hit->
Integral();
2317 double highestCharge = 0;
2318 int showerTrack = 0;
2320 if (trackIt->second > highestCharge) {
2321 highestCharge = trackIt->second;
2322 showerTrack = trackIt->first;
2334 double particleEnergy = 0;
2335 int likelyTrackID = 0;
2336 std::vector<sim::TrackIDE> trackIDs = bt_serv->HitToTrackIDEs(hit);
2337 for (
unsigned int idIt = 0; idIt < trackIDs.size(); ++idIt) {
2338 if (trackIDs.at(idIt).energy > particleEnergy) {
2339 particleEnergy = trackIDs.at(idIt).energy;
2340 likelyTrackID = TMath::Abs(trackIDs.at(idIt).trackID);
2344 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
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.
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
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)
std::vector< Vector_t > convertCollToVector(std::vector< Vector > const &coll)
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)
TrackTrajectory::Flags_t Flags_t
bool CheckShowerHits(std::map< int, std::vector< art::Ptr< recob::Hit > > > const &showerHitsMap)
Vector_t VertexDirection() const
Access to track direction at different points.
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.
A trajectory in space reconstructed from hits.
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.
Point_t const & Vertex() const
Access to track position at different points.
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)
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
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
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)