15 #include "art_root_io/TFileDirectory.h" 16 #include "art_root_io/TFileService.h" 21 #include "cetlib/cpu_timer.h" 32 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 33 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 64 using HitVector = std::vector<const reco::ClusterHit2D*>;
70 using Hit2DSet = std::set<const reco::ClusterHit2D*, Hit2DSetCompare>;
109 return m_timeVector[index];
130 std::vector<recob::Hit>&,
163 std::tuple<const reco::ClusterHit2D*, const reco::ClusterHit2D*, const reco::ClusterHit3D>;
183 float hitWidthSclFctr = 1.,
184 size_t hitPairCntr = 0)
const;
199 size_t minStatus)
const;
210 float closestApproach(
const Eigen::Vector3f&,
211 const Eigen::Vector3f&,
212 const Eigen::Vector3f&,
213 const Eigen::Vector3f&,
222 float pairDeltaTimeLimits)
const;
227 int FindNumberInRange(
const Hit2DSet& hit2DSet,
239 float DistanceFromPointToHitWire(
const Eigen::Vector3f& position,
245 void BuildChannelStatusVec()
const;
250 float chargeIntegral(
float,
float,
float,
int,
int)
const;
280 float m_wirePitch[3];
310 mutable bool m_weHaveAllBeenHereBefore =
false;
318 : m_channelFilter(&
art::ServiceHandle<
lariov::ChannelStatusService const>()->GetProvider())
321 "HitFinderTagVec", std::vector<art::InputTag>() = {
"gaushit"});
349 m_tupleTree = tfs->make<TTree>(
"Hit3DBuilderTree",
"Tree by SnippetHit3DBuilder");
373 collector.
produces<std::vector<recob::Hit>>();
418 lariov::ChannelStatusProvider::Status_t chanStat =
m_channelFilter->Status(channel);
428 return (*left).getAvePeakTime() < (*right).getAvePeakTime();
436 if (left->second.size() == right->second.size())
return left->first < right->first;
438 return left->second.size() > right->second.size();
454 std::unique_ptr<std::vector<recob::Hit>> outputHitPtrVec(
new std::vector<recob::Hit>);
466 if (!hitPairList.empty())
472 std::unique_ptr<art::Assns<recob::Wire, recob::Hit>> wireAssns(
478 std::unique_ptr<art::Assns<raw::RawDigit, recob::Hit>> rawDigitAssns(
484 evt.
put(std::move(outputHitPtrVec));
485 evt.
put(std::move(wireAssns));
486 evt.
put(std::move(rawDigitAssns));
502 cet::cpu_timer theClockMakeHits;
513 theClockMakeHits.stop();
518 mf::LogDebug(
"Cluster3D") <<
">>>>> 3D hit building done, found " << numHitPairs <<
" 3D Hits" 527 if (left.first == left.second)
return false;
528 if (right.first == right.second)
return true;
531 return left.first->first.first < right.first->first.first;
556 size_t totalNumHits(0);
557 size_t hitPairCntr(0);
560 size_t nDeadChanHits(0);
566 planeToSnippetHitMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 0));
568 planeToSnippetHitMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 1));
570 planeToSnippetHitMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 2));
572 size_t nPlanesWithHits =
573 (mapItr0 != planeToSnippetHitMap.end() && !mapItr0->second.empty() ? 1 : 0) +
574 (mapItr1 != planeToSnippetHitMap.end() && !mapItr1->second.empty() ? 1 : 0) +
575 (mapItr2 != planeToSnippetHitMap.end() && !mapItr2->second.empty() ? 1 : 0);
577 if (nPlanesWithHits < 2)
continue;
596 mf::LogDebug(
"Cluster3D") <<
"Total number hits: " << totalNumHits << std::endl;
597 mf::LogDebug(
"Cluster3D") <<
"Created a total of " << hitPairList.size()
598 <<
" hit pairs, counted: " << hitPairCntr << std::endl;
599 mf::LogDebug(
"Cluster3D") <<
"-- Triplets: " << nTriplets
600 <<
", dead channel pairs: " << nDeadChanHits << std::endl;
602 return hitPairList.size();
620 auto SetStartIterator =
622 while (startItr != endItr) {
623 if (startItr->first.second < startTime)
631 auto SetEndIterator =
633 while (lastItr != endItr) {
634 if (lastItr->first.first < endTime)
646 std::sort(snippetHitMapItrVec.begin(), snippetHitMapItrVec.end(),
SetStartTimeOrder());
649 int nPlanesWithHits(0);
651 for (
auto& pair : snippetHitMapItrVec)
652 if (pair.first != pair.second) nPlanesWithHits++;
654 if (nPlanesWithHits < 2)
break;
661 snippetHitMapItrVec[1].first, snippetHitMapItrVec[1].
second, firstSnippetItr->first.first);
663 snippetHitMapItr1Start, snippetHitMapItrVec[1].second, firstSnippetItr->first.second);
665 snippetHitMapItrVec[2].first, snippetHitMapItrVec[2].second, firstSnippetItr->first.first);
667 snippetHitMapItr2Start, snippetHitMapItrVec[2].second, firstSnippetItr->first.second);
674 findGoodHitPairs(firstSnippetItr, snippetHitMapItr1Start, snippetHitMapItr1End, pair12Map);
676 findGoodHitPairs(firstSnippetItr, snippetHitMapItr2Start, snippetHitMapItr2End, pair13Map);
678 if (n12Pairs > n13Pairs)
683 snippetHitMapItrVec.front().first++;
686 return hitPairList.size();
697 std::max_element(firstSnippetItr->second.begin(),
698 firstSnippetItr->second.end(),
699 [](
const auto&
left,
const auto&
right) {
700 return left->getHit()->PeakAmplitude() <
right->getHit()->PeakAmplitude();
702 float firstPHCut = firstMaxItr != firstSnippetItr->second.end() ?
707 for (
const auto& hit1 : firstSnippetItr->second) {
709 if (hit1->getHit()->DegreesOfFreedom() > 1 && hit1->getHit()->PeakAmplitude() < firstPHCut &&
717 while (secondHitItr != endItr) {
719 secondHitItr->second.begin(),
720 secondHitItr->second.end(),
721 [](
const auto&
left,
const auto&
right) {
722 return left->getHit()->PeakAmplitude() <
right->getHit()->PeakAmplitude();
724 float secondPHCut = secondMaxItr != secondHitItr->second.end() ?
728 for (
const auto& hit2 : secondHitItr->second) {
730 if (hit2->getHit()->DegreesOfFreedom() > 1 &&
731 hit2->getHit()->PeakAmplitude() < secondPHCut &&
740 std::vector<const recob::Hit*> recobHitVec = {
nullptr,
nullptr,
nullptr};
742 recobHitVec[hit1->WireID().Plane] = hit1->getHit();
743 recobHitVec[hit2->WireID().Plane] = hit2->getHit();
747 hitMatchMap[wireID].emplace_back(hit1, hit2, pair);
764 if (!pair12Map.empty()) {
766 std::vector<reco::ClusterHit3D> tempDeadChanVec;
770 std::map<const reco::ClusterHit3D*, bool> usedPairMap;
773 for (
const auto& pair13 : pair13Map) {
774 for (
const auto& hit2Dhit3DPair : pair13.second)
775 usedPairMap[&std::get<2>(hit2Dhit3DPair)] =
false;
779 for (
const auto& pair12 : pair12Map) {
780 if (pair12.second.empty())
continue;
784 for (
const auto& hit2Dhit3DPair12 : pair12.second) {
788 usedPairMap[&pair1] =
false;
791 for (
const auto& pair13 : pair13Map) {
792 if (pair13.second.empty())
continue;
794 for (
const auto& hit2Dhit3DPair13 : pair13.second) {
796 if (std::get<0>(hit2Dhit3DPair12) != std::get<0>(hit2Dhit3DPair13))
continue;
805 triplet.
setID(hitPairList.size());
806 hitPairList.emplace_back(triplet);
807 usedPairMap[&pair1] =
true;
808 usedPairMap[&pair2] =
true;
817 for (
const auto& pairMapPair : usedPairMap) {
818 if (pairMapPair.second)
continue;
824 tempDeadChanVec.emplace_back(deadChanPair);
828 if (!tempDeadChanVec.empty()) {
830 if (tempDeadChanVec.size() > 1) {
832 std::sort(tempDeadChanVec.begin(),
833 tempDeadChanVec.end(),
834 [](
const auto&
left,
const auto&
right) {
835 return left.getDeltaPeakTime() /
left.getSigmaPeakTime() <
836 right.getDeltaPeakTime() /
right.getSigmaPeakTime();
840 float firstSig = tempDeadChanVec.front().getDeltaPeakTime() /
841 tempDeadChanVec.front().getSigmaPeakTime();
843 tempDeadChanVec.back().getDeltaPeakTime() / tempDeadChanVec.back().getSigmaPeakTime();
844 float sigRange = lastSig - firstSig;
848 float maxSignificance = std::max(0.75 * (firstSig + lastSig), 1.0);
851 tempDeadChanVec.begin(),
852 tempDeadChanVec.end(),
853 [&maxSignificance](
const auto& pair) {
854 return pair.getDeltaPeakTime() / pair.getSigmaPeakTime() > maxSignificance;
858 if (std::distance(tempDeadChanVec.begin(), firstBadElem) > 20)
859 firstBadElem = tempDeadChanVec.begin() + 20;
861 else if (firstBadElem == tempDeadChanVec.begin())
864 tempDeadChanVec.resize(std::distance(tempDeadChanVec.begin(), firstBadElem));
868 for (
auto& pair : tempDeadChanVec) {
869 pair.setID(hitPairList.size());
870 hitPairList.emplace_back(pair);
882 float hitWidthSclFctr,
883 size_t hitPairCntr)
const 906 float hit1Width = hitWidthSclFctr * hit1Sigma;
907 float hit2Width = hitWidthSclFctr * hit2Sigma;
910 if (fabs(hit1Peak - hit2Peak) <= (hit1Width + hit2Width)) {
912 float hit1SigSq = hit1Sigma * hit1Sigma;
913 float hit2SigSq = hit2Sigma * hit2Sigma;
914 float deltaPeakTime = std::fabs(hit1Peak - hit2Peak);
915 float sigmaPeakTime = std::sqrt(hit1SigSq + hit2SigSq);
929 float oneOverWghts = hit1SigSq * hit2SigSq / (hit1SigSq + hit2SigSq);
930 float avePeakTime = (hit1Peak / hit1SigSq + hit2Peak / hit2SigSq) * oneOverWghts;
932 float hitChiSquare = std::pow((hit1Peak - avePeakTime), 2) / hit1SigSq +
933 std::pow((hit2Peak - avePeakTime), 2) / hit2SigSq;
937 float xPosition = (xPositionHit1 / hit1SigSq + xPositionHit2 / hit2SigSq) * hit1SigSq *
938 hit2SigSq / (hit1SigSq + hit2SigSq);
940 Eigen::Vector3f position(
941 xPosition,
float(widIntersect.
y),
float(widIntersect.
z) -
m_zPosOffset);
957 hitVector.resize(3, NULL);
963 unsigned int tpcIdx = hit1->
WireID().
TPC;
966 std::vector<geo::WireID> wireIDVec = {
geo::WireID(cryostatIdx, tpcIdx, 0, 0),
974 std::vector<float> hitDelTSigVec = {0., 0., 0.};
976 hitDelTSigVec[hit1->
WireID().
Plane] = deltaPeakTime / sigmaPeakTime;
977 hitDelTSigVec[hit2->
WireID().
Plane] = deltaPeakTime / sigmaPeakTime;
1013 static const double wirePitch =
1034 if (hitWireDist < wirePitch) {
1047 hit0 = pairHitVec[2];
1049 hit1 = pairHitVec[2];
1061 unsigned int statusBits(0x7);
1062 float avePeakTime(0.);
1063 float weightSum(0.);
1064 float xPosition(0.);
1070 for (
size_t planeIdx = 0; planeIdx < 3; planeIdx++) {
1073 wireIDVec[planeIdx] = hit2D->
WireID();
1086 float weight = 1. / (hitRMS * hitRMS);
1088 avePeakTime += peakTime *
weight;
1093 avePeakTime /= weightSum;
1094 xPosition /= weightSum;
1099 Eigen::Vector3f position(xPosition,
1100 float((pairYZVec[0] + pair0hYZVec[0] + pair1hYZVec[0]) / 3.),
1101 float((pairYZVec[1] + pair0hYZVec[1] + pair1hYZVec[1]) / 3.));
1104 float hitChiSquare(0.);
1105 float sigmaPeakTime(std::sqrt(1. / weightSum));
1106 std::vector<float> hitDelTSigVec;
1108 for (
const auto& hit2D : hitVector) {
1109 float hitRMS = hit2D->getHit()->RMS();
1114 float combRMS = std::sqrt(hitRMS * hitRMS - sigmaPeakTime * sigmaPeakTime);
1115 float peakTime = hit2D->getTimeTicks();
1116 float deltaTime = peakTime - avePeakTime;
1117 float hitSig = deltaTime / combRMS;
1119 hitChiSquare += hitSig * hitSig;
1121 hitDelTSigVec.emplace_back(std::fabs(hitSig));
1126 int lowMinIndex(std::numeric_limits<int>::max());
1127 int lowMaxIndex(std::numeric_limits<int>::min());
1128 int hiMinIndex(std::numeric_limits<int>::max());
1129 int hiMaxIndex(std::numeric_limits<int>::min());
1132 for (
const auto& hit2D : hitVector) {
1138 int hitStart = hit2D->getHit()->PeakTime() - range - 0.5;
1139 int hitStop = hit2D->getHit()->PeakTime() + range + 0.5;
1141 lowMinIndex = std::min(hitStart, lowMinIndex);
1142 lowMaxIndex = std::max(hitStart, lowMaxIndex);
1143 hiMinIndex = std::min(hitStop + 1, hiMinIndex);
1144 hiMaxIndex = std::max(hitStop + 1, hiMaxIndex);
1148 if (hitChiSquare < m_maxHit3DChiSquare && hiMinIndex > lowMaxIndex) {
1150 std::vector<float> chargeVec;
1152 for (
const auto& hit2D : hitVector)
1154 hit2D->getHit()->PeakAmplitude(),
1155 hit2D->getHit()->RMS(),
1160 std::accumulate(chargeVec.begin(), chargeVec.end(), 0.) / float(chargeVec.size());
1161 float overlapRange = float(hiMinIndex - lowMaxIndex);
1162 float overlapFraction = overlapRange / float(hiMaxIndex - lowMinIndex);
1165 std::vector<float> smallestChargeDiffVec;
1166 std::vector<float> chargeAveVec;
1167 float smallestDiff(std::numeric_limits<float>::max());
1168 float maxDeltaPeak(0.);
1169 size_t chargeIndex(0);
1171 for (
size_t idx = 0; idx < 3; idx++) {
1172 size_t leftIdx = (idx + 2) % 3;
1173 size_t rightIdx = (idx + 1) % 3;
1175 smallestChargeDiffVec.push_back(
std::abs(chargeVec[leftIdx] - chargeVec[rightIdx]));
1176 chargeAveVec.push_back(
float(0.5 * (chargeVec[leftIdx] + chargeVec[rightIdx])));
1178 if (smallestChargeDiffVec.back() < smallestDiff) {
1179 smallestDiff = smallestChargeDiffVec.back();
1184 float deltaPeakTime =
1185 hitVector[leftIdx]->getTimeTicks() - hitVector[rightIdx]->getTimeTicks();
1187 if (
std::abs(deltaPeakTime) > maxDeltaPeak) maxDeltaPeak =
std::abs(deltaPeakTime);
1192 float chargeAsymmetry = (chargeAveVec[chargeIndex] - chargeVec[chargeIndex]) /
1193 (chargeAveVec[chargeIndex] + chargeVec[chargeIndex]);
1196 if (chargeAsymmetry < -1. || chargeAsymmetry > 1.) {
1199 std::cout <<
"============> Charge asymmetry out of range: " << chargeAsymmetry
1200 <<
" <============" << std::endl;
1201 std::cout <<
" hit C: " << hitWireID.
Cryostat <<
", TPC: " << hitWireID.
TPC 1202 <<
", Plane: " << hitWireID.
Plane <<
", Wire: " << hitWireID.
Wire 1204 std::cout <<
" charge: " << chargeVec[0] <<
", " << chargeVec[1] <<
", " 1205 << chargeVec[2] << std::endl;
1206 std::cout <<
" index: " << chargeIndex <<
", smallest diff: " << smallestDiff
1212 float deltaPeakTime = *std::max_element(hitDelTSigVec.begin(), hitDelTSigVec.end());
1227 if (maxDeltaPeak > 3. * overlapRange)
return result;
1260 bool success(
false);
1274 Eigen::Vector3f wirePos0(wirePosArr.X(), wirePosArr.Y(), wirePosArr.Z());
1275 Eigen::Vector3f wireDir0(
1281 Eigen::Vector3f wirePos1(wirePosArr.X(), wirePosArr.Y(), wirePosArr.Z());
1282 Eigen::Vector3f wireDir1(
1289 if (
closestApproach(wirePos0, wireDir0, wirePos1, wireDir1, arcLen0, arcLen1)) {
1292 Eigen::Vector3f poca0 = wirePos0 + arcLen0 * wireDir0;
1294 widIntersection.
y = poca0[1];
1295 widIntersection.
z = poca0[2];
1305 const Eigen::Vector3f& u0,
1306 const Eigen::Vector3f& P1,
1307 const Eigen::Vector3f& u1,
1309 float& arcLen1)
const 1312 Eigen::Vector3f w0 = P0 - P1;
1314 float b(u0.dot(u1));
1316 float d(u0.dot(w0));
1317 float e(u1.dot(w0));
1318 float den(a * c - b * b);
1320 arcLen0 = (b *
e - c *
d) / den;
1321 arcLen1 = (a *
e - b *
d) / den;
1323 Eigen::Vector3f poca0 = P0 + arcLen0 * u0;
1324 Eigen::Vector3f poca1 = P1 + arcLen1 * u1;
1326 return (poca0 - poca1).norm();
1337 for (
int sigPos = low; sigPos < hi; sigPos++) {
1338 float arg = (float(sigPos) - peakMean + 0.5) / peakSigma;
1339 integral += peakAmp * std::exp(-0.5 * arg * arg);
1347 size_t maxChanStatus,
1348 size_t minChanStatus)
const 1356 size_t missPlane(2);
1380 bool wireOneStatus = m_channelStatus[wireID.
Plane][wireID.
Wire + 1] < maxChanStatus &&
1381 m_channelStatus[wireID.
Plane][wireID.
Wire + 1] >= minChanStatus;
1384 if (wireStatus || wireOneStatus) {
1386 if (!wireStatus) wireID.
Wire += 1;
1391 Eigen::Vector3f newPosition(
1394 newPosition[1] = (newPosition[1] + widIntersect0->y + widIntersect1->y) / 3.;
1396 (newPosition[2] + widIntersect0->z + widIntersect1->z - 2. *
m_zPosOffset) / 3.;
1421 float pairDeltaTimeLimits)
const 1423 static const float minCharge(0.);
1430 for (
const auto& hit2D : hit2DSet) {
1431 if (hit2D->getHit()->Integral() < minCharge)
continue;
1433 float hitVPeakTime(hit2D->getTimeTicks());
1434 float deltaPeakTime(pairAvePeakTime - hitVPeakTime);
1436 if (deltaPeakTime > pairDeltaTimeLimits)
continue;
1438 if (deltaPeakTime < -pairDeltaTimeLimits)
break;
1440 pairDeltaTimeLimits = fabs(deltaPeakTime);
1451 static const float minCharge(0.);
1453 int numberInRange(0);
1457 for (
const auto& hit2D : hit2DSet) {
1458 if (hit2D->getHit()->Integral() < minCharge)
continue;
1460 float hitVPeakTime(hit2D->getTimeTicks());
1461 float deltaPeakTime(pairAvePeakTime - hitVPeakTime);
1463 if (deltaPeakTime > range)
continue;
1465 if (deltaPeakTime < -range)
break;
1470 return numberInRange;
1481 double distanceToWire =
1484 wireID.
Wire = int(distanceToWire);
1488 mf::LogWarning(
"Cluster3D") <<
"Exception caught finding nearest wire, position - " 1489 << exc.what() << std::endl;
1504 float distance = std::numeric_limits<float>::max();
1512 auto const wirePosArr = wireGeo.
GetCenter();
1514 Eigen::Vector3f wirePos(wirePosArr.X(), wirePosArr.Y(), wirePosArr.Z());
1515 Eigen::Vector3f wireDir(
1519 Eigen::Vector3f hitPosition(wirePos[0], position[1], position[2]);
1522 double arcLen = (hitPosition - wirePos).
dot(wireDir);
1525 if (
abs(arcLen) < wireGeo.
HalfL()) {
1526 Eigen::Vector3f docaVec = hitPosition - (wirePos + arcLen * wireDir);
1528 distance = docaVec.norm();
1533 mf::LogWarning(
"Cluster3D") <<
"Exception caught finding nearest wire, position - " 1534 << exc.what() << std::endl;
1565 std::vector<const recob::Hit*> recobHitVec;
1572 if (!recobHitHandle.
isValid() || recobHitHandle->size() == 0)
continue;
1574 recobHitVec.reserve(recobHitVec.size() + recobHitHandle->size());
1576 for (
const auto&
hit : *recobHitHandle)
1577 recobHitVec.push_back(&
hit);
1581 if (recobHitVec.empty())
return;
1583 cet::cpu_timer theClockMakeHits;
1589 std::map<geo::PlaneID, double> planeOffsetMap;
1592 auto const clock_data =
1594 auto const det_prop =
1598 std::string debugMessage(
"");
1611 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1)) -
1612 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
1614 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2)) -
1615 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
1619 std::ostringstream outputString;
1621 outputString <<
"***> plane 0 offset: " 1623 <<
", plane 1: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 1)]
1624 <<
", plane 2: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 2)]
1626 debugMessage += outputString.str();
1627 outputString <<
" Det prop plane 0: " 1628 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0))
1630 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1))
1632 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2))
1634 debugMessage += outputString.str();
1640 mf::LogDebug(
"Cluster3D") << debugMessage << std::endl;
1642 std::cout << debugMessage << std::endl;
1649 for (
const auto& recobHit : recobHitVec) {
1651 if (recobHit->Integral() < 0.)
continue;
1655 const std::vector<geo::WireID>& wireIDs =
1659 HitStartEndPair hitStartEndPair(recobHit->StartTick(), recobHit->EndTick());
1662 if (hitStartEndPair.second <= hitStartEndPair.first) {
1663 std::cout <<
"Yes, found a hit with end time less than start time: " 1664 << hitStartEndPair.first <<
"/" << hitStartEndPair.second
1665 <<
", mult: " << recobHit->Multiplicity() << std::endl;
1670 for (
auto wireID : wireIDs) {
1680 double hitPeakTime(recobHit->PeakTime() - planeOffsetMap[planeID]);
1681 double xPosition(det_prop.ConvertTicksToX(
1693 theClockMakeHits.stop();
1706 std::vector<recob::Hit>& hitPtrVec,
1710 cet::cpu_timer theClockBuildNewHits;
1718 std::set<const reco::ClusterHit2D*> visitedHit2DSet;
1731 for (
size_t idx = 0; idx < hit3D.getHits().size(); idx++) {
1735 if (visitedHit2DSet.find(hit2D) == visitedHit2DSet.end()) {
1736 visitedHit2DSet.insert(hit2D);
1739 hitPtrVec.emplace_back(
1746 recobHitToPtrMap[newHit] = ptrMaker(hitPtrVec.size() - 1);
1754 size_t numNewHits = hitPtrVec.size();
1757 theClockBuildNewHits.stop();
1762 mf::LogDebug(
"Cluster3D") <<
">>>>> New output recob::Hit size: " << numNewHits <<
" (vs " 1777 std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>> channelToWireMap;
1786 if (hitToWireAssns.isValid()) {
1787 for (
size_t wireIdx = 0; wireIdx < hitToWireAssns.size(); wireIdx++) {
1790 channelToWireMap[wire->
Channel()] = wire;
1796 for (
const auto& hitPtrPair : recobHitPtrMap) {
1799 std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>>
::iterator chanWireItr =
1800 channelToWireMap.find(channel);
1802 if (!(chanWireItr != channelToWireMap.
end())) {
continue; }
1804 wireAssns.
addSingle(chanWireItr->second, hitPtrPair.second);
1817 std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>> channelToRawDigitMap;
1826 if (hitToRawDigitAssns.isValid()) {
1827 for (
size_t rawDigitIdx = 0; rawDigitIdx < hitToRawDigitAssns.size(); rawDigitIdx++) {
1830 channelToRawDigitMap[rawDigit->
Channel()] = rawDigit;
1836 for (
const auto& hitPtrPair : recobHitPtrMap) {
1839 std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>>
::iterator chanRawDigitItr =
1840 channelToRawDigitMap.find(channel);
1842 if (chanRawDigitItr == channelToRawDigitMap.
end()) {
continue; }
1844 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
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
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
unsigned int Nwires(PlaneID const &planeid) const
Returns the total number of wires in the specified plane.
float getTimeTicks() const
SnippetHit3DBuilder class definiton.
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
float getTimeToExecute(IHit3DBuilder::TimeValues index) const override
If monitoring, recover the time to execute a particular function.
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
double WireCoordinate(Point_t const &point) const
Returns the coordinate of the point on the plane, in wire units.
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.
unsigned int NTPC(CryostatID const &cryoid=details::cryostat_zero) const
Returns the total number of TPCs in the specified cryostat.
What follows are several highly useful typedefs which we want to expose to the outside world...
Declaration of signal hit object.
virtual unsigned int Nchannels() const =0
Returns the total number of channels present (not necessarily contiguous)
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.
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
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
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
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.
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.
float m_maxHit3DChiSquare
Provide ability to select hits based on "chi square".
WireGeo const & Wire(WireID const &wireid) const
Returns the specified wire.
bool SetPeakHitPairIteratorOrder(const reco::HitPairList::iterator &left, const reco::HitPairList::iterator &right)
std::vector< float > m_maxPullVec
const recob::Hit * getHit() const
float PeakAmplitude() const
The estimated amplitude of the hit at its peak, in ADC units.
double Length() const
Length is associated with z coordinate [cm].
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.
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)
Interface for a class providing readout channel mapping to geometry.
std::vector< float > m_maxDeltaPeakVec
T get(std::string const &key) const
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
Point_t toPoint(Point const &p)
Convert the specified point into a geo::Point_t.
float getXPosition() const
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.
const geo::WireReadoutGeom * m_wireReadoutGeom
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.
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, Point_t &intersection) const
Computes the intersection between two wires.
unsigned int Nplanes(TPCID const &tpcid=details::tpc_zero) const
Returns the total number of planes in the specified TPC.
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 std::vector< WireID > ChannelToWire(raw::ChannelID_t channel) const =0
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
int trigger_offset(DetectorClocksData const &data)
constexpr WireID()=default
Default constructor: an invalid TPC ID.
std::vector< float > m_deltaTimeVec
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
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
TPCID_t TPC
Index of the TPC within its cryostat.
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
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
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
constexpr PlaneID const & asPlaneID() const
Conversion to WireID (for convenience of notation).
unsigned getStatusBits() const
void setStatusBit(unsigned bits) const