15 #include "art_root_io/TFileDirectory.h" 16 #include "art_root_io/TFileService.h" 21 #include "cetlib/cpu_timer.h" 31 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 32 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 63 using HitVector = std::vector<const reco::ClusterHit2D*>;
69 using Hit2DSet = std::set<const reco::ClusterHit2D*, Hit2DSetCompare>;
110 return m_timeVector[index];
131 std::vector<recob::Hit>&,
164 std::tuple<const reco::ClusterHit2D*, const reco::ClusterHit2D*, const reco::ClusterHit3D>;
184 float hitWidthSclFctr = 1.,
185 size_t hitPairCntr = 0)
const;
200 size_t minStatus)
const;
211 float closestApproach(
const Eigen::Vector3f&,
212 const Eigen::Vector3f&,
213 const Eigen::Vector3f&,
214 const Eigen::Vector3f&,
223 float pairDeltaTimeLimits)
const;
228 int FindNumberInRange(
const Hit2DSet& hit2DSet,
240 float DistanceFromPointToHitWire(
const Eigen::Vector3f& position,
246 void BuildChannelStatusVec()
const;
251 float chargeIntegral(
float,
float,
float,
int,
int)
const;
281 float m_wirePitch[3];
311 mutable bool m_weHaveAllBeenHereBefore =
false;
318 : m_channelFilter(&
art::ServiceHandle<
lariov::ChannelStatusService const>()->GetProvider())
328 collector.
produces<std::vector<recob::Hit>>();
338 "HitFinderTagVec", std::vector<art::InputTag>() = {
"gaushit"});
365 m_tupleTree = tfs->make<TTree>(
"Hit3DBuilderTree",
"Tree by SnippetHit3DBuilder");
422 lariov::ChannelStatusProvider::Status_t chanStat =
m_channelFilter->Status(channel);
432 return (*left).getAvePeakTime() < (*right).getAvePeakTime();
440 if (left->second.size() == right->second.size())
return left->first < right->first;
442 return left->second.size() > right->second.size();
458 std::unique_ptr<std::vector<recob::Hit>> outputHitPtrVec(
new std::vector<recob::Hit>);
470 if (!hitPairList.empty())
476 std::unique_ptr<art::Assns<recob::Wire, recob::Hit>> wireAssns(
482 std::unique_ptr<art::Assns<raw::RawDigit, recob::Hit>> rawDigitAssns(
488 evt.
put(std::move(outputHitPtrVec));
489 evt.
put(std::move(wireAssns));
490 evt.
put(std::move(rawDigitAssns));
506 cet::cpu_timer theClockMakeHits;
517 theClockMakeHits.stop();
522 mf::LogDebug(
"Cluster3D") <<
">>>>> 3D hit building done, found " << numHitPairs <<
" 3D Hits" 531 if (left.first == left.second)
return false;
532 if (right.first == right.second)
return true;
535 return left.first->first.first < right.first->first.first;
560 size_t totalNumHits(0);
561 size_t hitPairCntr(0);
564 size_t nDeadChanHits(0);
570 planeToSnippetHitMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 0));
572 planeToSnippetHitMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 1));
574 planeToSnippetHitMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 2));
576 size_t nPlanesWithHits =
577 (mapItr0 != planeToSnippetHitMap.end() && !mapItr0->second.empty() ? 1 : 0) +
578 (mapItr1 != planeToSnippetHitMap.end() && !mapItr1->second.empty() ? 1 : 0) +
579 (mapItr2 != planeToSnippetHitMap.end() && !mapItr2->second.empty() ? 1 : 0);
581 if (nPlanesWithHits < 2)
continue;
600 mf::LogDebug(
"Cluster3D") <<
"Total number hits: " << totalNumHits << std::endl;
601 mf::LogDebug(
"Cluster3D") <<
"Created a total of " << hitPairList.size()
602 <<
" hit pairs, counted: " << hitPairCntr << std::endl;
603 mf::LogDebug(
"Cluster3D") <<
"-- Triplets: " << nTriplets
604 <<
", dead channel pairs: " << nDeadChanHits << std::endl;
606 return hitPairList.size();
624 auto SetStartIterator =
626 while (startItr != endItr) {
627 if (startItr->first.second < startTime)
635 auto SetEndIterator =
637 while (lastItr != endItr) {
638 if (lastItr->first.first < endTime)
650 std::sort(snippetHitMapItrVec.begin(), snippetHitMapItrVec.end(),
SetStartTimeOrder());
653 int nPlanesWithHits(0);
655 for (
auto& pair : snippetHitMapItrVec)
656 if (pair.first != pair.second) nPlanesWithHits++;
658 if (nPlanesWithHits < 2)
break;
668 snippetHitMapItrVec[1].first, snippetHitMapItrVec[1].
second, firstSnippetItr->first.first);
670 snippetHitMapItr1Start, snippetHitMapItrVec[1].second, firstSnippetItr->first.second);
672 snippetHitMapItrVec[2].first, snippetHitMapItrVec[2].second, firstSnippetItr->first.first);
674 snippetHitMapItr2Start, snippetHitMapItrVec[2].second, firstSnippetItr->first.second);
681 findGoodHitPairs(firstSnippetItr, snippetHitMapItr1Start, snippetHitMapItr1End, pair12Map);
683 findGoodHitPairs(firstSnippetItr, snippetHitMapItr2Start, snippetHitMapItr2End, pair13Map);
685 if (n12Pairs > n13Pairs)
690 snippetHitMapItrVec.front().first++;
693 return hitPairList.size();
704 std::max_element(firstSnippetItr->second.begin(),
705 firstSnippetItr->second.end(),
706 [](
const auto&
left,
const auto&
right) {
707 return left->getHit()->PeakAmplitude() <
right->getHit()->PeakAmplitude();
709 float firstPHCut = firstMaxItr != firstSnippetItr->second.end() ?
714 for (
const auto& hit1 : firstSnippetItr->second) {
716 if (hit1->getHit()->DegreesOfFreedom() > 1 && hit1->getHit()->PeakAmplitude() < firstPHCut &&
724 while (secondHitItr != endItr) {
726 secondHitItr->second.begin(),
727 secondHitItr->second.end(),
728 [](
const auto&
left,
const auto&
right) {
729 return left->getHit()->PeakAmplitude() <
right->getHit()->PeakAmplitude();
731 float secondPHCut = secondMaxItr != secondHitItr->second.end() ?
735 for (
const auto& hit2 : secondHitItr->second) {
737 if (hit2->getHit()->DegreesOfFreedom() > 1 &&
738 hit2->getHit()->PeakAmplitude() < secondPHCut &&
747 std::vector<const recob::Hit*> recobHitVec = {
nullptr,
nullptr,
nullptr};
749 recobHitVec[hit1->WireID().Plane] = hit1->getHit();
750 recobHitVec[hit2->WireID().Plane] = hit2->getHit();
754 hitMatchMap[wireID].emplace_back(hit1, hit2, pair);
771 if (!pair12Map.empty()) {
773 std::vector<reco::ClusterHit3D> tempDeadChanVec;
777 std::map<const reco::ClusterHit3D*, bool> usedPairMap;
780 for (
const auto& pair13 : pair13Map) {
781 for (
const auto& hit2Dhit3DPair : pair13.second)
782 usedPairMap[&std::get<2>(hit2Dhit3DPair)] =
false;
786 for (
const auto& pair12 : pair12Map) {
787 if (pair12.second.empty())
continue;
791 for (
const auto& hit2Dhit3DPair12 : pair12.second) {
795 usedPairMap[&pair1] =
false;
798 for (
const auto& pair13 : pair13Map) {
799 if (pair13.second.empty())
continue;
801 for (
const auto& hit2Dhit3DPair13 : pair13.second) {
803 if (std::get<0>(hit2Dhit3DPair12) != std::get<0>(hit2Dhit3DPair13))
continue;
812 triplet.
setID(hitPairList.size());
813 hitPairList.emplace_back(triplet);
814 usedPairMap[&pair1] =
true;
815 usedPairMap[&pair2] =
true;
824 for (
const auto& pairMapPair : usedPairMap) {
825 if (pairMapPair.second)
continue;
831 tempDeadChanVec.emplace_back(deadChanPair);
835 if (!tempDeadChanVec.empty()) {
837 if (tempDeadChanVec.size() > 1) {
839 std::sort(tempDeadChanVec.begin(),
840 tempDeadChanVec.end(),
841 [](
const auto&
left,
const auto&
right) {
842 return left.getDeltaPeakTime() /
left.getSigmaPeakTime() <
843 right.getDeltaPeakTime() /
right.getSigmaPeakTime();
847 float firstSig = tempDeadChanVec.front().getDeltaPeakTime() /
848 tempDeadChanVec.front().getSigmaPeakTime();
850 tempDeadChanVec.back().getDeltaPeakTime() / tempDeadChanVec.back().getSigmaPeakTime();
851 float sigRange = lastSig - firstSig;
855 float maxSignificance = std::max(0.75 * (firstSig + lastSig), 1.0);
858 tempDeadChanVec.begin(),
859 tempDeadChanVec.end(),
860 [&maxSignificance](
const auto& pair) {
861 return pair.getDeltaPeakTime() / pair.getSigmaPeakTime() > maxSignificance;
865 if (std::distance(tempDeadChanVec.begin(), firstBadElem) > 20)
866 firstBadElem = tempDeadChanVec.begin() + 20;
868 else if (firstBadElem == tempDeadChanVec.begin())
871 tempDeadChanVec.resize(std::distance(tempDeadChanVec.begin(), firstBadElem));
875 for (
auto& pair : tempDeadChanVec) {
876 pair.setID(hitPairList.size());
877 hitPairList.emplace_back(pair);
889 float hitWidthSclFctr,
890 size_t hitPairCntr)
const 913 float hit1Width = hitWidthSclFctr * hit1Sigma;
914 float hit2Width = hitWidthSclFctr * hit2Sigma;
917 if (fabs(hit1Peak - hit2Peak) <= (hit1Width + hit2Width)) {
919 float hit1SigSq = hit1Sigma * hit1Sigma;
920 float hit2SigSq = hit2Sigma * hit2Sigma;
921 float deltaPeakTime = std::fabs(hit1Peak - hit2Peak);
922 float sigmaPeakTime = std::sqrt(hit1SigSq + hit2SigSq);
936 float oneOverWghts = hit1SigSq * hit2SigSq / (hit1SigSq + hit2SigSq);
937 float avePeakTime = (hit1Peak / hit1SigSq + hit2Peak / hit2SigSq) * oneOverWghts;
939 float hitChiSquare = std::pow((hit1Peak - avePeakTime), 2) / hit1SigSq +
940 std::pow((hit2Peak - avePeakTime), 2) / hit2SigSq;
944 float xPosition = (xPositionHit1 / hit1SigSq + xPositionHit2 / hit2SigSq) * hit1SigSq *
945 hit2SigSq / (hit1SigSq + hit2SigSq);
947 Eigen::Vector3f position(
948 xPosition,
float(widIntersect.
y),
float(widIntersect.
z) -
m_zPosOffset);
964 hitVector.resize(3, NULL);
970 unsigned int tpcIdx = hit1->
WireID().
TPC;
973 std::vector<geo::WireID> wireIDVec = {
geo::WireID(cryostatIdx, tpcIdx, 0, 0),
981 std::vector<float> hitDelTSigVec = {0., 0., 0.};
983 hitDelTSigVec[hit1->
WireID().
Plane] = deltaPeakTime / sigmaPeakTime;
984 hitDelTSigVec[hit2->
WireID().
Plane] = deltaPeakTime / sigmaPeakTime;
1022 static const double wirePitch =
1043 if (hitWireDist < wirePitch) {
1056 hit0 = pairHitVec[2];
1058 hit1 = pairHitVec[2];
1070 unsigned int statusBits(0x7);
1071 float avePeakTime(0.);
1072 float weightSum(0.);
1073 float xPosition(0.);
1079 for (
size_t planeIdx = 0; planeIdx < 3; planeIdx++) {
1082 wireIDVec[planeIdx] = hit2D->
WireID();
1096 float weight = 1. / (hitRMS * hitRMS);
1098 avePeakTime += peakTime *
weight;
1103 avePeakTime /= weightSum;
1104 xPosition /= weightSum;
1109 Eigen::Vector3f position(xPosition,
1110 float((pairYZVec[0] + pair0hYZVec[0] + pair1hYZVec[0]) / 3.),
1111 float((pairYZVec[1] + pair0hYZVec[1] + pair1hYZVec[1]) / 3.));
1114 float hitChiSquare(0.);
1115 float sigmaPeakTime(std::sqrt(1. / weightSum));
1116 std::vector<float> hitDelTSigVec;
1118 for (
const auto& hit2D : hitVector) {
1119 float hitRMS = hit2D->getHit()->RMS();
1125 float combRMS = std::sqrt(hitRMS * hitRMS - sigmaPeakTime * sigmaPeakTime);
1126 float peakTime = hit2D->getTimeTicks();
1127 float deltaTime = peakTime - avePeakTime;
1128 float hitSig = deltaTime / combRMS;
1130 hitChiSquare += hitSig * hitSig;
1132 hitDelTSigVec.emplace_back(std::fabs(hitSig));
1137 int lowMinIndex(std::numeric_limits<int>::max());
1138 int lowMaxIndex(std::numeric_limits<int>::min());
1139 int hiMinIndex(std::numeric_limits<int>::max());
1140 int hiMaxIndex(std::numeric_limits<int>::min());
1143 for (
const auto& hit2D : hitVector) {
1150 int hitStart = hit2D->getHit()->PeakTime() - range - 0.5;
1151 int hitStop = hit2D->getHit()->PeakTime() + range + 0.5;
1153 lowMinIndex = std::min(hitStart, lowMinIndex);
1154 lowMaxIndex = std::max(hitStart, lowMaxIndex);
1155 hiMinIndex = std::min(hitStop + 1, hiMinIndex);
1156 hiMaxIndex = std::max(hitStop + 1, hiMaxIndex);
1160 if (hitChiSquare < m_maxHit3DChiSquare && hiMinIndex > lowMaxIndex) {
1162 std::vector<float> chargeVec;
1164 for (
const auto& hit2D : hitVector)
1166 hit2D->getHit()->PeakAmplitude(),
1167 hit2D->getHit()->RMS(),
1172 std::accumulate(chargeVec.begin(), chargeVec.end(), 0.) / float(chargeVec.size());
1173 float overlapRange = float(hiMinIndex - lowMaxIndex);
1174 float overlapFraction = overlapRange / float(hiMaxIndex - lowMinIndex);
1177 std::vector<float> smallestChargeDiffVec;
1178 std::vector<float> chargeAveVec;
1179 float smallestDiff(std::numeric_limits<float>::max());
1180 float maxDeltaPeak(0.);
1181 size_t chargeIndex(0);
1183 for (
size_t idx = 0; idx < 3; idx++) {
1184 size_t leftIdx = (idx + 2) % 3;
1185 size_t rightIdx = (idx + 1) % 3;
1187 smallestChargeDiffVec.push_back(
std::abs(chargeVec[leftIdx] - chargeVec[rightIdx]));
1188 chargeAveVec.push_back(
float(0.5 * (chargeVec[leftIdx] + chargeVec[rightIdx])));
1190 if (smallestChargeDiffVec.back() < smallestDiff) {
1191 smallestDiff = smallestChargeDiffVec.back();
1196 float deltaPeakTime =
1197 hitVector[leftIdx]->getTimeTicks() - hitVector[rightIdx]->getTimeTicks();
1199 if (
std::abs(deltaPeakTime) > maxDeltaPeak) maxDeltaPeak =
std::abs(deltaPeakTime);
1204 float chargeAsymmetry = (chargeAveVec[chargeIndex] - chargeVec[chargeIndex]) /
1205 (chargeAveVec[chargeIndex] + chargeVec[chargeIndex]);
1208 if (chargeAsymmetry < -1. || chargeAsymmetry > 1.) {
1211 std::cout <<
"============> Charge asymmetry out of range: " << chargeAsymmetry
1212 <<
" <============" << std::endl;
1213 std::cout <<
" hit C: " << hitWireID.
Cryostat <<
", TPC: " << hitWireID.
TPC 1214 <<
", Plane: " << hitWireID.
Plane <<
", Wire: " << hitWireID.
Wire 1216 std::cout <<
" charge: " << chargeVec[0] <<
", " << chargeVec[1] <<
", " 1217 << chargeVec[2] << std::endl;
1218 std::cout <<
" index: " << chargeIndex <<
", smallest diff: " << smallestDiff
1224 float deltaPeakTime = *std::max_element(hitDelTSigVec.begin(), hitDelTSigVec.end());
1239 if (maxDeltaPeak > 3. * overlapRange)
return result;
1274 bool success(
false);
1288 Eigen::Vector3f wirePos0(wirePosArr.X(), wirePosArr.Y(), wirePosArr.Z());
1289 Eigen::Vector3f wireDir0(
1299 Eigen::Vector3f wirePos1(wirePosArr.X(), wirePosArr.Y(), wirePosArr.Z());
1300 Eigen::Vector3f wireDir1(
1311 if (
closestApproach(wirePos0, wireDir0, wirePos1, wireDir1, arcLen0, arcLen1)) {
1314 Eigen::Vector3f poca0 = wirePos0 + arcLen0 * wireDir0;
1316 widIntersection.
y = poca0[1];
1317 widIntersection.
z = poca0[2];
1327 const Eigen::Vector3f& u0,
1328 const Eigen::Vector3f& P1,
1329 const Eigen::Vector3f& u1,
1331 float& arcLen1)
const 1334 Eigen::Vector3f w0 = P0 - P1;
1336 float b(u0.dot(u1));
1338 float d(u0.dot(w0));
1339 float e(u1.dot(w0));
1340 float den(a * c - b * b);
1342 arcLen0 = (b *
e - c *
d) / den;
1343 arcLen1 = (a *
e - b *
d) / den;
1345 Eigen::Vector3f poca0 = P0 + arcLen0 * u0;
1346 Eigen::Vector3f poca1 = P1 + arcLen1 * u1;
1348 return (poca0 - poca1).norm();
1359 for (
int sigPos = low; sigPos < hi; sigPos++) {
1360 float arg = (float(sigPos) - peakMean + 0.5) / peakSigma;
1361 integral += peakAmp * std::exp(-0.5 * arg * arg);
1369 size_t maxChanStatus,
1370 size_t minChanStatus)
const 1378 size_t missPlane(2);
1402 bool wireOneStatus = m_channelStatus[wireID.
Plane][wireID.
Wire + 1] < maxChanStatus &&
1403 m_channelStatus[wireID.
Plane][wireID.
Wire + 1] >= minChanStatus;
1406 if (wireStatus || wireOneStatus) {
1408 if (!wireStatus) wireID.
Wire += 1;
1417 Eigen::Vector3f newPosition(
1420 newPosition[1] = (newPosition[1] + widIntersect0.
y + widIntersect1.
y) / 3.;
1422 (newPosition[2] + widIntersect0.
z + widIntersect1.
z - 2. *
m_zPosOffset) / 3.;
1447 float pairDeltaTimeLimits)
const 1449 static const float minCharge(0.);
1456 for (
const auto& hit2D : hit2DSet) {
1457 if (hit2D->getHit()->Integral() < minCharge)
continue;
1459 float hitVPeakTime(hit2D->getTimeTicks());
1460 float deltaPeakTime(pairAvePeakTime - hitVPeakTime);
1462 if (deltaPeakTime > pairDeltaTimeLimits)
continue;
1464 if (deltaPeakTime < -pairDeltaTimeLimits)
break;
1466 pairDeltaTimeLimits = fabs(deltaPeakTime);
1477 static const float minCharge(0.);
1479 int numberInRange(0);
1483 for (
const auto& hit2D : hit2DSet) {
1484 if (hit2D->getHit()->Integral() < minCharge)
continue;
1486 float hitVPeakTime(hit2D->getTimeTicks());
1487 float deltaPeakTime(pairAvePeakTime - hitVPeakTime);
1489 if (deltaPeakTime > range)
continue;
1491 if (deltaPeakTime < -range)
break;
1496 return numberInRange;
1507 double distanceToWire =
1510 wireID.
Wire = int(distanceToWire);
1514 mf::LogWarning(
"Cluster3D") <<
"Exception caught finding nearest wire, position - " 1515 << exc.what() << std::endl;
1530 float distance = std::numeric_limits<float>::max();
1538 auto const wirePosArr = wireGeo.
GetCenter();
1540 Eigen::Vector3f wirePos(wirePosArr.X(), wirePosArr.Y(), wirePosArr.Z());
1541 Eigen::Vector3f wireDir(
1549 Eigen::Vector3f hitPosition(wirePos[0], position[1], position[2]);
1552 double arcLen = (hitPosition - wirePos).
dot(wireDir);
1555 if (
abs(arcLen) < wireGeo.
HalfL()) {
1556 Eigen::Vector3f docaVec = hitPosition - (wirePos + arcLen * wireDir);
1558 distance = docaVec.norm();
1563 mf::LogWarning(
"Cluster3D") <<
"Exception caught finding nearest wire, position - " 1564 << exc.what() << std::endl;
1595 std::vector<const recob::Hit*> recobHitVec;
1602 if (!recobHitHandle.
isValid() || recobHitHandle->size() == 0)
continue;
1604 recobHitVec.reserve(recobHitVec.size() + recobHitHandle->size());
1606 for (
const auto&
hit : *recobHitHandle)
1607 recobHitVec.push_back(&
hit);
1611 if (recobHitVec.empty())
return;
1613 cet::cpu_timer theClockMakeHits;
1619 std::map<geo::PlaneID, double> planeOffsetMap;
1622 auto const clock_data =
1624 auto const det_prop =
1628 std::string debugMessage(
"");
1641 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1)) -
1642 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
1644 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2)) -
1645 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
1649 std::ostringstream outputString;
1651 outputString <<
"***> plane 0 offset: " 1653 <<
", plane 1: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 1)]
1654 <<
", plane 2: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 2)]
1656 debugMessage += outputString.str();
1657 outputString <<
" Det prop plane 0: " 1658 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0))
1660 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1))
1662 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2))
1664 debugMessage += outputString.str();
1670 mf::LogDebug(
"Cluster3D") << debugMessage << std::endl;
1672 std::cout << debugMessage << std::endl;
1679 for (
const auto& recobHit : recobHitVec) {
1681 if (recobHit->Integral() < 0.)
continue;
1688 HitStartEndPair hitStartEndPair(recobHit->StartTick(), recobHit->EndTick());
1691 if (hitStartEndPair.second <= hitStartEndPair.first) {
1692 std::cout <<
"Yes, found a hit with end time less than start time: " 1693 << hitStartEndPair.first <<
"/" << hitStartEndPair.second
1694 <<
", mult: " << recobHit->Multiplicity() << std::endl;
1700 for (
auto wireID : wireIDs) {
1710 double hitPeakTime(recobHit->PeakTime() - planeOffsetMap[planeID]);
1711 double xPosition(det_prop.ConvertTicksToX(
1727 theClockMakeHits.stop();
1740 std::vector<recob::Hit>& hitPtrVec,
1744 cet::cpu_timer theClockBuildNewHits;
1752 std::set<const reco::ClusterHit2D*> visitedHit2DSet;
1765 for (
size_t idx = 0; idx < hit3D.getHits().size(); idx++) {
1769 if (visitedHit2DSet.find(hit2D) == visitedHit2DSet.end()) {
1770 visitedHit2DSet.insert(hit2D);
1773 hitPtrVec.emplace_back(
1780 recobHitToPtrMap[newHit] = ptrMaker(hitPtrVec.size() - 1);
1788 size_t numNewHits = hitPtrVec.size();
1791 theClockBuildNewHits.stop();
1796 mf::LogDebug(
"Cluster3D") <<
">>>>> New output recob::Hit size: " << numNewHits <<
" (vs " 1811 std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>> channelToWireMap;
1820 if (hitToWireAssns.isValid()) {
1821 for (
size_t wireIdx = 0; wireIdx < hitToWireAssns.size(); wireIdx++) {
1824 channelToWireMap[wire->
Channel()] = wire;
1830 for (
const auto& hitPtrPair : recobHitPtrMap) {
1833 std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>>
::iterator chanWireItr =
1834 channelToWireMap.find(channel);
1836 if (!(chanWireItr != channelToWireMap.
end())) {
1841 wireAssns.
addSingle(chanWireItr->second, hitPtrPair.second);
1856 std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>> channelToRawDigitMap;
1865 if (hitToRawDigitAssns.isValid()) {
1866 for (
size_t rawDigitIdx = 0; rawDigitIdx < hitToRawDigitAssns.size(); rawDigitIdx++) {
1869 channelToRawDigitMap[rawDigit->
Channel()] = rawDigit;
1875 for (
const auto& hitPtrPair : recobHitPtrMap) {
1878 std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>>
::iterator chanRawDigitItr =
1879 channelToRawDigitMap.find(channel);
1881 if (chanRawDigitItr == channelToRawDigitMap.
end()) {
1886 rawDigitAssns.
addSingle(chanRawDigitItr->second, hitPtrPair.second);
TTree * m_tupleTree
output analysis tree
void initialize(size_t id, unsigned int statusBits, const Eigen::Vector3f &position, float totalCharge, float avePeakTime, float deltaPeakTime, float sigmaPeakTime, float hitChiSquare, float overlapFraction, float chargeAsymmetry, float docaToAxis, float arclenToPoca, const ClusterHit2DVec &hitVec, const std::vector< float > &hitDelTSigVec, const std::vector< geo::WireID > &wireIDVec)
Geometry description of a TPC wireThe wire is a single straight segment on a wire plane...
PlaneToSnippetHitMap m_planeToSnippetHitMap
void clear()
clear the tuple vectors before processing next event
std::vector< int > m_invalidTPCVec
std::map< geo::TPCID, PlaneToSnippetHitMap > TPCToPlaneToSnippetHitMap
std::vector< float > m_overlapRangeVec
void setWireID(const geo::WireID &wid) const
unsigned int NTPC(CryostatID const &cryoid=cryostat_zero) const
Returns the total number of TPCs in the specified cryostat.
std::pair< raw::TDCtick_t, raw::TDCtick_t > HitStartEndPair
Point_t const & GetCenter() const
Returns the world coordinate of the center of the wire [cm].
double z
z position of intersection
std::list< reco::ClusterHit3D > HitPairList
bool m_weHaveAllBeenHereBefore
WireGeo const & WireIDToWireGeo(WireID const &wireid) const
Returns the specified wire.
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
float getTimeTicks() const
SnippetHit3DBuilder class definiton.
std::vector< WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
bool makeHitPair(reco::ClusterHit3D &pairOut, const reco::ClusterHit2D *hit1, const reco::ClusterHit2D *hit2, float hitWidthSclFctr=1., size_t hitPairCntr=0) const
Make a HitPair object by checking two hits.
std::vector< ChannelStatusVec > ChannelStatusByPlaneVec
std::vector< float > m_hitAsymmetryVec
int FindNumberInRange(const Hit2DSet &hit2DSet, const reco::ClusterHit3D &pair, float range) const
A utility routine for returning the number of 2D hits from the list in a given range.
void BuildChannelStatusVec() const
Create the internal channel status vector (assume will eventually be event-by-event) ...
void CreateNewRecobHitCollection(art::Event &, reco::HitPairList &, std::vector< recob::Hit > &, RecobHitToPtrMap &)
Create a new 2D hit collection from hits associated to 3D space points.
std::vector< float > m_smallChargeDiffVec
const Eigen::Vector3f getPosition() const
bool SetHitTimeOrder(const reco::ClusterHit2D *left, const reco::ClusterHit2D *right)
const lariov::ChannelStatusProvider * m_channelFilter
float RMS() const
RMS of the hit shape, in tick units.
What follows are several highly useful typedefs which we want to expose to the outside world...
Declaration of signal hit object.
std::vector< size_t > ChannelStatusVec
define data structure for keeping track of channel status
float chargeIntegral(float, float, float, int, int) const
Perform charge integration between limits.
std::map< geo::PlaneID, SnippetHitMap > PlaneToSnippetHitMap
The data type to uniquely identify a Plane.
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, Point_t &intersection) const
Computes the intersection between two wires.
const geo::WireID & WireID() const
ChannelID_t Channel() const
DAQ channel this raw data was read from.
const geo::Geometry * m_geometry
bool operator()(const reco::ClusterHit2D *, const reco::ClusterHit2D *) const
::geo::Point_t toPoint(Point const &p)
Convert the specified point into a geo::Point_t.
std::map< geo::WireID, HitMatchTripletVec > HitMatchTripletVecMap
bool makeHitTriplet(reco::ClusterHit3D &pairOut, const reco::ClusterHit3D &pairIn, const reco::ClusterHit2D *hit2) const
Make a 3D HitPair object by checking two hits.
std::vector< float > m_chiSquare3DVec
constexpr auto abs(T v)
Returns the absolute value of the argument.
void BuildHit3D(reco::HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
size_t BuildHitPairMapByTPC(PlaneSnippetHitMapItrPairVec &planeSnippetHitMapItrPairVec, reco::HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
int DegreesOfFreedom() const
Initial tdc tick for hit.
CryostatID_t Cryostat
Index of cryostat.
SnippetHit3DBuilder(fhicl::ParameterSet const &pset)
Constructor.
std::vector< float > m_timeVector
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
WireID_t Wire
Index of the wire within its plane.
double WireCoordinate(geo::Point_t const &point) const
Returns the coordinate of the point on the plane, in wire units.
float getSigmaPeakTime() const
float DistanceFromPointToHitWire(const Eigen::Vector3f &position, const geo::WireID &wireID) const
Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range...
std::map< geo::PlaneID, WireToHitSetMap > PlaneToWireToHitSetMap
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
float m_wirePitchScaleFactor
Scaling factor to determine max distance allowed between candidate pairs.
Length_t DetLength(TPCID const &tpcid=tpc_zero) const
Returns the length of the active volume of the specified TPC.
float m_maxHit3DChiSquare
Provide ability to select hits based on "chi square".
bool SetPeakHitPairIteratorOrder(const reco::HitPairList::iterator &left, const reco::HitPairList::iterator &right)
std::vector< float > m_maxPullVec
const recob::Hit * getHit() const
unsigned int Nchannels() const
Returns the number of TPC readout channels in the detector.
float PeakAmplitude() const
The estimated amplitude of the hit at its peak, in ADC units.
IDparameter< geo::PlaneID > PlaneID
Member type of validated geo::PlaneID parameter.
bool isValid() const noexcept
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
void findGoodTriplets(HitMatchTripletVecMap &, HitMatchTripletVecMap &, reco::HitPairList &) const
This algorithm takes lists of hit pairs and finds good triplets.
std::tuple< const reco::ClusterHit2D *, const reco::ClusterHit2D *, const reco::ClusterHit3D > HitMatchTriplet
This builds a list of candidate hit pairs from lists of hits on two planes.
float getAvePeakTime() const
std::map< size_t, HitVector > HitVectorMap
Class managing the creation of a new recob::Hit object.
int findGoodHitPairs(SnippetHitMap::iterator &, SnippetHitMap::iterator &, SnippetHitMap::iterator &, HitMatchTripletVecMap &) const
Helper functions to create a hit.
PlaneGeo const & Plane(PlaneID const &planeid) const
Returns the specified wire.
void produces(std::string const &instanceName={}, Persistable const persistable=Persistable::Yes)
std::list< reco::ClusterHit2D > Hit2DList
std::vector< float > m_pairWireDistVec
std::vector< float > m_maxSideVecVec
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
Vector_t Direction() const
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
std::vector< float > m_maxDeltaPeakVec
T get(std::string const &key) const
virtual void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
std::vector< HitMatchTriplet > HitMatchTripletVec
void makeWireAssns(const art::Event &, art::Assns< recob::Wire, recob::Hit > &, RecobHitToPtrMap &) const
Create recob::Wire to recob::Hit associations.
bool operator()(const SnippetHitMapItrPair &left, const SnippetHitMapItrPair &right) const
float getXPosition() const
constexpr PlaneID const & asPlaneID() const
Conversion to PlaneID (for convenience of notation).
TimeValues
enumerate the possible values for time checking if monitoring timing
void makeRawDigitAssns(const art::Event &, art::Assns< raw::RawDigit, recob::Hit > &, RecobHitToPtrMap &) const
Create raw::RawDigit to recob::Hit associations.
PlaneToWireToHitSetMap m_planeToWireToHitSetMap
The geometry of one entire detector, as served by art.
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
constexpr auto dot(Vector const &a, OtherVector const &b)
Return cross product of two vectors.
std::vector< float > m_overlapFractionVec
std::vector< float > m_spacePointChargeVec
IHit3DBuilder interface class definiton.
std::vector< int > m_smallIndexVec
std::map< HitStartEndPair, HitVector > SnippetHitMap
Detector simulation of raw signals on wires.
std::vector< art::InputTag > m_hitFinderTagVec
Data members to follow.
const_iterator end() const
This provides an art tool interface definition for tools which construct 3D hits used in 3D clusterin...
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
std::set< const reco::ClusterHit2D *, Hit2DSetCompare > Hit2DSet
std::map< geo::TPCID, PlaneToWireToHitSetMap > TPCToPlaneToWireToHitSetMap
std::vector< const reco::ClusterHit2D * > HitVector
double HalfL() const
Returns half the length of the wire [cm].
Filters for channels, events, etc.
size_t BuildHitPairMap(PlaneToSnippetHitMap &planeToHitVectorMap, reco::HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
std::vector< SnippetHitMapItrPair > PlaneSnippetHitMapItrPairVec
geo::WireID NearestWireID(const Eigen::Vector3f &position, const geo::WireID &wireID) const
Jacket the calls to finding the nearest wire in order to intercept the exceptions if out of range...
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
bool operator()(const reco::HitPairClusterMap::iterator &left, const reco::HitPairClusterMap::iterator &right)
float PeakTime() const
Time of the signal peak, in tick units.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
bool makeDeadChannelPair(reco::ClusterHit3D &pairOut, const reco::ClusterHit3D &pair, size_t maxStatus, size_t minStatus) const
Make a 3D HitPair object from a valid pair and a dead channel in the missing plane.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
void setID(const size_t &id) const
virtual void produces(art::ProducesCollector &) override
Each algorithm may have different objects it wants "produced" so use this to let the top level produc...
bool WireIDsIntersect(const geo::WireID &, const geo::WireID &, geo::WireIDIntersection &) const
function to detemine if two wires "intersect" (in the 2D sense)
void CollectArtHits(const art::Event &evt) const
Extract the ART hits and the ART hit-particle relationships.
double y
y position of intersection
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
ChannelStatusByPlaneVec m_channelStatus
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
unsigned int Nwires(PlaneID const &planeid) const
Returns the total number of wires in the specified plane.
int trigger_offset(DetectorClocksData const &data)
constexpr WireID()=default
Default constructor: an invalid TPC ID.
unsigned int Nplanes(TPCID const &tpcid=tpc_zero) const
Returns the total number of planes in the specified TPC.
std::vector< float > m_deltaTimeVec
virtual void Hit3DBuilder(art::Event &, reco::HitPairList &, RecobHitToPtrMap &) override
Given a set of recob hits, run DBscan to form 3D clusters.
2D representation of charge deposited in the TDC/wire plane
unsigned int ChannelID_t
Type representing the ID of a readout channel.
TPCID_t TPC
Index of the TPC within its cryostat.
second_as<> second
Type of time stored in seconds, in double precision.
float m_LongHitStretchFctr
float closestApproach(const Eigen::Vector3f &, const Eigen::Vector3f &, const Eigen::Vector3f &, const Eigen::Vector3f &, float &, float &) const
function to compute the distance of closest approach and the arc length to the points of closest appr...
bool m_outputHistograms
Take the time to create and fill some histograms for diagnostics.
std::vector< float > m_qualityMetricVec
const ClusterHit2DVec & getHits() const
std::pair< SnippetHitMap::iterator, SnippetHitMap::iterator > SnippetHitMapItrPair
std::unordered_map< const recob::Hit *, art::Ptr< recob::Hit >> RecobHitToPtrMap
Defines a structure mapping art representation to internal.
void setPosition(const Eigen::Vector3f &pos) const
virtual float getTimeToExecute(IHit3DBuilder::TimeValues index) const override
If monitoring, recover the time to execute a particular function.
bool SetPairStartTimeOrder(const reco::ClusterHit3D &left, const reco::ClusterHit3D &right)
const reco::ClusterHit2D * FindBestMatchingHit(const Hit2DSet &hit2DSet, const reco::ClusterHit3D &pair, float pairDeltaTimeLimits) const
A utility routine for finding a 2D hit closest in time to the given pair.
Hit2DList m_clusterHit2DMasterList
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Event finding and building.
std::map< unsigned int, Hit2DSet > WireToHitSetMap
unsigned getStatusBits() const
void setStatusBit(unsigned bits) const