15 #include "art_root_io/TFileDirectory.h" 16 #include "art_root_io/TFileService.h" 21 #include "cetlib/cpu_timer.h" 30 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 31 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 58 struct Hit2DSetCompare {
62 using HitVector = std::vector<const reco::ClusterHit2D*>;
65 using Hit2DList = std::list<reco::ClusterHit2D>;
66 using Hit2DSet = std::set<const reco::ClusterHit2D*, Hit2DSetCompare>;
107 return m_timeVector[index];
128 std::vector<recob::Hit>&,
155 std::vector<std::pair<HitVector::iterator, HitVector::iterator>>;
163 using HitMatchPair = std::pair<const reco::ClusterHit2D*, reco::ClusterHit3D>;
183 float hitWidthSclFctr = 1.,
184 size_t hitPairCntr = 0)
const;
199 size_t minStatus)
const;
206 float pairDeltaTimeLimits)
const;
211 int FindNumberInRange(
const Hit2DSet& hit2DSet,
223 float DistanceFromPointToHitWire(
const Eigen::Vector3f& position,
229 void BuildChannelStatusVec()
const;
234 float chargeIntegral(
float,
float,
float,
int,
int)
const;
261 float m_wirePitch[3];
291 mutable bool m_weHaveAllBeenHereBefore =
false;
298 : m_geometry(
art::ServiceHandle<
geo::Geometry const>{}.get())
308 collector.
produces<std::vector<recob::Hit>>();
318 std::vector<art::InputTag>{
"gaushit"});
342 m_tupleTree = tfs->make<TTree>(
"Hit3DBuilderTree",
"Tree by StandardHit3DBuilder");
403 lariov::ChannelStatusProvider::Status_t chanStat =
m_channelFilter->Status(channel);
413 return (*left).getAvePeakTime() < (*right).getAvePeakTime();
421 if (left->second.size() == right->second.size())
return left->first < right->first;
423 return left->second.size() > right->second.size();
439 std::unique_ptr<std::vector<recob::Hit>> outputHitPtrVec(
new std::vector<recob::Hit>);
451 if (!hitPairList.empty())
457 std::unique_ptr<art::Assns<recob::Wire, recob::Hit>> wireAssns(
463 std::unique_ptr<art::Assns<raw::RawDigit, recob::Hit>> rawDigitAssns(
469 evt.
put(std::move(outputHitPtrVec));
470 evt.
put(std::move(wireAssns));
471 evt.
put(std::move(rawDigitAssns));
487 cet::cpu_timer theClockMakeHits;
498 theClockMakeHits.stop();
503 mf::LogDebug(
"Cluster3D") <<
">>>>> 3D hit building done, found " << numHitPairs <<
" 3D Hits" 510 class SetHitEarliestTimeOrder {
512 SetHitEarliestTimeOrder() :
m_numRMS(1.) {}
513 SetHitEarliestTimeOrder(
float numRMS) :
m_numRMS(numRMS) {}
525 using HitVectorItrPair = std::pair<HitVector::iterator, HitVector::iterator>;
527 class SetStartTimeOrder {
529 SetStartTimeOrder() :
m_numRMS(1.) {}
530 SetStartTimeOrder(
float numRMS) :
m_numRMS(numRMS) {}
532 bool operator()(
const HitVectorItrPair& left,
const HitVectorItrPair& right)
const 535 if (left.first != left.second && right.first != right.second) {
537 return (*left.first)->getTimeTicks() -
m_numRMS * (*left.first)->getHit()->RMS() <
538 (*right.first)->getTimeTicks() -
m_numRMS * (*right.first)->getHit()->RMS();
541 return left.first != left.second;
570 size_t totalNumHits(0);
571 size_t hitPairCntr(0);
574 size_t nDeadChanHits(0);
580 planeToHitVectorMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 0));
582 planeToHitVectorMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 1));
584 planeToHitVectorMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 2));
586 size_t nPlanesWithHits =
587 (mapItr0 != planeToHitVectorMap.end() && !mapItr0->second.empty() ? 1 : 0) +
588 (mapItr1 != planeToHitVectorMap.end() && !mapItr1->second.empty() ? 1 : 0) +
589 (mapItr2 != planeToHitVectorMap.end() && !mapItr2->second.empty() ? 1 : 0);
591 if (nPlanesWithHits < 2)
continue;
598 std::sort(hitVector0.begin(),
601 std::sort(hitVector1.begin(),
604 std::sort(hitVector2.begin(),
609 HitVectorItrPair(hitVector0.begin(), hitVector0.end()),
610 HitVectorItrPair(hitVector1.begin(), hitVector1.end()),
611 HitVectorItrPair(hitVector2.begin(), hitVector2.end())};
621 mf::LogDebug(
"Cluster3D") <<
"Total number hits: " << totalNumHits << std::endl;
622 mf::LogDebug(
"Cluster3D") <<
"Created a total of " << hitPairList.size()
623 <<
" hit pairs, counted: " << hitPairCntr << std::endl;
624 mf::LogDebug(
"Cluster3D") <<
"-- Triplets: " << nTriplets
625 <<
", dead channel pairs: " << nDeadChanHits << std::endl;
627 return hitPairList.size();
644 auto SetStartIterator =
646 while (startItr != endItr) {
648 if ((*startItr)->getTimeTicks() + numRMS * (*startItr)->getHit()->RMS() < startTime)
656 auto SetEndIterator =
658 while (firstItr != endItr) {
660 if ((*firstItr)->getTimeTicks() - numRMS * (*firstItr)->getHit()->RMS() < endTime)
680 std::numeric_limits<float>::epsilon();
681 float goldenTimeEnd = goldenHit->getTimeTicks() +
683 std::numeric_limits<float>::epsilon();
699 size_t n12Pairs =
findGoodHitPairs(goldenHit, hitItr1Start, hitItr1End, pair12Map);
700 size_t n13Pairs =
findGoodHitPairs(goldenHit, hitItr2Start, hitItr2End, pair13Map);
702 if (n12Pairs > n13Pairs)
707 hitItrVec[0].first++;
709 int nPlanesWithHits(0);
711 for (
auto& pair : hitItrVec)
712 if (pair.first != pair.second) nPlanesWithHits++;
714 if (nPlanesWithHits < 2)
break;
717 return hitPairList.size();
728 while (startItr != endItr) {
737 hitMatchMap[wireID].emplace_back(hit, pair);
750 if (!pair12Map.empty()) {
752 std::vector<reco::ClusterHit3D> tempDeadChanVec;
756 std::map<const reco::ClusterHit3D*, bool> usedPairMap;
759 for (
const auto& pair13 : pair13Map) {
760 for (
const auto& hit2Dhit3DPair : pair13.second)
761 usedPairMap[&hit2Dhit3DPair.second] =
false;
765 for (
const auto& pair12 : pair12Map) {
766 if (pair12.second.empty())
continue;
770 for (
const auto& hit2Dhit3DPair12 : pair12.second) {
774 usedPairMap[&pair1] =
false;
777 for (
const auto& pair13 : pair13Map) {
778 if (pair13.second.empty())
continue;
780 for (
const auto& hit2Dhit3DPair13 : pair13.second) {
788 triplet.
setID(hitPairList.size());
789 hitPairList.emplace_back(triplet);
790 usedPairMap[&pair1] =
true;
791 usedPairMap[&pair2] =
true;
800 for (
const auto& pairMapPair : usedPairMap) {
801 if (pairMapPair.second)
continue;
807 tempDeadChanVec.emplace_back(deadChanPair);
811 if (!tempDeadChanVec.empty()) {
813 if (tempDeadChanVec.size() > 1) {
815 std::sort(tempDeadChanVec.begin(),
816 tempDeadChanVec.end(),
817 [](
const auto&
left,
const auto&
right) {
818 return left.getDeltaPeakTime() / left.getSigmaPeakTime() <
819 right.getDeltaPeakTime() / right.getSigmaPeakTime();
823 float firstSig = tempDeadChanVec.front().getDeltaPeakTime() /
824 tempDeadChanVec.front().getSigmaPeakTime();
826 tempDeadChanVec.back().getDeltaPeakTime() / tempDeadChanVec.back().getSigmaPeakTime();
827 float sigRange = lastSig - firstSig;
831 float maxSignificance = std::max(0.75 * (firstSig + lastSig), 1.0);
834 tempDeadChanVec.begin(),
835 tempDeadChanVec.end(),
836 [&maxSignificance](
const auto& pair) {
837 return pair.getDeltaPeakTime() / pair.getSigmaPeakTime() > maxSignificance;
841 if (std::distance(tempDeadChanVec.begin(), firstBadElem) > 20)
842 firstBadElem = tempDeadChanVec.begin() + 20;
844 else if (firstBadElem == tempDeadChanVec.begin())
847 tempDeadChanVec.resize(std::distance(tempDeadChanVec.begin(), firstBadElem));
851 for (
auto& pair : tempDeadChanVec) {
852 pair.setID(hitPairList.size());
853 hitPairList.emplace_back(pair);
865 float hitWidthSclFctr,
866 size_t hitPairCntr)
const 899 float hit1Width = hitWidthSclFctr * hit1Sigma;
900 float hit2Width = hitWidthSclFctr * hit2Sigma;
903 if (fabs(hit1Peak - hit2Peak) <= (hit1Width + hit2Width)) {
905 float hit1SigSq = hit1Sigma * hit1Sigma;
906 float hit2SigSq = hit2Sigma * hit2Sigma;
907 float deltaPeakTime = std::fabs(hit1Peak - hit2Peak);
908 float sigmaPeakTime = std::sqrt(hit1SigSq + hit2SigSq);
914 float oneOverWghts = hit1SigSq * hit2SigSq / (hit1SigSq + hit2SigSq);
915 float avePeakTime = (hit1Peak / hit1SigSq + hit2Peak / hit2SigSq) * oneOverWghts;
917 float hitChiSquare = std::pow((hit1Peak - avePeakTime), 2) / hit1SigSq +
918 std::pow((hit2Peak - avePeakTime), 2) / hit2SigSq;
922 float xPosition = (xPositionHit1 / hit1SigSq + xPositionHit2 / hit2SigSq) * hit1SigSq *
923 hit2SigSq / (hit1SigSq + hit2SigSq);
925 Eigen::Vector3f position(
926 xPosition,
float(widIntersect.
y),
float(widIntersect.
z) -
m_zPosOffset);
942 hitVector.resize(3, NULL);
948 unsigned int tpcIdx = hit1->
WireID().
TPC;
951 std::vector<geo::WireID> wireIDVec = {
geo::WireID(cryostatIdx, tpcIdx, 0, 0),
959 std::vector<float> hitDelTSigVec = {0., 0., 0.};
961 hitDelTSigVec[hit1->
WireID().
Plane] = deltaPeakTime / sigmaPeakTime;
962 hitDelTSigVec[hit2->
WireID().
Plane] = deltaPeakTime / sigmaPeakTime;
998 static const double wirePitch =
1019 if (hitWireDist < wirePitch) {
1032 hit0 = pairHitVec[2];
1034 hit1 = pairHitVec[2];
1046 unsigned int statusBits(0x7);
1047 float avePeakTime(0.);
1048 float weightSum(0.);
1049 float xPosition(0.);
1055 for (
size_t planeIdx = 0; planeIdx < 3; planeIdx++) {
1058 wireIDVec[planeIdx] = hit2D->
WireID();
1073 float weight = 1. / (hitRMS * hitRMS);
1075 avePeakTime += peakTime *
weight;
1080 avePeakTime /= weightSum;
1081 xPosition /= weightSum;
1086 Eigen::Vector3f position(xPosition,
1087 float((pairYZVec[0] + pair0hYZVec[0] + pair1hYZVec[0]) / 3.),
1088 float((pairYZVec[1] + pair0hYZVec[1] + pair1hYZVec[1]) / 3.));
1091 float hitChiSquare(0.);
1092 float sigmaPeakTime(std::sqrt(1. / weightSum));
1093 std::vector<float> hitDelTSigVec;
1095 for (
const auto& hit2D : hitVector) {
1096 float hitRMS = hit2D->getHit()->RMS();
1099 if (hit2D->getHit()->DegreesOfFreedom() < 2)
1100 hitRMS = std::min(hit2D->getTimeTicks() - float(hit2D->getHit()->StartTick()),
1101 float(hit2D->getHit()->EndTick()) - hit2D->getTimeTicks());
1103 float combRMS = std::sqrt(hitRMS * hitRMS - sigmaPeakTime * sigmaPeakTime);
1104 float peakTime = hit2D->getTimeTicks();
1105 float deltaTime = peakTime - avePeakTime;
1106 float hitSig = deltaTime / combRMS;
1108 hitChiSquare += hitSig * hitSig;
1110 hitDelTSigVec.emplace_back(std::fabs(hitSig));
1115 int lowMinIndex(std::numeric_limits<int>::max());
1116 int lowMaxIndex(std::numeric_limits<int>::min());
1117 int hiMinIndex(std::numeric_limits<int>::max());
1118 int hiMaxIndex(std::numeric_limits<int>::min());
1121 for (
const auto& hit2D : hitVector) {
1122 float range = 2. * hit2D->getHit()->RMS();
1125 if (hit2D->getHit()->DegreesOfFreedom() < 2)
1126 range = std::min(hit2D->getTimeTicks() - float(hit2D->getHit()->StartTick()),
1127 float(hit2D->getHit()->EndTick()) - hit2D->getTimeTicks());
1129 int hitStart = hit2D->getHit()->PeakTime() - range - 0.5;
1130 int hitStop = hit2D->getHit()->PeakTime() + range + 0.5;
1132 lowMinIndex = std::min(hitStart, lowMinIndex);
1133 lowMaxIndex = std::max(hitStart, lowMaxIndex);
1134 hiMinIndex = std::min(hitStop + 1, hiMinIndex);
1135 hiMaxIndex = std::max(hitStop + 1, hiMaxIndex);
1139 if (hitChiSquare < m_maxHit3DChiSquare && hiMinIndex > lowMaxIndex) {
1141 std::vector<float> chargeVec;
1143 for (
const auto& hit2D : hitVector)
1145 hit2D->getHit()->PeakAmplitude(),
1146 hit2D->getHit()->RMS(),
1151 std::accumulate(chargeVec.begin(), chargeVec.end(), 0.) / float(chargeVec.size());
1152 float overlapRange = float(hiMinIndex - lowMaxIndex);
1153 float overlapFraction = overlapRange / float(hiMaxIndex - lowMinIndex);
1156 std::vector<float> smallestChargeDiffVec;
1157 std::vector<float> chargeAveVec;
1158 float smallestDiff(std::numeric_limits<float>::max());
1159 float maxDeltaPeak(0.);
1160 size_t chargeIndex(0);
1162 for (
size_t idx = 0; idx < 3; idx++) {
1163 size_t leftIdx = (idx + 2) % 3;
1164 size_t rightIdx = (idx + 1) % 3;
1166 smallestChargeDiffVec.push_back(
std::abs(chargeVec[leftIdx] - chargeVec[rightIdx]));
1167 chargeAveVec.push_back(
float(0.5 * (chargeVec[leftIdx] + chargeVec[rightIdx])));
1169 if (smallestChargeDiffVec.back() < smallestDiff) {
1170 smallestDiff = smallestChargeDiffVec.back();
1175 float deltaPeakTime =
1176 hitVector[leftIdx]->getTimeTicks() - hitVector[rightIdx]->getTimeTicks();
1178 if (
std::abs(deltaPeakTime) > maxDeltaPeak) maxDeltaPeak =
std::abs(deltaPeakTime);
1183 float chargeAsymmetry = (chargeAveVec[chargeIndex] - chargeVec[chargeIndex]) /
1184 (chargeAveVec[chargeIndex] + chargeVec[chargeIndex]);
1187 if (chargeAsymmetry < -1. || chargeAsymmetry > 1.) {
1190 std::cout <<
"============> Charge asymmetry out of range: " << chargeAsymmetry
1191 <<
" <============" << std::endl;
1192 std::cout <<
" hit C: " << hitWireID.
Cryostat <<
", TPC: " << hitWireID.
TPC 1193 <<
", Plane: " << hitWireID.
Plane <<
", Wire: " << hitWireID.
Wire 1195 std::cout <<
" charge: " << chargeVec[0] <<
", " << chargeVec[1] <<
", " 1196 << chargeVec[2] << std::endl;
1197 std::cout <<
" index: " << chargeIndex <<
", smallest diff: " << smallestDiff
1203 float deltaPeakTime = *std::max_element(hitDelTSigVec.begin(), hitDelTSigVec.end());
1218 if (maxDeltaPeak > overlapRange)
return result;
1255 for (
int sigPos = low; sigPos < hi; sigPos++) {
1256 float arg = (float(sigPos) - peakMean + 0.5) / peakSigma;
1257 integral += peakAmp * std::exp(-0.5 * arg * arg);
1265 size_t maxChanStatus,
1266 size_t minChanStatus)
const 1274 size_t missPlane(2);
1298 bool wireOneStatus = m_channelStatus[wireID.
Plane][wireID.
Wire + 1] < maxChanStatus &&
1299 m_channelStatus[wireID.
Plane][wireID.
Wire + 1] >= minChanStatus;
1302 if (wireStatus || wireOneStatus) {
1304 if (!wireStatus) wireID.
Wire += 1;
1313 Eigen::Vector3f newPosition(
1316 newPosition[1] = (newPosition[1] + widIntersect0.
y + widIntersect1.
y) / 3.;
1318 (newPosition[2] + widIntersect0.
z + widIntersect1.
z - 2. *
m_zPosOffset) / 3.;
1343 float pairDeltaTimeLimits)
const 1345 static const float minCharge(0.);
1352 for (
const auto& hit2D : hit2DSet) {
1353 if (hit2D->getHit()->Integral() < minCharge)
continue;
1355 float hitVPeakTime(hit2D->getTimeTicks());
1356 float deltaPeakTime(pairAvePeakTime - hitVPeakTime);
1358 if (deltaPeakTime > pairDeltaTimeLimits)
continue;
1360 if (deltaPeakTime < -pairDeltaTimeLimits)
break;
1362 pairDeltaTimeLimits = fabs(deltaPeakTime);
1373 static const float minCharge(0.);
1375 int numberInRange(0);
1379 for (
const auto& hit2D : hit2DSet) {
1380 if (hit2D->getHit()->Integral() < minCharge)
continue;
1382 float hitVPeakTime(hit2D->getTimeTicks());
1383 float deltaPeakTime(pairAvePeakTime - hitVPeakTime);
1385 if (deltaPeakTime > range)
continue;
1387 if (deltaPeakTime < -range)
break;
1392 return numberInRange;
1403 double distanceToWire =
1406 wireID.
Wire = int(distanceToWire);
1410 mf::LogWarning(
"Cluster3D") <<
"Exception caught finding nearest wire, position - " 1411 << exc.what() << std::endl;
1431 Eigen::Vector3d wireStart;
1432 Eigen::Vector3d wireEnd;
1437 Eigen::Vector3d hitPosition(wireStart[0], position[1], position[2]);
1440 Eigen::Vector3d wireDir = wireEnd - wireStart;
1442 wireDir.normalize();
1445 double arcLen = (hitPosition - wireStart).
dot(wireDir);
1447 Eigen::Vector3d docaVec = hitPosition - (wireStart + arcLen * wireDir);
1449 distance = docaVec.norm();
1453 mf::LogWarning(
"Cluster3D") <<
"Exception caught finding nearest wire, position - " 1454 << exc.what() << std::endl;
1485 std::vector<const recob::Hit*> recobHitVec;
1487 auto const clock_data =
1489 auto const det_prop =
1497 if (!recobHitHandle.
isValid() || recobHitHandle->size() == 0)
continue;
1499 recobHitVec.reserve(recobHitVec.size() + recobHitHandle->size());
1501 for (
const auto&
hit : *recobHitHandle)
1502 recobHitVec.push_back(&
hit);
1506 if (recobHitVec.empty())
return;
1508 cet::cpu_timer theClockMakeHits;
1514 std::map<geo::PlaneID, double> planeOffsetMap;
1517 std::string debugMessage(
"");
1530 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1)) -
1531 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
1533 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2)) -
1534 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
1538 std::ostringstream outputString;
1540 outputString <<
"***> plane 0 offset: " 1542 <<
", plane 1: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 1)]
1543 <<
", plane 2: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 2)]
1545 debugMessage += outputString.str();
1546 outputString <<
" Det prop plane 0: " 1547 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0))
1549 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1))
1551 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2))
1553 debugMessage += outputString.str();
1559 mf::LogDebug(
"Cluster3D") << debugMessage << std::endl;
1566 for (
const auto& recobHit : recobHitVec) {
1568 if (recobHit->Integral() < 0.)
continue;
1575 for (
const auto& wireID : wireIDs) {
1585 double hitPeakTime(recobHit->PeakTime() - planeOffsetMap[planeID]);
1586 double xPosition(det_prop.ConvertTicksToX(
1598 std::sort(hitVectorMap.second.begin(), hitVectorMap.second.end(),
SetHitTimeOrder);
1601 theClockMakeHits.stop();
1614 std::vector<recob::Hit>& hitPtrVec,
1618 cet::cpu_timer theClockBuildNewHits;
1626 std::set<const reco::ClusterHit2D*> visitedHit2DSet;
1639 for (
size_t idx = 0; idx < hit3D.getHits().size(); idx++) {
1643 if (visitedHit2DSet.find(hit2D) == visitedHit2DSet.end()) {
1644 visitedHit2DSet.insert(hit2D);
1647 hitPtrVec.emplace_back(
1654 recobHitToPtrMap[newHit] = ptrMaker(hitPtrVec.size() - 1);
1662 size_t numNewHits = hitPtrVec.size();
1665 theClockBuildNewHits.stop();
1670 mf::LogDebug(
"Cluster3D") <<
">>>>> New output recob::Hit size: " << numNewHits <<
" (vs " 1685 std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>> channelToWireMap;
1694 if (hitToWireAssns.isValid()) {
1695 for (
size_t wireIdx = 0; wireIdx < hitToWireAssns.size(); wireIdx++) {
1698 channelToWireMap[wire->
Channel()] = wire;
1704 for (
const auto& hitPtrPair : recobHitPtrMap) {
1707 std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>>
::iterator chanWireItr =
1708 channelToWireMap.find(channel);
1710 if (!(chanWireItr != channelToWireMap.
end())) {
1711 mf::LogDebug(
"Cluster3D") <<
"** Did not find channel to wire match! Skipping..." 1716 wireAssns.
addSingle(chanWireItr->second, hitPtrPair.second);
1731 std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>> channelToRawDigitMap;
1740 if (hitToRawDigitAssns.isValid()) {
1741 for (
size_t rawDigitIdx = 0; rawDigitIdx < hitToRawDigitAssns.size(); rawDigitIdx++) {
1744 channelToRawDigitMap[rawDigit->
Channel()] = rawDigit;
1750 for (
const auto& hitPtrPair : recobHitPtrMap) {
1753 std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>>
::iterator chanRawDigitItr =
1754 channelToRawDigitMap.find(channel);
1756 if (!(chanRawDigitItr != channelToRawDigitMap.
end())) {
1757 mf::LogDebug(
"Cluster3D") <<
"** Did not find channel to wire match! Skipping..." 1762 rawDigitAssns.
addSingle(chanRawDigitItr->second, hitPtrPair.second);
PlaneToWireToHitSetMap m_planeToWireToHitSetMap
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)
bool makeHitTriplet(reco::ClusterHit3D &pairOut, const reco::ClusterHit3D &pairIn, const reco::ClusterHit2D *hit2) const
Make a 3D HitPair object by checking two hits.
void findGoodTriplets(HitMatchPairVecMap &, HitMatchPairVecMap &, reco::HitPairList &) const
This algorithm takes lists of hit pairs and finds good triplets.
std::vector< float > m_maxDeltaPeakVec
float m_wirePitchScaleFactor
Scaling factor to determine max distance allowed between candidate pairs.
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::vector< float > m_chiSquare3DVec
double z
z position of intersection
std::list< reco::ClusterHit3D > HitPairList
const geo::Geometry * m_geometry
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
std::vector< float > m_hitAsymmetryVec
void CreateNewRecobHitCollection(art::Event &, reco::HitPairList &, std::vector< recob::Hit > &, RecobHitToPtrMap &)
Create a new 2D hit collection from hits associated to 3D space points.
float getTimeTicks() const
std::vector< WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
std::vector< float > m_deltaTimeVec
std::vector< size_t > ChannelStatusVec
define data structure for keeping track of channel status
const Eigen::Vector3f getPosition() const
bool SetHitTimeOrder(const reco::ClusterHit2D *left, const reco::ClusterHit2D *right)
float RMS() const
RMS of the hit shape, in tick units.
Declaration of signal hit object.
size_t BuildHitPairMapByTPC(PlaneHitVectorItrPairVec &planeHitVectorItrPairVec, reco::HitPairList &hitPairList) const
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.
TTree * m_tupleTree
output analysis tree
int findGoodHitPairs(const reco::ClusterHit2D *, HitVector::iterator &, HitVector::iterator &, HitMatchPairVecMap &) const
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.
constexpr auto abs(T v)
Returns the absolute value of the argument.
int DegreesOfFreedom() const
Initial tdc tick for hit.
CryostatID_t Cryostat
Index of cryostat.
void BuildHit3D(reco::HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
std::map< geo::WireID, HitMatchPairVec > HitMatchPairVecMap
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.
void produces(art::ProducesCollector &) override
Each algorithm may have different objects it wants "produced" so use this to let the top level produc...
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
void Hit3DBuilder(art::Event &, reco::HitPairList &, RecobHitToPtrMap &) override
Given a set of recob hits, run DBscan to form 3D clusters.
std::vector< float > m_timeVector
std::map< geo::PlaneID, WireToHitSetMap > PlaneToWireToHitSetMap
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
Length_t DetLength(TPCID const &tpcid=tpc_zero) const
Returns the length of the active volume of the specified TPC.
bool SetPeakHitPairIteratorOrder(const reco::HitPairList::iterator &left, const reco::HitPairList::iterator &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.
void BuildChannelStatusVec() const
Create the internal channel status vector (assume will eventually be event-by-event) ...
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.
std::vector< float > m_spacePointChargeVec
IDparameter< geo::PlaneID > PlaneID
Member type of validated geo::PlaneID parameter.
float m_maxHit3DChiSquare
Provide ability to select hits based on "chi square".
bool isValid() const noexcept
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
std::vector< int > m_smallIndexVec
float getAvePeakTime() const
std::map< size_t, HitVector > HitVectorMap
Class managing the creation of a new recob::Hit object.
void makeWireAssns(const art::Event &, art::Assns< recob::Wire, recob::Hit > &, RecobHitToPtrMap &) const
Create recob::Wire to recob::Hit associations.
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...
Helper functions to create a hit.
PlaneGeo const & Plane(PlaneID const &planeid) const
Returns the specified wire.
std::vector< art::InputTag > m_hitFinderTagVec
Data members to follow.
void produces(std::string const &instanceName={}, Persistable const persistable=Persistable::Yes)
std::list< reco::ClusterHit2D > Hit2DList
std::vector< float > m_pairWireDistVec
std::vector< int > m_invalidTPCVec
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
bool m_outputHistograms
Take the time to create and fill some histograms for diagnostics.
std::map< geo::PlaneID, HitVector > PlaneToHitVectorMap
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
float chargeIntegral(float, float, float, int, int) const
Perform charge integration between limits.
T get(std::string const &key) const
StandardHit3DBuilder class definiton.
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.
Hit2DList m_clusterHit2DMasterList
void CollectArtHits(const art::Event &evt) const
Extract the ART hits and the ART hit-particle relationships.
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
std::vector< float > m_maxSideVecVec
The geometry of one entire detector, as served by art.
std::vector< HitMatchPair > HitMatchPairVec
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.
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
IHit3DBuilder interface class definiton.
bool m_weHaveAllBeenHereBefore
Detector simulation of raw signals on wires.
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.
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...
void makeRawDigitAssns(const art::Event &, art::Assns< raw::RawDigit, recob::Hit > &, RecobHitToPtrMap &) const
Create raw::RawDigit to recob::Hit associations.
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
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
const lariov::ChannelStatusProvider * m_channelFilter
std::map< geo::TPCID, PlaneToWireToHitSetMap > TPCToPlaneToWireToHitSetMap
ChannelStatusByPlaneVec m_channelStatus
std::vector< const reco::ClusterHit2D * > HitVector
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)
std::map< geo::TPCID, PlaneToHitVectorMap > TPCToPlaneToHitVectorMap
float PeakTime() const
Time of the signal peak, in tick units.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
std::pair< const reco::ClusterHit2D *, reco::ClusterHit3D > HitMatchPair
This builds a list of candidate hit pairs from lists of hits on two planes.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
std::vector< float > m_qualityMetricVec
void setID(const size_t &id) const
std::vector< ChannelStatusVec > ChannelStatusByPlaneVec
double y
y position of intersection
std::vector< std::pair< HitVector::iterator, HitVector::iterator >> PlaneHitVectorItrPairVec
Given the ClusterHit2D objects, build the HitPairMap.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
size_t BuildHitPairMap(PlaneToHitVectorMap &planeToHitVectorMap, reco::HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
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)
StandardHit3DBuilder(fhicl::ParameterSet const &pset)
Constructor.
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.
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.
Namespace collecting geometry-related classes utilities.
std::vector< float > m_maxPullVec
float getTimeToExecute(IHit3DBuilder::TimeValues index) const override
If monitoring, recover the time to execute a particular function.
const ClusterHit2DVec & getHits() const
void clear()
clear the tuple vectors before processing next event
std::unordered_map< const recob::Hit *, art::Ptr< recob::Hit >> RecobHitToPtrMap
Defines a structure mapping art representation to internal.
std::vector< float > m_smallChargeDiffVec
void setPosition(const Eigen::Vector3f &pos) const
bool SetPairStartTimeOrder(const reco::ClusterHit3D &left, const reco::ClusterHit3D &right)
void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Event finding and building.
void WireEndPoints(WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
std::vector< float > m_overlapRangeVec
PlaneToHitVectorMap m_planeToHitVectorMap
std::map< unsigned int, Hit2DSet > WireToHitSetMap
unsigned getStatusBits() const
void setStatusBit(unsigned bits) const
std::vector< float > m_overlapFractionVec