27 #include "TMathBase.h" 28 #include "TMultiGraph.h" 31 #include "range/v3/numeric.hpp" 32 #include "range/v3/view.hpp" 42 ,
fNfitpass{pset.get<
unsigned int>(
"Nfitpass")}
43 ,
fNfithits{pset.get<std::vector<unsigned int>>(
"Nfithits")}
44 ,
fToler{pset.get<std::vector<double>>(
"Toler")}
55 <<
"EMShowerAlg: fNfithits and fToler need to have size fNfitpass";
62 art::FindManyP<recob::Hit>
const& fmh,
63 art::FindManyP<recob::Track>
const& fmt,
64 std::map<
int, std::vector<int>>& clusterToTracks,
65 std::map<
int, std::vector<int>>& trackToClusters)
const 67 std::vector<int> clustersToIgnore = {-999};
69 clusters, fmh, fmt, clustersToIgnore, clusterToTracks, trackToClusters);
75 art::FindManyP<recob::Hit>
const& fmh,
76 art::FindManyP<recob::Track>
const& fmt,
77 std::vector<int>
const& clustersToIgnore,
78 std::map<
int, std::vector<int>>& clusterToTracks,
79 std::map<
int, std::vector<int>>& trackToClusters)
const 82 for (
auto const& clusterPtr : clusters) {
85 auto const& clusterHits = fmh.at(clusterPtr.key());
88 for (
auto const& clusterHitPtr : clusterHits) {
90 auto const& clusterHitTracks = fmt.at(clusterHitPtr.key());
91 if (clusterHitTracks.size() > 1) {
92 std::cout <<
"More than one track associated with this hit!\n";
96 if (clusterHitTracks.size() < 1)
continue;
98 auto const& clusterHitTrackPtr = clusterHitTracks[0];
101 std::cout <<
"Track " << clusterHitTrackPtr->ID() <<
" is too short! (" 102 << clusterHitTrackPtr->Length() <<
")\n";
107 int track = clusterHitTrackPtr.key();
108 int cluster = clusterPtr.key();
111 trackToClusters[track].push_back(cluster);
113 clusterToTracks[
cluster].push_back(track);
122 std::map<int, std::vector<int>> firstTPC;
123 for (
auto const& [plane, hits] : showerHitsMap)
124 firstTPC[hits.at(0)->WireID().TPC].push_back(plane);
127 if (firstTPC.size() != 2)
return;
130 else if (firstTPC.size() > 2)
136 int problemPlane = -1;
138 if (planes.size() == 1) problemPlane = planes[0];
141 if (showerHitsMap.at(problemPlane).size() < 3)
return;
144 std::vector<int> otherPlanes;
146 if (plane != problemPlane and showerHitsMap.count(plane) and
147 showerHitsMap.at(plane).size() >= 3)
148 otherPlanes.push_back(plane);
150 if (otherPlanes.size() == 0)
return;
153 unsigned int wrongTPC = showerHitsMap.at(problemPlane).at(0)->WireID().TPC;
154 unsigned int nHits = 0;
156 hitIt != showerHitsMap.at(problemPlane).end() and (*hitIt)->WireID().TPC == wrongTPC;
161 if (nHits > 2)
return;
164 std::map<int, int> otherTPCs;
166 std::next(showerHitsMap.at(problemPlane).begin(), nHits);
167 hitIt != showerHitsMap.at(problemPlane).end() and
168 std::distance(std::next(showerHitsMap.at(problemPlane).begin(), nHits), hitIt) < 4 * nHits;
170 ++otherTPCs[(*hitIt)->WireID().TPC];
172 if (otherTPCs.size() > 1)
return;
175 std::map<int, int> tpcCount;
176 for (
int const otherPlane : otherPlanes)
178 std::next(showerHitsMap.at(otherPlane).begin());
179 hitIt != showerHitsMap.at(otherPlane).end() and
180 hitIt != std::next(showerHitsMap.at(otherPlane).begin(), 2);
182 ++tpcCount[(*hitIt)->WireID().TPC];
185 if (tpcCount.size() == 1 and
186 tpcCount.begin()->first ==
187 (
int)(*std::next(showerHitsMap.at(problemPlane).begin(), nHits))->WireID().TPC) {
188 std::vector<art::Ptr<recob::Hit>> naughty_hits;
190 hitIt != std::next(showerHitsMap.at(problemPlane).begin(), nHits);
192 naughty_hits.push_back(*hitIt);
193 showerHitsMap.at(problemPlane).erase(hitIt);
195 for (
auto const& naughty_hit : naughty_hits)
196 showerHitsMap.at(problemPlane).push_back(naughty_hit);
205 bool consistencyCheck =
true;
207 if (showerHitsMap.size() < 2) { consistencyCheck =
true; }
208 else if (showerHitsMap.size() == 2) {
214 std::vector<art::Ptr<recob::Hit>> startHits;
215 std::vector<int> planes;
216 for (
auto const& [plane, hits] : showerHitsMap) {
217 startHits.push_back(hits.front());
218 planes.push_back(plane);
221 TVector3 showerStartPos =
Construct3DPoint_(detProp, startHits.at(0), startHits.at(1));
225 double timingDifference =
std::abs(startHits.at(0)->PeakTime() - startHits.at(1)->PeakTime());
226 double projectionDifference = ((
HitPosition_(detProp, *startHits.at(0)) - proj1).Mod() +
227 (
HitPosition_(detProp, *startHits.at(1)) - proj2).Mod()) /
230 if (timingDifference > 40 or projectionDifference > 5 or showerStartPos.X() == -9999 or
231 showerStartPos.Y() == -9999 or showerStartPos.Z() == -9999)
232 consistencyCheck =
false;
235 std::cout <<
"Timing difference is " << timingDifference <<
" and projection distance is " 236 << projectionDifference <<
" (start is (" << showerStartPos.X() <<
", " 237 << showerStartPos.Y() <<
", " << showerStartPos.Z() <<
")\n";
239 else if (showerHitsMap.size() == 3) {
245 std::map<int, art::Ptr<recob::Hit>> start2DMap;
246 for (
auto const& [plane, hits] : showerHitsMap) {
247 start2DMap[plane] = hits.front();
250 std::map<int, double> projDiff;
251 std::map<int, double> timingDiff;
253 for (
int plane = 0; plane < 3; ++plane) {
255 std::vector<int> otherPlanes;
256 for (
int otherPlane = 0; otherPlane < 3; ++otherPlane)
257 if (otherPlane != plane) otherPlanes.push_back(otherPlane);
260 detProp, start2DMap.at(otherPlanes.at(0)), start2DMap.at(otherPlanes.at(1)));
264 std::cout <<
"Plane... " << plane;
265 std::cout <<
"\nStart position in this plane is " 267 <<
HitPosition_(detProp, *start2DMap.at(plane)).
Y() <<
")\n";
268 std::cout <<
"Shower start from other two planes is (" << showerStartPos.X() <<
", " 269 << showerStartPos.Y() <<
", " << showerStartPos.Z() <<
")\n";
270 std::cout <<
"Projecting the other two planes gives position (" << showerStartProj.X()
271 <<
", " << showerStartProj.Y() <<
")\n";
276 double timeDiff = TMath::Max(
277 std::abs(start2DMap.at(plane)->PeakTime() - start2DMap.at(otherPlanes.at(0))->PeakTime()),
278 std::abs(start2DMap.at(plane)->PeakTime() - start2DMap.at(otherPlanes.at(1))->PeakTime()));
281 std::cout <<
"Plane " << plane <<
" has projDiff " << projDiff <<
" and timeDiff " 284 if (projDiff > 5 or timeDiff > 40) consistencyCheck =
false;
288 if (
fDebug > 1) std::cout <<
"Consistency check is " << consistencyCheck <<
'\n';
290 return consistencyCheck;
296 art::FindManyP<recob::Hit>
const& fmh)
const 298 std::vector<int> clustersToIgnore;
301 for (
auto initialShowerIt = initialShowers.cbegin(); initialShowerIt != initialShowers.cend();
304 if (
std::distance(initialShowers.cbegin(), initialShowerIt) > 0)
continue;
307 std::map<int, std::vector<art::Ptr<recob::Cluster>>> planeClusters;
308 std::map<int, std::vector<art::Ptr<recob::Hit>>> planeHits;
309 for (
int const clusterIndex : *initialShowerIt) {
311 planeClusters[cluster->
Plane().
Plane].push_back(cluster);
312 for (
auto const&
hit : fmh.at(cluster.
key()))
313 planeHits[
hit->WireID().Plane].push_back(
hit);
316 TFile*
outFile =
new TFile(
"chargeDistributions.root",
"RECREATE");
317 std::map<int, TH1D*> chargeDist;
318 for (
auto const& [plane, clusterPtrs] : planeClusters) {
319 for (
auto const& clusterPtr : clusterPtrs) {
327 auto const& hits = fmh.at(clusterPtr.key());
328 for (
auto const&
hit : hits | views::transform(
to_element)) {
329 chargeDist[plane]->Fill(
hit.Integral());
332 chargeDist[plane]->Write();
339 if (planeClusters.size() < 3)
continue;
342 std::map<int, std::vector<double>> planeClusterSizes;
344 planeClusters.begin();
345 planeClustersIt != planeClusters.end();
348 planeClustersIt->second.begin();
349 planeClusterIt != planeClustersIt->second.end();
351 std::vector<art::Ptr<recob::Hit>> hits = fmh.at(planeClusterIt->key());
352 planeClusterSizes[planeClustersIt->first].push_back(
353 (
double)hits.size() / (double)planeHits.at(planeClustersIt->first).size());
358 std::map<int, double> planeClustersAvSizes;
359 for (
auto const& [plane, cluster_sizes] : planeClusterSizes) {
360 double const average = accumulate(cluster_sizes, 0.) / cluster_sizes.size();
361 planeClustersAvSizes[plane] =
average;
367 for (
auto const [plane,
avg] : planeClustersAvSizes) {
370 std::vector<double> otherAverages;
371 for (
auto const [other_plane, other_avg] : planeClustersAvSizes)
372 if (plane != other_plane) otherAverages.push_back(other_avg);
374 double const sumSquareAvgsOtherPlanes = accumulate(
375 otherAverages, 0., [](
double sum,
double avg) {
return sum +
cet::square(avg); });
376 double const quadOtherPlanes = std::sqrt(sumSquareAvgsOtherPlanes);
380 if (avg >= quadOtherPlanes) badPlane = plane;
383 if (badPlane != -1) {
384 if (
fDebug > 1) std::cout <<
"Bad plane is " << badPlane <<
'\n';
385 for (
auto const&
cluster : planeClusters.at(badPlane))
386 clustersToIgnore.push_back(
cluster.key());
390 return clustersToIgnore;
408 return TVector3(x, intersection.
y, intersection.
z);
411 std::unique_ptr<recob::Track>
415 std::map<int, TVector2>
const& showerCentreMap)
const 418 std::unique_ptr<recob::Track> track;
420 std::vector<art::Ptr<recob::Hit>> track1, track2;
423 if ((*hits1.begin())->
WireID().TPC != (*hits2.begin())->
WireID().TPC) {
424 mf::LogWarning(
"EMShowerAlg") <<
"Warning: attempting to construct a track from two different " 425 "TPCs. Returning a null track.";
430 std::map<int, int> tpcMap;
431 for (
auto const&
hit : hits1)
432 ++tpcMap[
hit->WireID().TPC];
433 for (
auto const&
hit : hits2)
434 ++tpcMap[
hit->WireID().TPC];
435 if (tpcMap.size() > 1) {
437 <<
"Warning: attempting to construct a track which crosses more than one TPC -- PMTrack " 438 "can't handle this right now. Returning a track made just from hits in the first TPC it " 440 unsigned int firstTPC1 = hits1.at(0)->WireID().TPC, firstTPC2 = hits2.at(0)->WireID().TPC;
441 for (
auto const&
hit : hits1)
442 if (
hit->WireID().TPC == firstTPC1) track1.push_back(
hit);
443 for (
auto const&
hit : hits2)
444 if (
hit->WireID().TPC == firstTPC2) track2.push_back(
hit);
452 std::cout <<
"About to make a track from these hits:\n";
453 auto print_hits = [
this](
auto const& track) {
454 for (
auto const&
hit : track | views::transform(
to_element)) {
456 <<
") (real wire " <<
hit.WireID().Wire <<
") in TPC " <<
hit.WireID().TPC
468 mf::LogInfo(
"EMShowerAlg") <<
"Skipping this event because not enough hits in two views";
472 std::vector<TVector3> xyz, dircos;
474 for (
unsigned int i = 0; i < pmatrack->size(); i++) {
476 xyz.push_back((*pmatrack)[i]->
Point3D());
478 if (i < pmatrack->
size() - 1) {
481 TVector3 dc(0., 0., 0.);
482 while ((mag == 0.0) and (j < pmatrack->
size())) {
483 dc = (*pmatrack)[j]->Point3D();
484 dc -= (*pmatrack)[i]->Point3D();
490 else if (!dircos.empty())
492 dircos.push_back(dc);
495 dircos.push_back(dircos.back());
499 std::map<int, double> distanceToVertex, distanceToEnd;
500 TVector3
vertex = *xyz.begin(),
end = *xyz.rbegin();
505 showerCentreIt != showerCentreMap.end();
513 distanceToVertex[showerCentreIt->first] = (vertexProj - showerCentreIt->second).Mod();
514 distanceToEnd[showerCentreIt->first] = (endProj - showerCentreIt->second).Mod();
518 double avDistanceToVertex = 0, avDistanceToEnd = 0;
520 distanceToVertexIt != distanceToVertex.end();
521 ++distanceToVertexIt)
522 avDistanceToVertex += distanceToVertexIt->second;
523 avDistanceToVertex /= distanceToVertex.size();
526 distanceToEndIt != distanceToEnd.end();
528 avDistanceToEnd += distanceToEndIt->second;
529 if (distanceToEnd.size() != 0) avDistanceToEnd /= distanceToEnd.size();
532 std::cout <<
"Distance to vertex is " << avDistanceToVertex <<
" and distance to end is " 533 << avDistanceToEnd <<
'\n';
536 if (avDistanceToEnd > avDistanceToVertex) {
539 dircos.begin(), dircos.end(), dircos.begin(), [](TVector3
const& vec) {
return -1 * vec; });
542 if (xyz.size() != dircos.size())
543 mf::LogError(
"EMShowerAlg") <<
"Problem converting pma::Track3D to recob::Track";
545 track = std::make_unique<recob::Track>(
560 std::unique_ptr<recob::Track>
565 std::map<int, TVector2> showerCentreMap;
573 std::unique_ptr<recob::Track>
const& track)
const 575 assert(not
empty(trackHits));
576 if (!track)
return -999;
578 recob::Hit const& firstHit = *trackHits.front();
593 double totalCharge = 0, totalDistance = 0, avHitTime = 0;
594 unsigned int nHits = 0;
596 for (
auto const&
hit : trackHits | views::transform(
to_element)) {
598 totalDistance += pitch;
599 totalCharge +=
hit.Integral();
600 avHitTime +=
hit.PeakTime();
605 avHitTime /= (double)nHits;
607 double const dQdx = totalCharge / totalDistance;
615 std::unique_ptr<recob::Track>& initialTrack,
626 std::cout <<
" ------------------ Finding initial track hits " 627 "-------------------- \n";
630 std::cout <<
"Here are the initial shower hits... \n";
631 for (
auto const& [plane, hitPtrs] : initialTrackHits) {
632 std::cout <<
" Plane " << plane <<
'\n';
633 for (
auto const&
hit : hitPtrs | views::transform(
to_element)) {
640 std::cout <<
" ------------------ End finding initial track hits " 641 "-------------------- \n";
644 if (
fDebug > 1) std::cout <<
" ------------------ Finding initial track -------------------- \n";
646 if (initialTrack and
fDebug > 1) {
647 std::cout <<
"The track start is (" << initialTrack->
Vertex().X() <<
", " 648 << initialTrack->
Vertex().Y() <<
", " << initialTrack->
Vertex().Z() <<
")\n";
649 std::cout <<
"The track direction is (" << initialTrack->
VertexDirection().X() <<
", " 654 std::cout <<
" ------------------ End finding initial track " 655 "-------------------- \n";
658 std::vector<art::Ptr<recob::Hit>>
661 bool perpendicular)
const 669 if (perpendicular) direction = direction.Rotate(TMath::Pi() / 2);
673 std::map<double, art::Ptr<recob::Hit>> hitProjection;
674 for (
auto const& hitPtr : hits) {
676 hitProjection[direction *
pos] = hitPtr;
680 std::vector<art::Ptr<recob::Hit>> showerHits;
682 hitProjection, std::back_inserter(showerHits), [](
auto const& pr) {
return pr.second; });
686 std::map<int, TGraph*> graphs;
687 for (
auto const&
hit : showerHits | views::transform(
to_element)) {
688 int tpc =
hit.WireID().TPC;
689 if (graphs[tpc] ==
nullptr) graphs[tpc] =
new TGraph();
690 graphs[tpc]->SetPoint(
693 TMultiGraph* multigraph =
new TMultiGraph();
696 graph->SetMarkerStyle(8);
697 graph->SetMarkerSize(2);
698 multigraph->Add(
graph);
700 TCanvas* canvas =
new TCanvas();
701 multigraph->Draw(
"AP");
703 line.SetLineColor(2);
704 line.DrawLine(centre.X() - 1000 * direction.X(),
705 centre.Y() - 1000 * direction.Y(),
706 centre.X() + 1000 * direction.X(),
707 centre.Y() + 1000 * direction.Y());
708 canvas->SaveAs(
"Gradient.png");
716 std::vector<std::vector<int>>
720 std::vector<std::vector<int>>
showers;
723 for (
auto const& clusters : trackToClusters |
views::values) {
726 std::vector<int> matchingShowers;
728 for (
int const cluster : clusters) {
731 matchingShowers.push_back(shower);
742 if (matchingShowers.size() < 1) showers.push_back(clusters);
746 for (
int const cluster : clusters) {
756 std::map<int, std::vector<art::Ptr<recob::Hit>>>
761 std::map<int, std::vector<art::Ptr<recob::Hit>>> initialHitsMap;
763 for (
auto const& [plane, orderedShower] : orderedShowerMap) {
764 std::vector<art::Ptr<recob::Hit>> initialHits;
767 bool wireDirection =
true;
768 std::vector<int> wires;
769 for (
auto const&
hit : orderedShower | views::transform(
to_element))
775 wireDirection =
false;
781 std::map<int, std::vector<art::Ptr<recob::Hit>>> wireHitMap;
782 int multipleWires = 0;
783 for (
auto const& hitPtr : orderedShower)
786 for (
auto const& hitPtr : orderedShower) {
788 if (wireHitMap[wire].
size() > 1) {
790 if (multipleWires > 5)
break;
793 else if ((increasing and wireHitMap[wire + 1].
size() > 1 and
794 (wireHitMap[wire + 2].
size() > 1 or wireHitMap[wire + 3].
size() > 1)) or
795 (!increasing and wireHitMap[wire - 1].
size() > 1 and
796 (wireHitMap[wire - 2].
size() > 1 or wireHitMap[wire - 3].
size() > 1))) {
798 (wireHitMap[wire + 4].
size() < 2 and wireHitMap[wire + 5].
size() < 2 and
799 wireHitMap[wire + 6].
size() < 2 and wireHitMap[wire + 9].
size() > 1)) or
801 (wireHitMap[wire - 4].
size() < 2 and wireHitMap[wire - 5].
size() < 2 and
802 wireHitMap[wire - 6].
size() < 2) and
803 wireHitMap[wire - 9].
size() > 1))
804 initialHits.push_back(hitPtr);
809 initialHits.push_back(hitPtr);
811 if (!initialHits.size()) initialHits.push_back(*orderedShower.begin());
818 std::map<int, std::vector<art::Ptr<recob::Hit>>> tickHitMap;
820 hitIt != orderedShower.end();
824 for (
auto const& hitPtr : orderedShower) {
826 if ((increasing and (tickHitMap[tick + 1].
size() or tickHitMap[tick + 2].
size() or
827 tickHitMap[tick + 3].
size() or tickHitMap[tick + 4].
size() or
828 tickHitMap[tick + 5].
size())) or
829 (!increasing and (tickHitMap[tick - 1].
size() or tickHitMap[tick - 2].
size() or
830 tickHitMap[tick - 3].
size() or tickHitMap[tick - 4].
size() or
831 tickHitMap[tick - 5].
size())))
834 initialHits.push_back(hitPtr);
836 if (initialHits.empty()) initialHits.push_back(*orderedShower.begin());
840 if (initialHits.size() == 1 and orderedShower.size() > 2)
841 initialHits.push_back(orderedShower[1]);
844 std::vector<art::Ptr<recob::Hit>> newInitialHits;
845 std::map<int, int> tpcHitMap;
846 std::vector<int> singleHitTPCs;
847 for (
auto const&
hit : initialHits | views::transform(
to_element))
848 ++tpcHitMap[
hit.WireID().TPC];
850 for (
auto const [tpc,
count] : tpcHitMap)
851 if (
count == 1) singleHitTPCs.push_back(tpc);
853 if (singleHitTPCs.size()) {
855 for (
int const tpc : singleHitTPCs)
856 std::cout <<
"Removed hits in TPC " << tpc <<
'\n';
858 for (
auto const& hitPtr : initialHits)
860 newInitialHits.push_back(hitPtr);
861 if (!newInitialHits.size()) newInitialHits.push_back(*orderedShower.begin());
864 newInitialHits = initialHits;
866 initialHitsMap[plane] = newInitialHits;
869 return initialHitsMap;
872 std::map<int, std::map<int, bool>>
879 std::map<int, std::map<int, bool>> permutations;
889 std::map<int, double> planeRMSGradients, planeRMS;
890 for (
auto const& [plane, hitPtrs] : showerHitsMap) {
896 std::map<double, int> gradientMap;
897 for (
int const plane : showerHitsMap |
views::keys)
898 gradientMap[
std::abs(planeRMSGradients.at(plane))] = plane;
903 for (
auto const [gradient, plane] : wireWidthMap)
904 std::cout <<
"Plane " << plane <<
" has relative width in wire of " << gradient
905 <<
"; and an RMS gradient of " << planeRMSGradients[plane] <<
'\n';
909 std::vector<std::map<int, bool>> usedPermutations;
912 for (
int const plane : showerHitsMap |
views::keys)
913 permutations[perm][plane] = 0;
918 std::map<int, bool> permutation;
919 permutation[plane] =
true;
921 if (plane != plane2) permutation[plane2] =
false;
924 permutations[perm] = permutation;
925 usedPermutations.push_back(permutation);
930 std::map<int, bool> permutation;
931 permutation[plane] =
false;
933 if (plane != plane2) permutation[plane2] =
true;
936 permutations[perm] = permutation;
937 usedPermutations.push_back(permutation);
943 for (
int const plane : showerHitsMap |
views::keys)
944 permutations[perm][plane] = 1;
948 std::cout <<
"Here are the permutations!\n";
949 for (
auto const& [
index, permutation] : permutations) {
950 std::cout <<
"Permutation " <<
index <<
'\n';
951 for (
auto const [plane,
value] : permutation)
952 std::cout <<
" Plane " << plane <<
" has value " <<
value <<
'\n';
959 std::unique_ptr<recob::Track>
966 if (initialHitsMap.size() < 2) {
967 mf::LogInfo(
"EMShowerAlg") <<
"Only one useful view for this shower; nothing can be done\n";
968 return std::unique_ptr<recob::Track>();
971 std::vector<std::pair<int, int>> initialHitsSize;
973 initialHitsMap.begin();
974 initialHitIt != initialHitsMap.end();
976 initialHitsSize.push_back(std::make_pair(initialHitIt->first, initialHitIt->second.size()));
979 std::sort(initialHitsSize.begin(),
980 initialHitsSize.end(),
981 [](std::pair<int, int>
const& size1, std::pair<int, int>
const& size2) {
982 return size1.second > size2.second;
990 std::vector<int> planes;
992 if (initialHitsSize.size() > 2 and !
CheckShowerHits_(detProp, showerHitsMap)) {
995 std::cout <<
"Igoring plane " << planeToIgnore <<
" in creation of initial track\n";
997 hitsSizeIt != initialHitsSize.end() and planes.size() < 2;
999 if (hitsSizeIt->first == planeToIgnore)
continue;
1000 planes.push_back(hitsSizeIt->first);
1004 planes = {initialHitsSize.at(0).first, initialHitsSize.at(1).first};
1006 return ConstructTrack(detProp, initialHitsMap.at(planes.at(0)), initialHitsMap.at(planes.at(1)));
1014 std::unique_ptr<recob::Track>
const& initialTrack,
1019 std::map<int, std::vector<art::Ptr<recob::Hit>>> planeHitsMap;
1020 for (
auto const& hitPtr : hits)
1021 planeHitsMap[hitPtr->View()].push_back(hitPtr);
1024 unsigned int highestNumberOfHits = 0;
1025 std::vector<double> totalEnergy, totalEnergyError,
dEdx, dEdxError;
1028 for (
unsigned int plane = 0; plane <
fGeom->
MaxPlanes(); ++plane) {
1031 if (planeHitsMap.count(plane)) {
1032 dEdx.push_back(
FinddEdx_(clockData, detProp, initialHitsMap.at(plane), initialTrack));
1033 totalEnergy.push_back(
1035 if (planeHitsMap.at(plane).size() > highestNumberOfHits and initialHitsMap.count(plane)) {
1037 highestNumberOfHits = planeHitsMap.at(plane).size();
1044 totalEnergy.push_back(0);
1048 TVector3
direction, directionError, showerStart, showerStartError;
1051 showerStart = initialTrack->
Vertex<TVector3>();
1055 std::cout <<
"Best plane is " << bestPlane;
1056 std::cout <<
"\ndE/dx for each plane is: " << dEdx[0] <<
", " << dEdx[1] <<
" and " << dEdx[2];
1057 std::cout <<
"\nTotal energy for each plane is: " << totalEnergy[0] <<
", " << totalEnergy[1]
1058 <<
" and " << totalEnergy[2];
1059 std::cout <<
"\nThe shower start is (" << showerStart.X() <<
", " << showerStart.Y() <<
", " 1060 << showerStart.Z() <<
")\n";
1061 std::cout <<
"The shower direction is (" << direction.X() <<
", " << direction.Y() <<
", " 1062 << direction.Z() <<
")\n";
1086 std::map<int, std::vector<art::Ptr<recob::Hit>>> planeHitsMap;
1087 for (
auto const& hitPtr : hits)
1088 planeHitsMap[hitPtr->WireID().Plane].push_back(hitPtr);
1090 std::vector<std::vector<art::Ptr<recob::Hit>>> initialTrackHits(3);
1094 unsigned maxhits0 = 0;
1095 unsigned maxhits1 = 0;
1098 planeHits != planeHitsMap.end();
1101 std::vector<art::Ptr<recob::Hit>> showerHits;
1104 if ((planeHits->second).size() > maxhits0) {
1106 maxhits1 = maxhits0;
1109 pl0 = planeHits->first;
1110 maxhits0 = (planeHits->second).
size();
1112 else if ((planeHits->second).size() > maxhits1) {
1113 pl1 = planeHits->first;
1114 maxhits1 = (planeHits->second).
size();
1117 if (pl0 != -1 && pl1 != -1 && initialTrackHits[pl0].
size() >= 2 &&
1118 initialTrackHits[pl1].size() >= 2 &&
1119 initialTrackHits[pl0][0]->WireID().TPC == initialTrackHits[pl1][0]->WireID().TPC) {
1125 std::vector<TVector3> spts;
1127 for (
size_t i = 0; i < pmatrack->
size(); ++i) {
1128 if ((*pmatrack)[i]->IsEnabled()) {
1129 TVector3 p3d = (*pmatrack)[i]->Point3D();
1130 spts.push_back(p3d);
1133 if (spts.size() >= 2) {
1134 TVector3 shwxyz, shwxyzerr;
1135 TVector3 shwdir, shwdirerr;
1136 std::vector<double> totalEnergy, totalEnergyError,
dEdx, dEdxError;
1137 int bestPlane = pl0;
1138 double minpitch = 1000;
1139 std::vector<TVector3> dirs;
1140 if ((spts[0] - vtx).Mag() < (spts.back() - vtx).Mag()) {
1143 if (spts.size() - 1 < 5) i = spts.size() - 1;
1144 shwdir = spts[i] - spts[0];
1145 shwdir = shwdir.Unit();
1148 shwxyz = spts.back();
1150 if (spts.size() > 6) i = spts.size() - 6;
1151 shwdir = spts[i] - spts[spts.size() - 1];
1152 shwdir = shwdir.Unit();
1154 for (
unsigned int plane = 0; plane <
fGeom->
MaxPlanes(); ++plane) {
1155 if (planeHitsMap.find(plane) != planeHitsMap.end()) {
1156 totalEnergy.push_back(
1160 totalEnergy.push_back(0);
1162 if (initialTrackHits[plane].
size()) {
1168 double angleToVert =
1170 initialTrackHits[plane][0]->WireID().planeID()) -
1172 double cosgamma =
std::abs(sin(angleToVert) * shwdir.Y() + cos(angleToVert) * shwdir.Z());
1173 if (cosgamma > 0) pitch = wirepitch / cosgamma;
1175 if (pitch < minpitch) {
1180 std::vector<float> vQ;
1181 for (
auto const&
hit : initialTrackHits[plane]) {
1182 int w1 =
hit->WireID().Wire;
1183 int w0 = initialTrackHits[plane][0]->WireID().Wire;
1185 vQ.push_back(
hit->Integral());
1186 totQ +=
hit->Integral();
1187 avgT +=
hit->PeakTime();
1192 double dQdx = TMath::Median(vQ.size(), &vQ[0]) / pitch;
1194 clockData, detProp, dQdx, avgT / nhits, initialTrackHits[plane][0]->
WireID().
Plane);
1197 dEdx.push_back(fdEdx);
1205 std::cout <<
"Best plane is " << bestPlane;
1206 std::cout <<
"\ndE/dx for each plane is: " << dEdx[0] <<
", " << dEdx[1] <<
" and " 1208 std::cout <<
"\nTotal energy for each plane is: " << totalEnergy[0] <<
", " 1209 << totalEnergy[1] <<
" and " << totalEnergy[2];
1210 std::cout <<
"\nThe shower start is (" << shwxyz.X() <<
", " << shwxyz.Y() <<
", " 1211 << shwxyz.Z() <<
")\n";
1229 std::vector<recob::SpacePoint>
1236 std::vector<recob::SpacePoint> spacePoints;
1250 std::vector<int> usedHits;
1255 showerHitIt != showerHits.end();
1259 std::vector<int> otherPlanes;
1260 for (
unsigned int otherPlane = 0; otherPlane <
fGeom->
MaxPlanes(); ++otherPlane)
1261 if ((
int)otherPlane != showerHitIt->first and showerHits.count(otherPlane))
1262 otherPlanes.push_back(otherPlane);
1265 if (otherPlanes.size() == 0)
return spacePoints;
1269 planeHitIt != showerHitIt->second.end();
1272 if (std::find(usedHits.begin(), usedHits.end(), planeHitIt->key()) != usedHits.end())
1276 const std::vector<art::Ptr<recob::Hit>> otherPlaneHits = showerHits.at(otherPlanes.at(0));
1278 otherPlaneHits.begin();
1279 otherPlaneHitIt != otherPlaneHits.end() and
1280 std::find(usedHits.begin(), usedHits.end(), planeHitIt->key()) == usedHits.end();
1281 ++otherPlaneHitIt) {
1283 if ((*otherPlaneHitIt)->WireID().TPC != (*planeHitIt)->WireID().TPC or
1284 std::find(usedHits.begin(), usedHits.end(), otherPlaneHitIt->key()) != usedHits.end())
1288 std::vector<art::Ptr<recob::Hit>> pointHits;
1289 bool truePoint =
false;
1291 if (otherPlanes.size() > 1) {
1294 const std::vector<art::Ptr<recob::Hit>> otherOtherPlaneHits =
1295 showerHits.at(otherPlanes.at(1));
1298 otherOtherPlaneHits.begin();
1299 otherOtherPlaneHitIt != otherOtherPlaneHits.end() and !truePoint;
1300 ++otherOtherPlaneHitIt) {
1302 if ((*otherOtherPlaneHitIt)->WireID().TPC == (*planeHitIt)->WireID().TPC and
1303 (projThirdPlane -
HitPosition_(detProp, **otherOtherPlaneHitIt)).Mod() <
1309 usedHits.push_back(planeHitIt->key());
1310 usedHits.push_back(otherPlaneHitIt->key());
1311 usedHits.push_back(otherOtherPlaneHitIt->key());
1313 pointHits.push_back(*planeHitIt);
1314 pointHits.push_back(*otherPlaneHitIt);
1315 pointHits.push_back(*otherOtherPlaneHitIt);
1329 usedHits.push_back(planeHitIt->key());
1330 usedHits.push_back(otherPlaneHitIt->key());
1332 pointHits.push_back(*planeHitIt);
1333 pointHits.push_back(*otherPlaneHitIt);
1338 double xyz[3] = {point.X(), point.Y(), point.Z()};
1346 spacePoints.emplace_back(xyz, xyzerr, chisq);
1347 hitAssns.push_back(pointHits);
1357 std::cout <<
"-------------------- Space points -------------------\n";
1358 std::cout <<
"There are " << spacePoints.size() <<
" space points:\n";
1361 spacePointIt != spacePoints.end();
1363 const double* xyz = spacePointIt->XYZ();
1364 std::cout <<
" Space point (" << xyz[0] <<
", " << xyz[1] <<
", " << xyz[2] <<
")\n";
1371 std::map<int, std::vector<art::Ptr<recob::Hit>>>
1374 int desired_plane)
const 1384 std::map<int, std::vector<art::Ptr<recob::Hit>>> showerHitsMap;
1385 for (
auto const& hitPtr : shower) {
1386 showerHitsMap[hitPtr->WireID().Plane].push_back(hitPtr);
1390 std::map<int, double> planeRMSGradients, planeRMS;
1391 for (
auto const& [plane, hits] : showerHitsMap) {
1392 if (desired_plane != plane and desired_plane != -1)
continue;
1393 std::vector<art::Ptr<recob::Hit>> orderedHits =
FindOrderOfHits_(detProp, hits);
1396 showerHitsMap[plane] = orderedHits;
1400 for (
auto const [plane, shower_hit_rms] : planeRMS) {
1401 std::cout <<
"Plane " << plane <<
" has RMS " << shower_hit_rms <<
" and RMS gradient " 1402 << planeRMSGradients.at(plane) <<
'\n';
1407 std::cout <<
"\nHits in order; after ordering, before reversing...\n";
1408 for (
auto const& [plane, hitPtrs] : showerHitsMap) {
1409 std::cout <<
" Plane " << plane <<
'\n';
1410 for (
auto const&
hit : hitPtrs | views::transform(
to_element)) {
1412 <<
") -- real wire " <<
hit.WireID() <<
", hit position (" 1423 std::map<int, double> planeOtherRMS, planeOtherRMSGradients;
1426 planeOtherRMS[planeRMSIt->first] = 0;
1427 planeOtherRMSGradients[planeRMSIt->first] = 0;
1428 int nOtherPlanes = 0;
1430 if (plane != planeRMSIt->first and planeRMS.count(plane)) {
1431 planeOtherRMS[planeRMSIt->first] += planeRMS.at(plane);
1432 planeOtherRMSGradients[planeRMSIt->first] += planeRMSGradients.at(plane);
1436 planeOtherRMS[planeRMSIt->first] /= (double)nOtherPlanes;
1437 planeOtherRMSGradients[planeRMSIt->first] /= (double)nOtherPlanes;
1442 for (
auto const& [plane, hitPtrs] : showerHitsMap) {
1443 if (planeRMS.at(plane) > planeOtherRMS.at(plane) * 2) {
1444 if (
fDebug > 1) std::cout <<
"Plane " << plane <<
" was perpendicular... recalculating\n";
1445 std::vector<art::Ptr<recob::Hit>> orderedHits =
1447 showerHitsMap[plane] = orderedHits;
1455 std::cout <<
"Before reversing, here are the start and end points...\n";
1456 for (
auto const& [plane, hitPtrs] : showerHitsMap) {
1457 std::cout <<
" Plane " << plane <<
" has start (" <<
HitCoordinates_(*hitPtrs.front()).
X()
1459 << hitPtrs.front()->WireID() <<
") and end (" 1462 << hitPtrs.back()->WireID() <<
")\n";
1468 showerHitsMap.begin();
1469 showerHitsIt != showerHitsMap.end();
1471 double gradient = planeRMSGradients.at(showerHitsIt->first);
1472 if (gradient < 0)
std::reverse(showerHitsIt->second.begin(), showerHitsIt->second.end());
1476 std::cout <<
"\nHits in order; after reversing, before checking isolated hits...\n";
1478 showerHitsMap.begin();
1479 showerHitsIt != showerHitsMap.end();
1481 std::cout <<
" Plane " << showerHitsIt->first <<
'\n';
1483 hitIt != showerHitsIt->second.end();
1486 <<
HitCoordinates_(**hitIt).Y() <<
") -- real wire " << (*hitIt)->WireID()
1487 <<
", hit position (" <<
HitPosition_(detProp, **hitIt).X() <<
", " 1495 std::cout <<
"\nHits in order; after checking isolated hits...\n";
1497 showerHitsMap.begin();
1498 showerHitsIt != showerHitsMap.end();
1500 std::cout <<
" Plane " << showerHitsIt->first <<
'\n';
1502 hitIt != showerHitsIt->second.end();
1505 <<
HitCoordinates_(**hitIt).Y() <<
") -- real wire " << (*hitIt)->WireID()
1506 <<
", hit position (" <<
HitPosition_(detProp, **hitIt).X() <<
", " 1512 std::cout <<
"After reversing and checking isolated hits, here are the " 1513 "start and end points...\n";
1515 showerHitsMap.begin();
1516 showerHitsIt != showerHitsMap.end();
1518 std::cout <<
" Plane " << showerHitsIt->first <<
" has start (" 1521 << showerHitsIt->second.front()->WireID() <<
") and end (" 1529 std::vector<int> badPlanes;
1530 if (
fDebug > 1) std::cout <<
"Here are the relative wire widths... \n";
1531 for (
auto const [relative_wire_width, plane] : wireWidths) {
1533 std::cout <<
"Plane " << plane <<
" has relative wire width " << relative_wire_width <<
'\n';
1534 if (relative_wire_width < 1 / (
double)wireWidths.size()) badPlanes.push_back(plane);
1537 std::map<int, std::vector<art::Ptr<recob::Hit>>> ignoredPlanes;
1538 if (badPlanes.size() == 1) {
1539 int const badPlane = badPlanes[0];
1540 if (
fDebug > 1) std::cout <<
"Ignoring plane " << badPlane <<
" when orientating\n";
1541 ignoredPlanes[badPlane] = showerHitsMap.at(badPlane);
1542 showerHitsMap.erase(badPlane);
1550 auto const originalShowerHitsMap = showerHitsMap;
1554 n < TMath::Power(2, (
int)showerHitsMap.size())) {
1555 if (
fDebug > 1) std::cout <<
"Permutation " << n <<
'\n';
1556 for (
int const plane : showerHitsMap |
views::keys) {
1557 auto hits = originalShowerHitsMap.at(plane);
1558 if (permutations[n][plane] == 1) {
std::reverse(hits.begin(), hits.end()); }
1559 showerHitsMap[plane] = hits;
1565 if (!
CheckShowerHits_(detProp, showerHitsMap)) showerHitsMap = originalShowerHitsMap;
1568 std::cout <<
"End of OrderShowerHits: here are the order of hits:\n";
1569 for (
auto const& [plane, hitPtrs] : showerHitsMap) {
1570 std::cout <<
" Plane " << plane <<
'\n';
1571 for (
auto const&
hit : hitPtrs | views::transform(
to_element)) {
1580 if (ignoredPlanes.size())
1581 showerHitsMap[ignoredPlanes.begin()->first] = ignoredPlanes.begin()->second;
1583 return showerHitsMap;
1603 for (
auto&
hit : showerHits) {
1604 if (
hit->WireID().TPC == tpc.
TPC) {
1614 if ((coord1 - coordvtx).Mod() < (coord0 - coordvtx).Mod()) {
1632 std::map<geo::TPCID, unsigned int> tpcmap;
1633 unsigned maxhits = 0;
1634 for (
auto const&
hit : showerHits) {
1637 for (
auto const&
t : tpcmap) {
1638 if (
t.second > maxhits) {
1648 std::vector<double> wfit;
1649 std::vector<double> tfit;
1650 std::vector<double> cfit;
1652 for (
size_t i = 0; i <
fNfitpass; ++i) {
1655 unsigned int nhits = 0;
1656 for (
auto&
hit : showerHits) {
1657 if (
hit->WireID().TPC == tpc.
TPC) {
1660 (
std::abs((coord.Y() - (parm[0] + coord.X() * parm[1])) * cos(atan(parm[1]))) <
1665 wfit.push_back(coord.X());
1666 tfit.push_back(coord.Y());
1668 if (i == fNfitpass - 1) { trackHits.push_back(
hit); }
1673 if (i < fNfitpass - 1 && wfit.size()) {
1674 fitok =
WeightedFit(wfit.size(), &wfit[0], &tfit[0], &cfit[0], &parm[0]);
1698 TVector2
const&
pos,
1707 double globalWire = -999;
1711 double wireCentre[3];
1713 if (wireID.
TPC % 2 == 0)
1727 if (wireID.
TPC == 0 or wireID.
TPC == 1)
1728 globalWire = wireID.
Wire;
1729 else if (wireID.
TPC == 2 or wireID.
TPC == 3 or wireID.
TPC == 4 or wireID.
TPC == 5)
1730 globalWire = nwires + wireID.
Wire;
1731 else if (wireID.
TPC == 6 or wireID.
TPC == 7)
1735 <<
"Error when trying to find a global induction plane coordinate for TPC " << wireID.
TPC 1741 int block = wireID.
TPC / 4;
1742 globalWire = (nwires * block) + wireID.
Wire;
1745 double wireCentre[3];
1747 if (wireID.
TPC % 2 == 0)
1759 std::map<double, int>
1765 std::map<int, int> planeWireLength;
1767 showerHitsMap.begin();
1768 showerHitsIt != showerHitsMap.end();
1770 planeWireLength[showerHitsIt->first] =
1775 std::map<int, double> planeOtherWireLengths;
1777 planeWireLengthIt != planeWireLength.end();
1778 ++planeWireLengthIt) {
1781 if (plane != planeWireLengthIt->first and planeWireLength.count(plane))
1783 quad = std::sqrt(quad);
1784 planeOtherWireLengths[planeWireLengthIt->first] =
1785 planeWireLength[planeWireLengthIt->first] / (double)quad;
1789 std::map<double, int> wireWidthMap;
1791 showerHitsMap.begin();
1792 showerHitsIt != showerHitsMap.end();
1794 wireWidthMap[planeOtherWireLengths.at(showerHitsIt->first)] = showerHitsIt->first;
1796 return wireWidthMap;
1806 double sumx = 0., sumy = 0., sumx2 = 0., sumxy = 0., sumweight = 0.;
1808 hit != showerHits.end();
1814 sumx += weight * pos.X();
1815 sumy += weight * pos.Y();
1816 sumx2 += weight * pos.X() * pos.X();
1817 sumxy += weight * pos.X() * pos.Y();
1819 double gradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
1820 TVector2
direction = TVector2(1, gradient).Unit();
1830 TVector2
pos, chargePoint = TVector2(0, 0);
1831 double totalCharge = 0;
1833 hit != showerHits.end();
1836 chargePoint += (*hit)->Integral() *
pos;
1837 totalCharge += (*hit)->Integral();
1839 TVector2 centre = chargePoint / totalCharge;
1852 std::vector<double> distanceToAxis;
1854 showerHitsIt != showerHits.end();
1856 TVector2 proj = (
HitPosition_(detProp, **showerHitsIt) - centre).Proj(direction) + centre;
1857 distanceToAxis.push_back((
HitPosition_(detProp, **showerHitsIt) - proj).Mod());
1859 double RMS = TMath::RMS(distanceToAxis.begin(), distanceToAxis.end());
1874 double lengthOfShower =
1876 double lengthOfSegment = lengthOfShower / (double)nShowerSegments;
1877 std::map<int, std::vector<art::Ptr<recob::Hit>>> showerSegments;
1878 std::map<int, double> segmentCharge;
1879 for (
auto const& hitPtr : showerHits) {
1880 auto const&
hit = *hitPtr;
1884 showerSegments[segment].push_back(hitPtr);
1885 segmentCharge[segment] +=
hit.Integral();
1888 TGraph*
graph =
new TGraph();
1889 std::vector<std::pair<int, double>> binVsRMS;
1893 for (
auto const& [segment, hitPtrs] : showerSegments) {
1896 TVector2 meanPosition(0, 0);
1897 for (
auto const&
hit : hitPtrs | views::transform(
to_element))
1899 meanPosition /= (double)hitPtrs.size();
1902 std::vector<double> distanceToAxisBin;
1903 for (
auto const&
hit : hitPtrs | views::transform(
to_element)) {
1904 TVector2 proj = (
HitPosition_(detProp,
hit) - meanPosition).Proj(direction) + meanPosition;
1905 distanceToAxisBin.push_back((
HitPosition_(detProp,
hit) - proj).Mod());
1908 double RMSBin = TMath::RMS(distanceToAxisBin.begin(), distanceToAxisBin.end());
1909 binVsRMS.emplace_back(segment, RMSBin);
1914 double sumx = 0., sumy = 0., sumx2 = 0., sumxy = 0., sumweight = 0.;
1915 for (
auto const [
bin, RMSBin] : binVsRMS) {
1918 sumx += weight *
bin;
1919 sumy += weight * RMSBin;
1920 sumx2 += weight * bin *
bin;
1921 sumxy += weight * bin * RMSBin;
1923 double RMSgradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
1926 TVector2 direction = TVector2(1, RMSgradient).Unit();
1927 TCanvas* canv =
new TCanvas();
1929 graph->GetXaxis()->SetTitle(
"Shower segment");
1930 graph->GetYaxis()->SetTitle(
"RMS of hit distribution");
1931 TVector2 centre = TVector2(graph->GetMean(1), graph->GetMean(2));
1933 line.SetLineColor(2);
1934 line.DrawLine(centre.X() - 1000 * direction.X(),
1935 centre.Y() - 1000 * direction.Y(),
1936 centre.X() + 1000 * direction.X(),
1937 centre.Y() + 1000 * direction.Y());
1938 canv->SaveAs(
"RMSGradient.png");
1948 TVector3
const& point,
1953 TVector2 wireTickPos = TVector2(-999., -999.);
1955 double pointPosition[3] = {point.X(), point.Y(), point.Z()};
1984 std::map<int, int> planeWireLength;
1985 std::map<int, double> planeOtherWireLengths;
1986 for (
auto const& [plane, hits] : showerHitsMap)
1987 planeWireLength[plane] =
1990 planeWireLengthIt != planeWireLength.end();
1991 ++planeWireLengthIt) {
1994 if (plane != planeWireLengthIt->first and planeWireLength.count(plane))
1996 quad = std::sqrt(quad);
1997 planeOtherWireLengths[planeWireLengthIt->first] =
1998 planeWireLength[planeWireLengthIt->first] / (double)quad;
2002 for (
auto const [plane, relative_width] : planeOtherWireLengths) {
2003 std::cout <<
"Plane " << plane <<
" has " << planeWireLength[plane]
2004 <<
" wire width and therefore has relative width in wire of " << relative_width
2008 std::map<double, int> wireWidthMap;
2009 for (
int const plane : showerHitsMap |
views::keys) {
2010 double wireWidth = planeWireLength.at(plane);
2011 wireWidthMap[wireWidth] = plane;
2014 return wireWidthMap.begin()->second;
2022 Double_t* parm)
const 2026 Double_t sumx2 = 0.;
2028 Double_t sumy2 = 0.;
2029 Double_t sumxy = 0.;
2038 for (Int_t i = 0; i <
n; i++) {
2039 sumx += x[i] * w[i];
2040 sumx2 += x[i] * x[i] * w[i];
2041 sumy += y[i] * w[i];
2042 sumy2 += y[i] * y[i] * w[i];
2043 sumxy += x[i] * y[i] * w[i];
2047 if (sumx2 * sumw - sumx * sumx == 0.)
return 1;
2048 if (sumx2 - sumx * sumx / sumw == 0.)
return 1;
2050 parm[0] = (sumy * sumx2 - sumx * sumxy) / (sumx2 * sumw - sumx * sumx);
2051 parm[1] = (sumxy - sumx * sumy / sumw) / (sumx2 - sumx * sumx / sumw);
2053 eparm[0] = sumx2 * (sumx2 * sumw - sumx * sumx);
2054 eparm[1] = (sumx2 - sumx * sumx / sumw);
2056 if (eparm[0] < 0. || eparm[1] < 0.)
return 1;
2058 eparm[0] = sqrt(eparm[0]) / (sumx2 * sumw - sumx * sumx);
2059 eparm[1] = sqrt(eparm[1]) / (sumx2 - sumx * sumx / sumw);
2067 if (hits.empty())
return false;
2068 if (hits.size() > 2000)
return true;
2069 if (hits.size() < 20)
return true;
2071 std::map<int, int> hitmap;
2073 for (
auto const&
hit : hits | views::transform(
to_element)) {
2075 if (nhits > 2) ++hitmap[
hit.WireID().Wire];
2076 if (nhits == 20)
break;
2078 if (
float(nhits - 2) / hitmap.size() > 1.4)
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
void XYZ(double *xyz) const
Legacy method to access vertex position, preserved to avoid breaking code. Please try to use Vertex::...
TVector2 HitPosition_(detinfo::DetectorPropertiesData const &detProp, recob::Hit const &hit) const
Return the coordinates of this hit in units of cm.
std::vector< recob::SpacePoint > MakeSpacePoints(detinfo::DetectorPropertiesData const &detProp, std::map< int, std::vector< art::Ptr< recob::Hit >>> const &hits, std::vector< std::vector< art::Ptr< recob::Hit >>> &hitAssns) const
Makes space points from the shower hits in each plane.
void FindInitialTrackHits(std::vector< art::Ptr< recob::Hit >> const &showerHits, art::Ptr< recob::Vertex > const &vertex, std::vector< art::Ptr< recob::Hit >> &trackHits) const
<Tingjun to="" document>="">
int WorstPlane_(const std::map< int, std::vector< art::Ptr< recob::Hit >>> &showerHitsMap) const
Returns the plane which is determined to be the least likely to be correct.
double z
z position of intersection
void cluster(In first, In last, Out result, Pred *pred)
shower::ShowerEnergyAlg const fShowerEnergyAlg
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
constexpr to_element_t to_element
pma::ProjectionMatchingAlg const fProjectionMatchingAlg
double ShowerEnergy(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &hits, geo::PlaneID::PlaneID_t plane) const
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
recob::Shower MakeShower(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, art::PtrVector< recob::Hit > const &hits, std::unique_ptr< recob::Track > const &initialTrack, std::map< int, std::vector< art::Ptr< recob::Hit >>> const &initialTrackHits) const
Makes a recob::Shower object given the hits in the shower and the initial track-like part...
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
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
::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.
TrackTrajectory::Flags_t Flags_t
def graph(desc, maker=maker)
Vector_t VertexDirection() const
CryostatID_t Cryostat
Index of cryostat.
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) const
Map associated tracks and clusters together given their associated hits.
std::map< int, std::map< int, bool > > GetPlanePermutations_(const detinfo::DetectorPropertiesData &detProp, const std::map< int, std::vector< art::Ptr< recob::Hit >>> &showerHitsMap) const
double GlobalWire_(const geo::WireID &wireID) const
Find the global wire position.
geo::View_t View() const
View for the plane of the hit.
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.
double const fdEdxTrackLength
unsigned int const fNfitpass
TVector2 ShowerCenter_(detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &showerHits) const
Returns the charge-weighted shower center.
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
std::vector< std::vector< int > > FindShowers(std::map< int, std::vector< int >> const &trackToClusters) const
Makes showers given a map between tracks and all clusters associated with them.
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.
std::vector< double > const fToler
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
void sort_all(RandCont &)
bool const fMakeRMSGradientPlot
void CheckIsolatedHits_(std::map< int, std::vector< art::Ptr< recob::Hit >>> &showerHitsMap) const
View_t View() const
Which coordinate does this plane measure.
std::vector< unsigned int > const fNfithits
Int_t WeightedFit(const Int_t n, const Double_t *x, const Double_t *y, const Double_t *w, Double_t *parm) const
<Tingjun to="" document>="">
double dEdx(float dqdx, float Efield)
fInnerVessel push_back(Point(-578.400000, 0.000000, 0.000000))
TVector3 Construct3DPoint_(detinfo::DetectorPropertiesData const &detProp, art::Ptr< recob::Hit > const &hit1, art::Ptr< recob::Hit > const &hit2) const
Constructs a 3D point (in [cm]) to represent the hits given in two views.
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
bool search_all(FwdCont const &, Datum const &)
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
Signal from induction planes.
Collection of exceptions for Geometry system.
A trajectory in space reconstructed from hits.
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) const
Takes the initial showers found and tries to resolve issues where one bad view ruins the event...
key_type key() const noexcept
Point_t const & Vertex() const
std::unique_ptr< recob::Track > ConstructTrack(detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &track1, std::vector< art::Ptr< recob::Hit >> const &track2, std::map< int, TVector2 > const &showerCentreMap) const
bool isNull() const noexcept
std::map< int, std::vector< art::Ptr< recob::Hit > > > OrderShowerHits(detinfo::DetectorPropertiesData const &detProp, art::PtrVector< recob::Hit > const &shower, int plane) const
Takes the hits associated with a shower and orders them so they follow the direction of the shower...
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
double ConvertXToTicks(double X, int p, int t, int c) const
double ShowerHitRMS_(detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &showerHits) const
double const fMinTrackLength
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
pma::Track3D * buildSegment(const detinfo::DetectorPropertiesData &clockData, const std::vector< art::Ptr< recob::Hit >> &hits_1, const std::vector< art::Ptr< recob::Hit >> &hits_2={}) const
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
auto transform_all(Container &, OutputIt, UnaryOp)
bool isCleanShower(std::vector< art::Ptr< recob::Hit >> const &hits) const
<Tingjun to="" document>="">
bool const fMakeGradientPlot
TVector2 Project3DPointOntoPlane_(detinfo::DetectorPropertiesData const &detProp, TVector3 const &point, int plane, int cryostat=0) const
EMShowerAlg(fhicl::ParameterSet const &pset, int debug=0)
TVector2 ShowerDirection_(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &showerHits) const
void FindInitialTrack(detinfo::DetectorPropertiesData const &detProp, std::map< int, std::vector< art::Ptr< recob::Hit >>> const &hits, std::unique_ptr< recob::Track > &initialTrack, std::map< int, std::vector< art::Ptr< recob::Hit >>> &initialTrackHits, int plane) const
Detector simulation of raw signals on wires.
bool CheckShowerHits_(detinfo::DetectorPropertiesData const &detProp, std::map< int, std::vector< art::Ptr< recob::Hit >>> const &showerHitsMap) const
double ConvertTicksToX(double ticks, int p, int t, int c) const
void OrderShowerHits_(detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &shower, std::vector< art::Ptr< recob::Hit >> &orderedShower, art::Ptr< recob::Vertex > const &vertex) const
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
std::unique_ptr< recob::Track > MakeInitialTrack_(detinfo::DetectorPropertiesData const &detProp, std::map< int, std::vector< art::Ptr< recob::Hit >>> const &initialHitsMap, std::map< int, std::vector< art::Ptr< recob::Hit >>> const &showerHitsMap) const
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
std::size_t color(std::string const &procname)
double FinddEdx_(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &trackHits, std::unique_ptr< recob::Track > const &track) const
Finds dE/dx for the track given a set of hits.
float PeakTime() const
Time of the signal peak, in tick units.
Contains all timing reference information for the detector.
static unsigned int reverse(QString &chars, unsigned char *level, unsigned int a, unsigned int b)
double y
y position of intersection
void line(double t, double *p, double &x, double &y, double &z)
TVector2 HitCoordinates_(recob::Hit const &hit) const
Return the coordinates of this hit in global wire/tick space.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
double TrackPitchInView(recob::Track const &track, geo::View_t view, size_t trajectory_point=0U)
Returns the projected length of track on a wire pitch step [cm].
int const fNumShowerSegments
calo::CalorimetryAlg const fCalorimetryAlg
QTextStream & bin(QTextStream &s)
double dEdx_AREA(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
std::vector< art::Ptr< recob::Hit > > FindOrderOfHits_(detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &hits, bool perpendicular=false) const
Exception thrown on invalid wire number.
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.
detail::Node< FrameID, bool > PlaneID
double const fSpacePointSize
IDparameter< geo::TPCID > TPCID
Member type of validated geo::TPCID parameter.
std::map< double, int > RelativeWireWidth_(const std::map< int, std::vector< art::Ptr< recob::Hit >>> &showerHitsMap) const
2D representation of charge deposited in the TDC/wire plane
constexpr PlaneID const & planeID() const
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
TPCID_t TPC
Index of the TPC within its cryostat.
art::ServiceHandle< geo::Geometry const > fGeom
geo::WireID suggestedWireID() const
Returns a better wire ID.
recob::tracking::Plane Plane
Utility functions to extract information from recob::Track
std::string to_string(ModuleType const mt)
std::string const fDetector
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< int, std::vector< art::Ptr< recob::Hit > > > FindShowerStart_(std::map< int, std::vector< art::Ptr< recob::Hit >>> const &orderedShowerMap) const
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
WireGeo const & WireIDToWireGeo(geo::WireID const &wireid) const
double ShowerHitRMSGradient_(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &showerHits) const
Returns the gradient of the RMS vs shower segment graph.