11 #include "cetlib/container_algorithms.h"
12 #include "cetlib/pow.h"
13 #include "messagefacility/MessageLogger/MessageLogger.h"
27 #include "TMathBase.h"
28 #include "TMultiGraph.h"
31 #include "range/v3/numeric.hpp"
32 #include "range/v3/view.hpp"
35 using namespace ranges;
39 , fMinTrackLength{pset.get<
double>(
"MinTrackLength")}
40 , fdEdxTrackLength{pset.get<
double>(
"dEdxTrackLength")}
41 , fSpacePointSize{pset.get<
double>(
"SpacePointSize")}
42 , fNfitpass{pset.get<
unsigned int>(
"Nfitpass")}
43 , fNfithits{pset.get<std::vector<unsigned int>>(
"Nfithits")}
44 , fToler{pset.get<std::vector<double>>(
"Toler")}
45 , fShowerEnergyAlg(pset.get<fhicl::ParameterSet>(
"ShowerEnergyAlg"))
46 , fCalorimetryAlg(pset.get<fhicl::ParameterSet>(
"CalorimetryAlg"))
47 , fProjectionMatchingAlg(pset.get<fhicl::ParameterSet>(
"ProjectionMatchingAlg"))
48 , fDetector{pset.get<std::string>(
"Detector",
"dune35t")}
49 , fMakeGradientPlot{pset.get<
bool>(
"MakeGradientPlot",
false)}
50 , fMakeRMSGradientPlot{pset.get<
bool>(
"MakeRMSGradientPlot",
false)}
51 , fNumShowerSegments{pset.get<
int>(
"NumShowerSegments", 4)}
53 if (fNfitpass != fNfithits.size() || fNfitpass != fToler.size()) {
54 throw art::Exception(art::errors::Configuration)
55 <<
"EMShowerAlg: fNfithits and fToler need to have size fNfitpass";
61 std::vector<art::Ptr<recob::Cluster>>
const& clusters,
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};
68 AssociateClustersAndTracks(
69 clusters, fmh, fmt, clustersToIgnore, clusterToTracks, trackToClusters);
74 std::vector<art::Ptr<recob::Cluster>>
const& clusters,
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];
99 if (clusterHitTrackPtr->Length() < fMinTrackLength) {
101 std::cout <<
"Track " << clusterHitTrackPtr->ID() <<
" is too short! ("
102 << clusterHitTrackPtr->Length() <<
")\n";
107 int track = clusterHitTrackPtr.key();
108 int cluster = clusterPtr.key();
109 if (cet::search_all(clustersToIgnore, cluster))
continue;
110 if (not cet::search_all(trackToClusters[track], cluster))
111 trackToClusters[
track].push_back(cluster);
112 if (not cet::search_all(clusterToTracks[cluster], track))
113 clusterToTracks[
cluster].push_back(track);
120 std::map<
int,
std::vector<art::Ptr<recob::Hit>>>& showerHitsMap)
const
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;
141 if (showerHitsMap.at(problemPlane).size() < 3)
return;
144 std::vector<int> otherPlanes;
145 for (
int plane = 0; plane < (int)
fGeom->MaxPlanes(); ++plane)
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;
155 for (
std::vector<art::Ptr<recob::Hit>>::iterator hitIt = showerHitsMap.at(problemPlane).begin();
156 hitIt != showerHitsMap.at(problemPlane).end()
and (*hitIt)->WireID().TPC == wrongTPC;
161 if (nHits > 2)
return;
164 std::map<int, int> otherTPCs;
165 for (
std::vector<art::Ptr<recob::Hit>>::iterator hitIt =
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)
177 for (
std::vector<art::Ptr<recob::Hit>>::iterator hitIt =
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;
189 for (
std::vector<art::Ptr<recob::Hit>>::iterator hitIt = showerHitsMap.at(problemPlane).begin();
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);
203 std::map<
int,
std::vector<art::Ptr<recob::Hit>>>
const& showerHitsMap)
const
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;
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));
222 TVector2 proj1 = Project3DPointOntoPlane_(detProp, showerStartPos, planes.at(0));
223 TVector2 proj2 = Project3DPointOntoPlane_(detProp, showerStartPos, planes.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);
259 TVector3 showerStartPos = Construct3DPoint_(
260 detProp, start2DMap.at(otherPlanes.at(0)), start2DMap.at(otherPlanes.at(1)));
261 TVector2 showerStartProj = Project3DPointOntoPlane_(detProp, showerStartPos, plane);
265 std::cout <<
"\nStart position in this plane is "
266 << HitPosition_(detProp, *start2DMap.at(plane)).
X() <<
", "
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";
275 std::abs((showerStartProj - HitPosition_(detProp, *start2DMap.at(plane))).Mod());
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;
295 std::vector<art::Ptr<recob::Cluster>>
const& clusters,
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) {
310 art::Ptr<recob::Cluster>
const&
cluster = clusters.at(clusterIndex);
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) {
320 chargeDist[plane] =
new TH1D(std::string(
"chargeDist_Plane" +
std::to_string(plane) +
327 auto const& hits = fmh.at(clusterPtr.key());
329 chargeDist[plane]->Fill(
hit.Integral());
332 chargeDist[plane]->Write();
339 if (planeClusters.size() < 3)
continue;
342 std::map<int, std::vector<double>> planeClusterSizes;
343 for (std::map<
int,
std::vector<art::Ptr<recob::Cluster>>>::iterator planeClustersIt =
344 planeClusters.begin();
345 planeClustersIt != planeClusters.end();
347 for (
std::vector<art::Ptr<recob::Cluster>>::iterator planeClusterIt =
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;
395 art::Ptr<recob::Hit>
const& hit1,
396 art::Ptr<recob::Hit>
const& hit2)
const
400 double x = (detProp.
ConvertTicksToX(hit1->PeakTime(), hit1->WireID().planeID()) +
406 fGeom->WireIDsIntersect(hit1->WireID(), hit2->WireID(), intersection);
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) {
436 mf::LogWarning(
"EMShowerAlg")
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) {
455 std::cout <<
"Hit (" << HitCoordinates_(
hit).X() <<
", " << HitCoordinates_(
hit).Y()
456 <<
") (real wire " <<
hit.WireID().Wire <<
") in TPC " <<
hit.WireID().TPC
464 TVector3 trackStart = Construct3DPoint_(detProp, track1.at(0), track2.at(0));
465 pma::Track3D* pmatrack = fProjectionMatchingAlg.buildSegment(detProp, track1, track2, trackStart);
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();
504 for (std::map<int, TVector2>::const_iterator showerCentreIt = showerCentreMap.begin();
505 showerCentreIt != showerCentreMap.end();
509 TVector2 vertexProj = Project3DPointOntoPlane_(detProp, vertex, showerCentreIt->first);
510 TVector2 endProj = Project3DPointOntoPlane_(detProp,
end, showerCentreIt->first);
513 distanceToVertex[showerCentreIt->first] = (vertexProj - showerCentreIt->second).Mod();
514 distanceToEnd[showerCentreIt->first] = (endProj - showerCentreIt->second).Mod();
518 double avDistanceToVertex = 0, avDistanceToEnd = 0;
519 for (std::map<int, double>::iterator distanceToVertexIt = distanceToVertex.begin();
520 distanceToVertexIt != distanceToVertex.end();
521 ++distanceToVertexIt)
522 avDistanceToVertex += distanceToVertexIt->second;
523 avDistanceToVertex /= distanceToVertex.size();
525 for (std::map<int, double>::iterator distanceToEndIt = distanceToEnd.begin();
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) {
537 std::reverse(xyz.begin(), xyz.end());
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>
563 std::vector<art::Ptr<recob::Hit>>
const& track2)
const
565 std::map<int, TVector2> showerCentreMap;
566 return ConstructTrack(detProp, track1, track2, showerCentreMap);
572 std::vector<art::Ptr<recob::Hit>>
const& trackHits,
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();
589 if (pitch > fdEdxTrackLength) {
590 return fCalorimetryAlg.dEdx_AREA(clockData, detProp, firstHit, pitch);
593 double totalCharge = 0, totalDistance = 0, avHitTime = 0;
594 unsigned int nHits = 0;
597 if (totalDistance + pitch < fdEdxTrackLength) {
598 totalDistance += pitch;
599 totalCharge +=
hit.Integral();
600 avHitTime +=
hit.PeakTime();
605 avHitTime /= (double)nHits;
607 double const dQdx = totalCharge / totalDistance;
608 return fCalorimetryAlg.dEdx_AREA(clockData, detProp, dQdx, avHitTime, firstHit.
WireID().
Plane);
614 const std::map<
int,
std::vector<art::Ptr<recob::Hit>>>& showerHitsMap,
615 std::unique_ptr<recob::Track>& initialTrack,
616 std::map<
int,
std::vector<art::Ptr<recob::Hit>>>& initialTrackHits,
626 std::cout <<
" ------------------ Finding initial track hits "
627 "-------------------- \n";
628 initialTrackHits = FindShowerStart_(showerHitsMap);
630 std::cout <<
"Here are the initial shower hits... \n";
631 for (
auto const& [plane, hitPtrs] : initialTrackHits) {
634 std::cout <<
" Hit is (" << HitCoordinates_(
hit).X() <<
" (real hit " <<
hit.WireID()
635 <<
"), " << HitCoordinates_(
hit).Y() <<
")\n";
640 std::cout <<
" ------------------ End finding initial track hits "
641 "-------------------- \n";
644 if (fDebug > 1)
std::cout <<
" ------------------ Finding initial track -------------------- \n";
645 initialTrack = MakeInitialTrack_(detProp, initialTrackHits, showerHitsMap);
646 if (initialTrack
and fDebug > 1) {
647 std::cout <<
"The track start is (" << initialTrack->
Vertex().X() <<
", "
648 << initialTrack->
Vertex().Y() <<
", " << initialTrack->
Vertex().Z() <<
")\n";
654 std::cout <<
" ------------------ End finding initial track "
655 "-------------------- \n";
658 std::vector<art::Ptr<recob::Hit>>
661 bool perpendicular)
const
664 TVector2 centre = ShowerCenter_(detProp, hits);
667 TVector2 direction = ShowerDirection_(detProp, hits);
669 if (perpendicular) direction = direction.Rotate(TMath::Pi() / 2);
673 std::map<double, art::Ptr<recob::Hit>> hitProjection;
674 for (
auto const& hitPtr : hits) {
675 pos = HitPosition_(detProp, *hitPtr) - centre;
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; });
685 if (fMakeGradientPlot) {
686 std::map<int, TGraph*> graphs;
688 int tpc =
hit.WireID().TPC;
689 if (graphs[tpc] ==
nullptr) graphs[tpc] =
new TGraph();
690 graphs[tpc]->SetPoint(
691 graphs[tpc]->GetN(), HitPosition_(detProp,
hit).
X(), HitPosition_(detProp,
hit).Y());
693 TMultiGraph* multigraph =
new TMultiGraph();
694 for (
auto const [color, graph] : graphs) {
695 graph->SetMarkerColor(color);
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) {
730 not cet::search_all(matchingShowers, shower)) {
731 matchingShowers.push_back(shower);
742 if (matchingShowers.size() < 1) showers.push_back(clusters);
746 for (
int const cluster : clusters) {
747 if (not cet::search_all(showers.at(matchingShowers[0]),
cluster))
748 showers.at(matchingShowers.at(0)).push_back(
cluster);
756 std::map<int, std::vector<art::Ptr<recob::Hit>>>
758 std::map<
int,
std::vector<art::Ptr<recob::Hit>>>
const& orderedShowerMap)
const
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;
770 wires.push_back(std::round(HitCoordinates_(
hit).
X()));
772 cet::sort_all(wires);
773 if (
std::abs(*wires.begin() - std::round(HitCoordinates_(**orderedShower.begin()).
X())) > 3
and
774 std::abs(*wires.rbegin() - std::round(HitCoordinates_(**orderedShower.begin()).
X())) > 3)
775 wireDirection =
false;
779 bool increasing = HitCoordinates_(**orderedShower.rbegin()).
X() >
780 HitCoordinates_(**orderedShower.begin()).
X();
781 std::map<int, std::vector<art::Ptr<recob::Hit>>> wireHitMap;
782 int multipleWires = 0;
783 for (
auto const& hitPtr : orderedShower)
784 wireHitMap[std::round(HitCoordinates_(*hitPtr).X())].push_back(hitPtr);
786 for (
auto const& hitPtr : orderedShower) {
787 int wire = std::round(HitCoordinates_(*hitPtr).X());
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());
816 bool increasing = HitCoordinates_(**orderedShower.rbegin()).Y() >
817 HitCoordinates_(**orderedShower.begin()).Y();
818 std::map<int, std::vector<art::Ptr<recob::Hit>>> tickHitMap;
819 for (
std::vector<art::Ptr<recob::Hit>>::const_iterator hitIt = orderedShower.begin();
820 hitIt != orderedShower.end();
822 tickHitMap[std::round(HitCoordinates_(**hitIt).Y())].push_back(*hitIt);
824 for (
auto const& hitPtr : orderedShower) {
825 int const tick = std::round(HitCoordinates_(*hitPtr).Y());
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;
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)
859 if (not cet::search_all(singleHitTPCs, hitPtr->WireID().TPC))
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>>
875 const std::map<
int,
std::vector<art::Ptr<recob::Hit>>>& showerHitsMap)
const
879 std::map<int, std::map<int, bool>> permutations;
889 std::map<int, double> planeRMSGradients, planeRMS;
890 for (
auto const& [plane, hitPtrs] : showerHitsMap) {
891 planeRMS[plane] = ShowerHitRMS_(detProp, hitPtrs);
892 planeRMSGradients[plane] = ShowerHitRMSGradient_(detProp, hitPtrs);
896 std::map<double, int> gradientMap;
897 for (
int const plane : showerHitsMap | views::keys)
898 gradientMap[
std::abs(planeRMSGradients.at(plane))] = plane;
900 std::map<double, int> wireWidthMap = RelativeWireWidth_(showerHitsMap);
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;
923 if (not cet::search_all(usedPermutations, permutation)) {
924 permutations[perm] = permutation;
925 usedPermutations.push_back(permutation);
929 for (
int const plane : wireWidthMap | views::reverse |
views::values) {
930 std::map<int, bool> permutation;
931 permutation[plane] =
false;
933 if (plane != plane2) permutation[plane2] =
true;
935 if (not cet::search_all(usedPermutations, permutation)) {
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>
962 std::map<
int,
std::vector<art::Ptr<recob::Hit>>>
const& initialHitsMap,
963 std::map<
int,
std::vector<art::Ptr<recob::Hit>>>
const& showerHitsMap)
const
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;
972 for (std::map<
int,
std::vector<art::Ptr<recob::Hit>>>::const_iterator initialHitIt =
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;
992 if (initialHitsSize.size() > 2
and !CheckShowerHits_(detProp, showerHitsMap)) {
993 int planeToIgnore = WorstPlane_(showerHitsMap);
995 std::cout <<
"Igoring plane " << planeToIgnore <<
" in creation of initial track\n";
996 for (
std::vector<std::pair<int, int>>::iterator hitsSizeIt = initialHitsSize.begin();
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)));
1013 art::PtrVector<recob::Hit>
const& hits,
1014 std::unique_ptr<recob::Track>
const& initialTrack,
1015 std::map<
int,
std::vector<art::Ptr<recob::Hit>>>
const& initialHitsMap)
const
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(
1034 fShowerEnergyAlg.ShowerEnergy(clockData, detProp, planeHitsMap.at(plane), plane));
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";
1079 art::PtrVector<recob::Hit>
const& hits,
1080 art::Ptr<recob::Vertex>
const&
vertex,
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;
1097 for (std::map<
int,
std::vector<art::Ptr<recob::Hit>>>::iterator planeHits = planeHitsMap.begin();
1098 planeHits != planeHitsMap.end();
1101 std::vector<art::Ptr<recob::Hit>> showerHits;
1102 OrderShowerHits_(detProp, planeHits->second, showerHits, vertex);
1103 FindInitialTrackHits(showerHits, vertex, initialTrackHits[planeHits->first]);
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) {
1124 fProjectionMatchingAlg.buildSegment(detProp, initialTrackHits[pl0], initialTrackHits[pl1]);
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(
1157 fShowerEnergyAlg.ShowerEnergy(clockData, detProp, planeHitsMap[plane], plane));
1160 totalEnergy.push_back(0);
1162 if (initialTrackHits[plane].
size()) {
1167 double wirepitch =
fGeom->WirePitch(initialTrackHits[plane][0]->
WireID().planeID());
1168 double angleToVert =
1169 fGeom->WireAngleToVertical(
fGeom->Plane(plane).View(),
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;
1184 if (
std::abs((w1 - w0) * pitch) < fdEdxTrackLength) {
1185 vQ.push_back(
hit->Integral());
1186 totQ +=
hit->Integral();
1187 avgT +=
hit->PeakTime();
1192 double dQdx = TMath::Median(vQ.size(), &vQ[0]) / pitch;
1193 fdEdx = fCalorimetryAlg.dEdx_AREA(
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>
1232 std::map<
int,
std::vector<art::Ptr<recob::Hit>>>
const& showerHits,
1236 std::vector<recob::SpacePoint> spacePoints;
1250 std::vector<int> usedHits;
1253 for (std::map<
int,
std::vector<art::Ptr<recob::Hit>>>::const_iterator showerHitIt =
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;
1268 for (
std::vector<art::Ptr<recob::Hit>>::const_iterator planeHitIt = showerHitIt->second.begin();
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));
1277 for (
std::vector<art::Ptr<recob::Hit>>::const_iterator otherPlaneHitIt =
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())
1287 TVector3 point = Construct3DPoint_(detProp, *planeHitIt, *otherPlaneHitIt);
1288 std::vector<art::Ptr<recob::Hit>> pointHits;
1289 bool truePoint =
false;
1291 if (otherPlanes.size() > 1) {
1293 TVector2 projThirdPlane = Project3DPointOntoPlane_(detProp, point, otherPlanes.at(1));
1294 const std::vector<art::Ptr<recob::Hit>> otherOtherPlaneHits =
1295 showerHits.at(otherPlanes.at(1));
1297 for (
std::vector<art::Ptr<recob::Hit>>::const_iterator otherOtherPlaneHitIt =
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);
1320 else if ((Project3DPointOntoPlane_(detProp, point, (*planeHitIt)->WireID().Plane) -
1321 HitPosition_(detProp, **planeHitIt))
1322 .Mod() < fSpacePointSize
and
1323 (Project3DPointOntoPlane_(detProp, point, (*otherPlaneHitIt)->WireID().Plane) -
1324 HitPosition_(detProp, **otherPlaneHitIt))
1325 .Mod() < fSpacePointSize) {
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()};
1339 double xyzerr[6] = {fSpacePointSize,
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";
1360 for (std::vector<recob::SpacePoint>::const_iterator spacePointIt = spacePoints.begin();
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>>>
1373 art::PtrVector<recob::Hit>
const&
shower,
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);
1394 planeRMS[plane] = ShowerHitRMS_(detProp, orderedHits);
1395 planeRMSGradients[plane] = ShowerHitRMSGradient_(detProp, orderedHits);
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';
1411 std::cout <<
" Hit at (" << HitCoordinates_(
hit).X() <<
", " << HitCoordinates_(
hit).Y()
1412 <<
") -- real wire " <<
hit.WireID() <<
", hit position ("
1413 << HitPosition_(detProp,
hit).X() <<
", " << HitPosition_(detProp,
hit).Y()
1423 std::map<int, double> planeOtherRMS, planeOtherRMSGradients;
1424 for (std::map<int, double>::iterator planeRMSIt = planeRMS.begin(); planeRMSIt != planeRMS.end();
1426 planeOtherRMS[planeRMSIt->first] = 0;
1427 planeOtherRMSGradients[planeRMSIt->first] = 0;
1428 int nOtherPlanes = 0;
1429 for (
int plane = 0; plane < (int)
fGeom->MaxPlanes(); ++plane) {
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 =
1446 this->FindOrderOfHits_(detProp, hitPtrs,
true);
1447 showerHitsMap[plane] = orderedHits;
1448 planeRMSGradients[plane] = this->ShowerHitRMSGradient_(detProp, 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()
1458 <<
", " << HitCoordinates_(*hitPtrs.front()).Y() <<
") (real wire "
1459 << hitPtrs.front()->WireID() <<
") and end ("
1460 << HitCoordinates_(*hitPtrs.back()).
X() <<
", "
1461 << HitCoordinates_(*hitPtrs.back()).Y() <<
") (real wire "
1462 << hitPtrs.back()->WireID() <<
")\n";
1467 for (std::map<
int,
std::vector<art::Ptr<recob::Hit>>>::iterator showerHitsIt =
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";
1477 for (std::map<
int,
std::vector<art::Ptr<recob::Hit>>>::iterator showerHitsIt =
1478 showerHitsMap.begin();
1479 showerHitsIt != showerHitsMap.end();
1481 std::cout <<
" Plane " << showerHitsIt->first <<
'\n';
1482 for (
std::vector<art::Ptr<recob::Hit>>::iterator hitIt = showerHitsIt->second.begin();
1483 hitIt != showerHitsIt->second.end();
1485 std::cout <<
" Hit at (" << HitCoordinates_(**hitIt).X() <<
", "
1486 << HitCoordinates_(**hitIt).Y() <<
") -- real wire " << (*hitIt)->WireID()
1487 <<
", hit position (" << HitPosition_(detProp, **hitIt).X() <<
", "
1488 << HitPosition_(detProp, **hitIt).Y() <<
")\n";
1492 CheckIsolatedHits_(showerHitsMap);
1495 std::cout <<
"\nHits in order; after checking isolated hits...\n";
1496 for (std::map<
int,
std::vector<art::Ptr<recob::Hit>>>::iterator showerHitsIt =
1497 showerHitsMap.begin();
1498 showerHitsIt != showerHitsMap.end();
1500 std::cout <<
" Plane " << showerHitsIt->first <<
'\n';
1501 for (
std::vector<art::Ptr<recob::Hit>>::iterator hitIt = showerHitsIt->second.begin();
1502 hitIt != showerHitsIt->second.end();
1504 std::cout <<
" Hit at (" << HitCoordinates_(**hitIt).X() <<
", "
1505 << HitCoordinates_(**hitIt).Y() <<
") -- real wire " << (*hitIt)->WireID()
1506 <<
", hit position (" << HitPosition_(detProp, **hitIt).X() <<
", "
1507 << HitPosition_(detProp, **hitIt).Y() <<
")\n";
1512 std::cout <<
"After reversing and checking isolated hits, here are the "
1513 "start and end points...\n";
1514 for (std::map<
int,
std::vector<art::Ptr<recob::Hit>>>::iterator showerHitsIt =
1515 showerHitsMap.begin();
1516 showerHitsIt != showerHitsMap.end();
1518 std::cout <<
" Plane " << showerHitsIt->first <<
" has start ("
1519 << HitCoordinates_(*showerHitsIt->second.front()).
X() <<
", "
1520 << HitCoordinates_(*showerHitsIt->second.front()).Y() <<
") (real wire "
1521 << showerHitsIt->second.front()->WireID() <<
") and end ("
1522 << HitCoordinates_(*showerHitsIt->second.back()).
X() <<
", "
1523 << HitCoordinates_(*showerHitsIt->second.back()).Y() <<
")\n";
1528 std::map<double, int> wireWidths = RelativeWireWidth_(showerHitsMap);
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);
1547 std::map<int, std::map<int, bool>> permutations = GetPlanePermutations_(detProp, showerHitsMap);
1550 auto const originalShowerHitsMap = showerHitsMap;
1553 while (!CheckShowerHits_(detProp, showerHitsMap)
and
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';
1572 std::cout <<
" Hit (" << HitCoordinates_(
hit).X() <<
" (real wire " <<
hit.WireID()
1573 <<
"), " << HitCoordinates_(
hit).Y() <<
") -- pos ("
1574 << HitPosition_(detProp,
hit).X() <<
", " << HitPosition_(detProp,
hit).Y()
1580 if (ignoredPlanes.size())
1581 showerHitsMap[ignoredPlanes.begin()->first] = ignoredPlanes.begin()->second;
1583 return showerHitsMap;
1590 art::Ptr<recob::Vertex>
const&
vertex)
const
1593 showerHits = FindOrderOfHits_(detProp,
shower);
1602 art::Ptr<recob::Hit> hit0, hit1;
1603 for (
auto&
hit : showerHits) {
1604 if (
hit->WireID().TPC == tpc.
TPC) {
1605 if (hit0.isNull()) { hit0 =
hit; }
1609 if (hit0.isNull() || hit1.isNull())
return;
1610 TVector2 coord0 = TVector2(hit0->WireID().Wire, hit0->PeakTime());
1611 TVector2 coord1 = TVector2(hit1->WireID().Wire, hit1->PeakTime());
1612 TVector2 coordvtx = TVector2(
fGeom->WireCoordinate(xyz[1], xyz[2], hit0->WireID().planeID()),
1614 if ((coord1 - coordvtx).Mod() < (coord0 - coordvtx).Mod()) {
1615 std::reverse(showerHits.begin(), showerHits.end());
1621 art::Ptr<recob::Vertex>
const&
vertex,
1622 std::vector<art::Ptr<recob::Hit>>& trackHits)
const
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) {
1658 TVector2
coord = HitCoordinates_(*
hit);
1660 (
std::abs((coord.Y() - (parm[0] + coord.X() * parm[1])) * cos(atan(parm[1]))) <
1664 if (nhits == fNfithits[i] + 1)
break;
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]);
1693 return HitPosition_(detProp, HitCoordinates_(hit), planeID);
1698 TVector2
const& pos,
1701 return TVector2(pos.X() *
fGeom->WirePitch(planeID), detProp.
ConvertTicksToX(pos.Y(), planeID));
1707 double globalWire = -999;
1711 double wireCentre[3];
1712 fGeom->WireIDToWireGeo(wireID).GetCenter(wireCentre);
1713 if (wireID.
TPC % 2 == 0)
1715 fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.
Plane, 0, wireID.
Cryostat);
1718 fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.
Plane, 1, wireID.
Cryostat);
1725 if (fDetector ==
"dune35t") {
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)
1732 globalWire = (2 * nwires) + wireID.
Wire;
1734 mf::LogError(
"BlurredClusterAlg")
1735 <<
"Error when trying to find a global induction plane coordinate for TPC " << wireID.
TPC
1736 <<
" (geometry" << fDetector <<
")";
1738 else if (fDetector ==
"dune10kt") {
1741 int block = wireID.
TPC / 4;
1742 globalWire = (nwires * block) + wireID.
Wire;
1745 double wireCentre[3];
1746 fGeom->WireIDToWireGeo(wireID).GetCenter(wireCentre);
1747 if (wireID.
TPC % 2 == 0)
1749 fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.
Plane, 0, wireID.
Cryostat);
1752 fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.
Plane, 1, wireID.
Cryostat);
1759 std::map<double, int>
1761 const std::map<
int,
std::vector<art::Ptr<recob::Hit>>>& showerHitsMap)
const
1765 std::map<int, int> planeWireLength;
1766 for (std::map<
int,
std::vector<art::Ptr<recob::Hit>>>::const_iterator showerHitsIt =
1767 showerHitsMap.begin();
1768 showerHitsIt != showerHitsMap.end();
1770 planeWireLength[showerHitsIt->first] =
1771 std::abs(HitCoordinates_(*showerHitsIt->second.front()).
X() -
1772 HitCoordinates_(*showerHitsIt->second.back()).
X());
1775 std::map<int, double> planeOtherWireLengths;
1776 for (std::map<int, int>::iterator planeWireLengthIt = planeWireLength.begin();
1777 planeWireLengthIt != planeWireLength.end();
1778 ++planeWireLengthIt) {
1780 for (
int plane = 0; plane < (int)
fGeom->MaxPlanes(); ++plane)
1781 if (plane != planeWireLengthIt->first
and planeWireLength.count(plane))
1782 quad += cet::square(planeWireLength[plane]);
1783 quad = std::sqrt(quad);
1784 planeOtherWireLengths[planeWireLengthIt->first] =
1785 planeWireLength[planeWireLengthIt->first] / (double)quad;
1789 std::map<double, int> wireWidthMap;
1790 for (std::map<
int,
std::vector<art::Ptr<recob::Hit>>>::const_iterator showerHitsIt =
1791 showerHitsMap.begin();
1792 showerHitsIt != showerHitsMap.end();
1794 wireWidthMap[planeOtherWireLengths.at(showerHitsIt->first)] = showerHitsIt->first;
1796 return wireWidthMap;
1801 const std::vector<art::Ptr<recob::Hit>>& showerHits)
const
1806 double sumx = 0., sumy = 0., sumx2 = 0., sumxy = 0., sumweight = 0.;
1807 for (
std::vector<art::Ptr<recob::Hit>>::const_iterator
hit = showerHits.begin();
1808 hit != showerHits.end();
1811 pos = HitPosition_(detProp, **
hit);
1812 weight = cet::square((*hit)->Integral());
1813 sumweight += weight;
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();
1827 std::vector<art::Ptr<recob::Hit>>
const& showerHits)
const
1830 TVector2 pos, chargePoint = TVector2(0, 0);
1831 double totalCharge = 0;
1832 for (
std::vector<art::Ptr<recob::Hit>>::const_iterator
hit = showerHits.begin();
1833 hit != showerHits.end();
1835 pos = HitPosition_(detProp, **
hit);
1836 chargePoint += (*hit)->Integral() * pos;
1837 totalCharge += (*hit)->Integral();
1839 TVector2 centre = chargePoint / totalCharge;
1846 const std::vector<art::Ptr<recob::Hit>>& showerHits)
const
1849 TVector2 direction = ShowerDirection_(detProp, showerHits);
1850 TVector2 centre = ShowerCenter_(detProp, showerHits);
1852 std::vector<double> distanceToAxis;
1853 for (
std::vector<art::Ptr<recob::Hit>>::const_iterator showerHitsIt = showerHits.begin();
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());
1867 const std::vector<art::Ptr<recob::Hit>>& showerHits)
const
1870 TVector2 direction = ShowerDirection_(detProp, showerHits);
1873 int nShowerSegments = fNumShowerSegments;
1874 double lengthOfShower =
1875 (HitPosition_(detProp, *showerHits.back()) - HitPosition_(detProp, *showerHits.front())).Mod();
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;
1882 (HitPosition_(detProp,
hit) - HitPosition_(detProp, *showerHits.front())).Mod() /
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);
1898 meanPosition += HitPosition_(detProp,
hit);
1899 meanPosition /= (double)hitPtrs.size();
1902 std::vector<double> distanceToAxisBin;
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);
1910 if (fMakeRMSGradientPlot) graph->SetPoint(graph->GetN(), segment, RMSBin);
1914 double sumx = 0., sumy = 0., sumx2 = 0., sumxy = 0., sumweight = 0.;
1915 for (
auto const [
bin, RMSBin] : binVsRMS) {
1916 double weight = segmentCharge.at(
bin);
1917 sumweight += weight;
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);
1925 if (fMakeRMSGradientPlot) {
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()};
1968 wireID =
fGeom->NearestWireID(point, planeID);
1974 wireTickPos = TVector2(GlobalWire_(wireID), detProp.
ConvertXToTicks(point.X(), planeID));
1976 return HitPosition_(detProp, wireTickPos, planeID);
1981 const std::map<
int,
std::vector<art::Ptr<recob::Hit>>>& showerHitsMap)
const
1984 std::map<int, int> planeWireLength;
1985 std::map<int, double> planeOtherWireLengths;
1986 for (
auto const& [plane, hits] : showerHitsMap)
1987 planeWireLength[plane] =
1988 std::abs(HitCoordinates_(*hits.front()).
X() - HitCoordinates_(*hits.back()).
X());
1989 for (std::map<int, int>::iterator planeWireLengthIt = planeWireLength.begin();
1990 planeWireLengthIt != planeWireLength.end();
1991 ++planeWireLengthIt) {
1993 for (
int plane = 0; plane < (int)
fGeom->MaxPlanes(); ++plane)
1994 if (plane != planeWireLengthIt->first
and planeWireLength.count(plane))
1995 quad += cet::square(planeWireLength[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;
2075 if (nhits > 2) ++hitmap[
hit.WireID().Wire];
2076 if (nhits == 20)
break;
2078 if (
float(nhits - 2) / hitmap.size() > 1.4)
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>="">
then if[["$THISISATEST"==1]]
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
constexpr to_element_t to_element
BEGIN_PROLOG true icarus_rawdigitfilter FilterTools FilterPlane1 Plane
process_name opflash particleana ie x
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...
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
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::size_t size(FixedBins< T, C > const &) noexcept
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.
process_name use argoneut_mc_hitfinder track
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker see the discussion of warn common echo in *Note Linker such as a global int variable echo as opposed to a large global array echo echo I echo The symbol is an indirect reference to another symbol This echo is a GNU extension to the a out object file format which is echo rarely used echo echo N echo The symbol is a debugging symbol echo echo R echo The symbol is in a read only data section echo echo S echo The symbol is in an uninitialized data section for small echo objects echo echo T echo The symbol is in the the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo W echo The symbol is a weak symbol that has not been specifically echo tagged as a weak object symbol When a weak defined symbol echo is linked with a normal defined the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo echo The symbol is a stabs symbol in an a out object file In echo this the next values printed are the stabs other echo the stabs desc and the stab type Stabs symbols are echo used to hold debugging information For more echo see *Note or object file format specific echo echo For Mac OS X
TVector2 ShowerCenter_(detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> const &showerHits) const
Returns the charge-weighted shower center.
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.
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
IDparameter< geo::PlaneID > PlaneID
Member type of validated geo::PlaneID parameter.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
void CheckIsolatedHits_(std::map< int, std::vector< art::Ptr< recob::Hit >>> &showerHitsMap) const
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>="">
Collection of exceptions for Geometry system.
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.
process_name opflash particleana ie ie y
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
Signal from induction planes.
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...
Point_t const & Vertex() const
auto end(FixedBins< T, C > const &) noexcept
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
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
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
bool isCleanShower(std::vector< art::Ptr< recob::Hit >> const &hits) const
<Tingjun to="" document>="">
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
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
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
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
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.
std::string to_string(WindowPattern const &pattern)
double y
y position of intersection
TVector2 HitCoordinates_(recob::Hit const &hit) const
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=0U)
Returns the projected length of track on a wire pitch step [cm].
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.
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
std::size_t count(Cont const &cont)
TPCID_t TPC
Index of the TPC within its cryostat.
geo::WireID suggestedWireID() const
Returns a better wire ID.
bool empty(FixedBins< T, C > const &) noexcept
Utility functions to extract information from recob::Track
BEGIN_PROLOG could also be cout
std::map< int, std::vector< art::Ptr< recob::Hit > > > FindShowerStart_(std::map< int, std::vector< art::Ptr< recob::Hit >>> const &orderedShowerMap) 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.