15 #include "art_root_io/TFileDirectory.h" 16 #include "art_root_io/TFileService.h" 18 #include "canvas/Persistency/Common/FindOneP.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>;
108 return m_timeVector[
index];
129 std::vector<recob::Hit>&,
156 std::vector<std::pair<HitVector::iterator, HitVector::iterator>>;
164 using HitMatchPair = std::pair<const reco::ClusterHit2D*, reco::ClusterHit3D>;
187 float hitWidthSclFctr = 1.,
188 size_t hitPairCntr = 0)
const;
202 size_t maxStatus = 4,
203 size_t minStatus = 0,
204 float minOverlap = 0.2)
const;
211 float pairDeltaTimeLimits)
const;
216 int FindNumberInRange(
const Hit2DSet& hit2DSet,
228 float DistanceFromPointToHitWire(
const Eigen::Vector3f&
position,
239 float chargeIntegral(
float,
float,
float,
float,
int,
int)
const;
266 float m_wirePitch[3];
296 mutable bool m_weHaveAllBeenHereBefore =
false;
303 : m_geometry(
art::ServiceHandle<
geo::Geometry
const>{}.get())
314 collector.
produces<std::vector<recob::Hit>>();
325 "HitFinderTagVec", std::vector<art::InputTag>() = {
"gaushit"});
348 m_tupleTree = tfs->make<TTree>(
"Hit3DBuilderTree",
"Tree by StandardHit3DBuilder");
439 return (*left).getAvePeakTime() < (*right).getAvePeakTime();
448 if (left->second.size() == right->second.size())
return left->first < right->first;
450 return left->second.size() > right->second.size();
467 std::unique_ptr<std::vector<recob::Hit>> outputHitPtrVec(
new std::vector<recob::Hit>);
479 if (!hitPairList.empty())
485 std::unique_ptr<art::Assns<recob::Wire, recob::Hit>> wireAssns(
491 std::unique_ptr<art::Assns<raw::RawDigit, recob::Hit>> rawDigitAssns(
529 theClockMakeHits.
stop();
534 mf::LogDebug(
"Cluster3D") <<
">>>>> 3D hit building done, found " << numHitPairs <<
" 3D Hits" 543 class SetHitEarliestTimeOrder {
545 SetHitEarliestTimeOrder() :
m_numRMS(1.) {}
546 SetHitEarliestTimeOrder(
float numRMS) :
m_numRMS(numRMS) {}
559 using HitVectorItrPair = std::pair<HitVector::iterator, HitVector::iterator>;
561 class SetStartTimeOrder {
563 SetStartTimeOrder() :
m_numRMS(1.) {}
564 SetStartTimeOrder(
float numRMS) :
m_numRMS(numRMS) {}
567 operator()(
const HitVectorItrPair& left,
const HitVectorItrPair& right)
const 570 if (left.first != left.second && right.first != right.second) {
572 return (*left.first)->getTimeTicks() -
m_numRMS * (*left.first)->getHit()->RMS() <
573 (*right.first)->getTimeTicks() -
m_numRMS * (*right.first)->getHit()->RMS();
576 return left.first != left.second;
607 size_t totalNumHits(0);
608 size_t hitPairCntr(0);
611 size_t nDeadChanHits(0);
617 planeToHitVectorMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 0));
619 planeToHitVectorMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 1));
621 planeToHitVectorMap.find(
geo::PlaneID(cryoIdx, tpcIdx, 2));
623 size_t nPlanesWithHits =
624 (mapItr0 != planeToHitVectorMap.end() && !mapItr0->second.empty() ? 1 : 0) +
625 (mapItr1 != planeToHitVectorMap.end() && !mapItr1->second.empty() ? 1 : 0) +
626 (mapItr2 != planeToHitVectorMap.end() && !mapItr2->second.empty() ? 1 : 0);
628 if (nPlanesWithHits < 2)
continue;
635 std::sort(hitVector0.begin(),
638 std::sort(hitVector1.begin(),
641 std::sort(hitVector2.begin(),
646 HitVectorItrPair(hitVector0.begin(), hitVector0.end()),
647 HitVectorItrPair(hitVector1.begin(), hitVector1.end()),
648 HitVectorItrPair(hitVector2.begin(), hitVector2.end())};
659 mf::LogDebug(
"Cluster3D") <<
"Created a total of " << hitPairList.size()
660 <<
" hit pairs, counted: " << hitPairCntr <<
std::endl;
661 mf::LogDebug(
"Cluster3D") <<
"-- Triplets: " << nTriplets
662 <<
", dead channel pairs: " << nDeadChanHits <<
std::endl;
664 return hitPairList.size();
682 auto SetStartIterator =
684 while (startItr != endItr) {
686 if ((*startItr)->getTimeTicks() + numRMS * (*startItr)->getHit()->RMS() < startTime)
694 auto SetEndIterator =
696 while (firstItr != endItr) {
698 if ((*firstItr)->getTimeTicks() - numRMS * (*firstItr)->getHit()->RMS() < endTime)
707 size_t nDeadChanHits(0);
721 std::numeric_limits<float>::epsilon();
722 float goldenTimeEnd = goldenHit->getTimeTicks() +
724 std::numeric_limits<float>::epsilon();
737 size_t curHitListSize(hitPairList.size());
741 size_t n12Pairs =
findGoodHitPairs(goldenHit, hitItr1Start, hitItr1End, pair12Map);
742 size_t n13Pairs =
findGoodHitPairs(goldenHit, hitItr2Start, hitItr2End, pair13Map);
744 nDeadChanHits += hitPairList.size() - curHitListSize;
745 curHitListSize = hitPairList.size();
747 if (n12Pairs > n13Pairs)
752 nTriplets += hitPairList.size() - curHitListSize;
754 hitItrVec[0].first++;
756 int nPlanesWithHits(0);
758 for (
auto& pair : hitItrVec)
759 if (pair.first != pair.second) nPlanesWithHits++;
761 if (nPlanesWithHits < 2)
break;
764 return hitPairList.size();
776 while (startItr != endItr) {
785 hitMatchMap[wireID].emplace_back(hit, pair);
800 if (!pair12Map.empty()) {
802 std::vector<reco::ClusterHit3D> tempDeadChanVec;
806 std::map<const reco::ClusterHit3D*, bool> usedPairMap;
809 for (
const auto& pair13 : pair13Map) {
810 for (
const auto& hit2Dhit3DPair : pair13.second)
811 usedPairMap[&hit2Dhit3DPair.second] =
false;
815 for (
const auto& pair12 : pair12Map) {
816 if (pair12.second.empty())
continue;
820 for (
const auto& hit2Dhit3DPair12 : pair12.second) {
824 usedPairMap[&pair1] =
false;
827 for (
const auto& pair13 : pair13Map) {
828 if (pair13.second.empty())
continue;
830 for (
const auto& hit2Dhit3DPair13 : pair13.second) {
838 triplet.
setID(hitPairList.size());
839 hitPairList.emplace_back(triplet);
840 usedPairMap[&pair1] =
true;
841 usedPairMap[&pair2] =
true;
850 for (
const auto& pairMapPair : usedPairMap) {
851 if (pairMapPair.second)
continue;
857 tempDeadChanVec.emplace_back(deadChanPair);
861 if (!tempDeadChanVec.empty()) {
863 if (tempDeadChanVec.size() > 1) {
865 std::sort(tempDeadChanVec.begin(),
866 tempDeadChanVec.end(),
867 [](
const auto&
left,
const auto&
right) {
868 return left.getDeltaPeakTime() / left.getSigmaPeakTime() <
869 right.getDeltaPeakTime() / right.getSigmaPeakTime();
873 float firstSig = tempDeadChanVec.front().getDeltaPeakTime() /
874 tempDeadChanVec.front().getSigmaPeakTime();
876 tempDeadChanVec.back().getDeltaPeakTime() / tempDeadChanVec.back().getSigmaPeakTime();
877 float sigRange = lastSig - firstSig;
881 float maxSignificance =
std::max(0.75 * (firstSig + lastSig), 1.0);
884 tempDeadChanVec.begin(),
885 tempDeadChanVec.end(),
886 [&maxSignificance](
const auto& pair) {
887 return pair.getDeltaPeakTime() / pair.getSigmaPeakTime() > maxSignificance;
891 if (
std::distance(tempDeadChanVec.begin(), firstBadElem) > 20)
892 firstBadElem = tempDeadChanVec.begin() + 20;
894 else if (firstBadElem == tempDeadChanVec.begin())
897 tempDeadChanVec.resize(
std::distance(tempDeadChanVec.begin(), firstBadElem));
901 for (
auto& pair : tempDeadChanVec) {
902 pair.setID(hitPairList.size());
903 hitPairList.emplace_back(pair);
916 float hitWidthSclFctr,
917 size_t hitPairCntr)
const 950 float hit1Width = hitWidthSclFctr * hit1Sigma;
951 float hit2Width = hitWidthSclFctr * hit2Sigma;
954 if (fabs(hit1Peak - hit2Peak) <= (hit1Width + hit2Width)) {
956 float hit1SigSq = hit1Sigma * hit1Sigma;
957 float hit2SigSq = hit2Sigma * hit2Sigma;
958 float deltaPeakTime = std::fabs(hit1Peak - hit2Peak);
959 float sigmaPeakTime = std::sqrt(hit1SigSq + hit2SigSq);
965 float oneOverWghts = hit1SigSq * hit2SigSq / (hit1SigSq + hit2SigSq);
966 float avePeakTime = (hit1Peak / hit1SigSq + hit2Peak / hit2SigSq) * oneOverWghts;
968 float hitChiSquare =
std::pow((hit1Peak - avePeakTime), 2) / hit1SigSq +
969 std::pow((hit2Peak - avePeakTime), 2) / hit2SigSq;
973 float xPosition = (xPositionHit1 / hit1SigSq + xPositionHit2 / hit2SigSq) * hit1SigSq *
974 hit2SigSq / (hit1SigSq + hit2SigSq);
977 xPosition,
float(widIntersect.
y),
float(widIntersect.
z) -
m_zPosOffset);
993 hitVector.resize(3, NULL);
999 unsigned int tpcIdx = hit1->
WireID().
TPC;
1002 std::vector<geo::WireID> wireIDVec = {
geo::WireID(cryostatIdx, tpcIdx, 0, 0),
1010 std::vector<float> hitDelTSigVec = {0., 0., 0.};
1012 hitDelTSigVec[hit1->
WireID().
Plane] = deltaPeakTime / sigmaPeakTime;
1013 hitDelTSigVec[hit2->
WireID().
Plane] = deltaPeakTime / sigmaPeakTime;
1050 static const double wirePitch =
1071 if (hitWireDist < wirePitch) {
1084 hit0 = pairHitVec[2];
1086 hit1 = pairHitVec[2];
1098 unsigned int statusBits(0x7);
1099 float avePeakTime(0.);
1100 float weightSum(0.);
1101 float xPosition(0.);
1107 for (
size_t planeIdx = 0; planeIdx < 3; planeIdx++) {
1110 wireIDVec[planeIdx] = hit2D->
WireID();
1125 float weight = 1. / (hitRMS * hitRMS);
1127 avePeakTime += peakTime *
weight;
1132 avePeakTime /= weightSum;
1133 xPosition /= weightSum;
1138 Eigen::Vector3f
position(xPosition,
1139 float((pairYZVec[0] + pair0hYZVec[0] + pair1hYZVec[0]) / 3.),
1140 float((pairYZVec[1] + pair0hYZVec[1] + pair1hYZVec[1]) / 3.));
1143 float hitChiSquare(0.);
1144 float sigmaPeakTime(std::sqrt(1. / weightSum));
1145 std::vector<float> hitDelTSigVec;
1147 for (
const auto& hit2D : hitVector) {
1148 float hitRMS = hit2D->getHit()->RMS();
1151 if (hit2D->getHit()->DegreesOfFreedom() < 2)
1152 hitRMS =
std::min(hit2D->getTimeTicks() -
float(hit2D->getHit()->StartTick()),
1153 float(hit2D->getHit()->EndTick()) - hit2D->getTimeTicks());
1155 float combRMS = std::sqrt(hitRMS * hitRMS - sigmaPeakTime * sigmaPeakTime);
1156 float peakTime = hit2D->getTimeTicks();
1157 float deltaTime = peakTime - avePeakTime;
1158 float hitSig = deltaTime / combRMS;
1160 hitChiSquare += hitSig * hitSig;
1162 hitDelTSigVec.emplace_back(std::fabs(hitSig));
1173 for (
const auto& hit2D : hitVector) {
1174 float range = 2. * hit2D->getHit()->RMS();
1177 if (hit2D->getHit()->DegreesOfFreedom() < 2)
1178 range =
std::min(hit2D->getTimeTicks() -
float(hit2D->getHit()->StartTick()),
1179 float(hit2D->getHit()->EndTick()) - hit2D->getTimeTicks());
1181 int hitStart = hit2D->getHit()->PeakTime() - range - 0.5;
1182 int hitStop = hit2D->getHit()->PeakTime() + range + 0.5;
1184 lowMinIndex =
std::min(hitStart, lowMinIndex);
1185 lowMaxIndex =
std::max(hitStart, lowMaxIndex);
1186 hiMinIndex =
std::min(hitStop + 1, hiMinIndex);
1187 hiMaxIndex =
std::max(hitStop + 1, hiMaxIndex);
1191 if (hitChiSquare < m_maxHit3DChiSquare && hiMinIndex > lowMaxIndex) {
1193 std::vector<float> chargeVec;
1195 for (
const auto& hit2D : hitVector)
1197 hit2D->getHit()->PeakAmplitude(),
1198 hit2D->getHit()->RMS(),
1204 std::accumulate(chargeVec.begin(), chargeVec.end(), 0.) /
float(chargeVec.size());
1205 float overlapRange =
float(hiMinIndex - lowMaxIndex);
1206 float overlapFraction = overlapRange /
float(hiMaxIndex - lowMinIndex);
1209 std::vector<float> smallestChargeDiffVec;
1210 std::vector<float> chargeAveVec;
1212 float maxDeltaPeak(0.);
1213 size_t chargeIndex(0);
1215 for (
size_t idx = 0; idx < 3; idx++) {
1216 size_t leftIdx = (idx + 2) % 3;
1217 size_t rightIdx = (idx + 1) % 3;
1219 smallestChargeDiffVec.push_back(
std::abs(chargeVec[leftIdx] - chargeVec[rightIdx]));
1220 chargeAveVec.push_back(
float(0.5 * (chargeVec[leftIdx] + chargeVec[rightIdx])));
1222 if (smallestChargeDiffVec.back() < smallestDiff) {
1223 smallestDiff = smallestChargeDiffVec.back();
1228 float deltaPeakTime =
1229 hitVector[leftIdx]->getTimeTicks() - hitVector[rightIdx]->getTimeTicks();
1231 if (
std::abs(deltaPeakTime) > maxDeltaPeak) maxDeltaPeak =
std::abs(deltaPeakTime);
1236 float chargeAsymmetry = (chargeAveVec[chargeIndex] - chargeVec[chargeIndex]) /
1237 (chargeAveVec[chargeIndex] + chargeVec[chargeIndex]);
1240 if (chargeAsymmetry < -1. || chargeAsymmetry > 1.) {
1243 std::cout <<
"============> Charge asymmetry out of range: " << chargeAsymmetry
1245 std::cout <<
" hit C: " << hitWireID.
Cryostat <<
", TPC: " << hitWireID.
TPC 1246 <<
", Plane: " << hitWireID.
Plane <<
", Wire: " << hitWireID.
Wire 1248 std::cout <<
" charge: " << chargeVec[0] <<
", " << chargeVec[1] <<
", " 1250 std::cout <<
" index: " << chargeIndex <<
", smallest diff: " << smallestDiff
1256 float deltaPeakTime = *std::max_element(hitDelTSigVec.begin(), hitDelTSigVec.end());
1271 if (maxDeltaPeak > overlapRange)
return result;
1310 for (
int sigPos = low; sigPos < hi; sigPos++) {
1311 float arg = (
float(sigPos) - peakMean + 0.5) / peakSigma;
1312 integral += peakAmp * std::exp(-0.5 * arg * arg);
1321 size_t maxChanStatus,
1322 size_t minChanStatus,
1323 float minOverlap)
const 1331 size_t missPlane(2);
1355 bool wireOneStatus = m_channelStatus[wireID.
Plane][wireID.
Wire + 1] < maxChanStatus &&
1356 m_channelStatus[wireID.
Plane][wireID.
Wire + 1] >= minChanStatus;
1359 if (wireStatus || wireOneStatus) {
1361 if (!wireStatus) wireID.
Wire += 1;
1370 Eigen::Vector3f newPosition(
1373 newPosition[1] = (newPosition[1] + widIntersect0.
y + widIntersect1.
y) / 3.;
1375 (newPosition[2] + widIntersect0.
z + widIntersect1.
z - 2. *
m_zPosOffset) / 3.;
1400 float pairDeltaTimeLimits)
const 1402 static const float minCharge(0.);
1409 for (
const auto& hit2D : hit2DSet) {
1410 if (hit2D->getHit()->Integral() < minCharge)
continue;
1412 float hitVPeakTime(hit2D->getTimeTicks());
1413 float deltaPeakTime(pairAvePeakTime - hitVPeakTime);
1415 if (deltaPeakTime > pairDeltaTimeLimits)
continue;
1417 if (deltaPeakTime < -pairDeltaTimeLimits)
break;
1419 pairDeltaTimeLimits = fabs(deltaPeakTime);
1431 static const float minCharge(0.);
1433 int numberInRange(0);
1437 for (
const auto& hit2D : hit2DSet) {
1438 if (hit2D->getHit()->Integral() < minCharge)
continue;
1440 float hitVPeakTime(hit2D->getTimeTicks());
1441 float deltaPeakTime(pairAvePeakTime - hitVPeakTime);
1443 if (deltaPeakTime > range)
continue;
1445 if (deltaPeakTime < -range)
break;
1450 return numberInRange;
1464 wireID.
Wire =
int(distanceToWire);
1468 mf::LogWarning(
"Cluster3D") <<
"Exception caught finding nearest wire, position - " 1490 Eigen::Vector3d wireStart;
1491 Eigen::Vector3d wireEnd;
1496 Eigen::Vector3d hitPosition(wireStart[0], position[1], position[2]);
1499 Eigen::Vector3d wireDir = wireEnd - wireStart;
1501 wireDir.normalize();
1504 double arcLen = (hitPosition - wireStart).
dot(wireDir);
1506 Eigen::Vector3d docaVec = hitPosition - (wireStart + arcLen * wireDir);
1508 distance = docaVec.norm();
1512 mf::LogWarning(
"Cluster3D") <<
"Exception caught finding nearest wire, position - " 1546 std::vector<const recob::Hit*> recobHitVec;
1548 auto const clock_data =
1550 auto const det_prop =
1558 if (!recobHitHandle.
isValid() || recobHitHandle->size() == 0)
continue;
1560 recobHitVec.reserve(recobHitVec.size() + recobHitHandle->size());
1562 for (
const auto&
hit : *recobHitHandle)
1563 recobHitVec.push_back(&
hit);
1567 if (recobHitVec.empty())
return;
1575 std::map<geo::PlaneID, double> planeOffsetMap;
1591 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1)) -
1592 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
1594 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2)) -
1595 det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0));
1599 std::ostringstream outputString;
1601 outputString <<
"***> plane 0 offset: " 1603 <<
", plane 1: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 1)]
1604 <<
", plane 2: " << planeOffsetMap[
geo::PlaneID(cryoIdx, tpcIdx, 2)]
1606 debugMessage += outputString.str();
1607 outputString <<
" Det prop plane 0: " 1608 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 0))
1610 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 1))
1612 << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx, tpcIdx, 2))
1614 debugMessage += outputString.str();
1627 for (
const auto& recobHit : recobHitVec) {
1629 if (recobHit->Integral() < 0.)
continue;
1636 for (
const auto& wireID : wireIDs) {
1646 double hitPeakTime(recobHit->PeakTime() - planeOffsetMap[planeID]);
1647 double xPosition(det_prop.ConvertTicksToX(
1659 std::sort(hitVectorMap.second.begin(), hitVectorMap.second.end(),
SetHitTimeOrder);
1662 theClockMakeHits.
stop();
1676 std::vector<recob::Hit>& hitPtrVec,
1688 std::set<const reco::ClusterHit2D*> visitedHit2DSet;
1701 for (
size_t idx = 0; idx < hit3D.getHits().size(); idx++) {
1705 if (visitedHit2DSet.find(hit2D) == visitedHit2DSet.end()) {
1706 visitedHit2DSet.insert(hit2D);
1709 hitPtrVec.emplace_back(
1716 recobHitToPtrMap[newHit] = ptrMaker(hitPtrVec.size() - 1);
1724 size_t numNewHits = hitPtrVec.size();
1727 theClockBuildNewHits.
stop();
1732 mf::LogDebug(
"Cluster3D") <<
">>>>> New output recob::Hit size: " << numNewHits <<
" (vs " 1748 std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>> channelToWireMap;
1755 art::FindOneP<recob::Wire> hitToWireAssns(hitHandle, evt, inputTag);
1757 if (hitToWireAssns.isValid()) {
1758 for (
size_t wireIdx = 0; wireIdx < hitToWireAssns.size(); wireIdx++) {
1761 channelToWireMap[wire->
Channel()] = wire;
1767 for (
const auto& hitPtrPair : recobHitPtrMap) {
1770 std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>>
::iterator chanWireItr =
1771 channelToWireMap.find(channel);
1773 if (!(chanWireItr != channelToWireMap.
end())) {
1774 mf::LogDebug(
"Cluster3D") <<
"** Did not find channel to wire match! Skipping..." 1779 wireAssns.
addSingle(chanWireItr->second, hitPtrPair.second);
1795 std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>> channelToRawDigitMap;
1802 art::FindOneP<raw::RawDigit> hitToRawDigitAssns(hitHandle, evt, inputTag);
1804 if (hitToRawDigitAssns.isValid()) {
1805 for (
size_t rawDigitIdx = 0; rawDigitIdx < hitToRawDigitAssns.size(); rawDigitIdx++) {
1808 channelToRawDigitMap[rawDigit->
Channel()] = rawDigit;
1814 for (
const auto& hitPtrPair : recobHitPtrMap) {
1817 std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>>
::iterator chanRawDigitItr =
1818 channelToRawDigitMap.find(channel);
1820 if (!(chanRawDigitItr != channelToRawDigitMap.
end())) {
1821 mf::LogDebug(
"Cluster3D") <<
"** Did not find channel to wire match! Skipping..." 1826 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.
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
std::vector< float > m_chiSquare3DVec
double z
z position of intersection
std::list< reco::ClusterHit3D > HitPairList
const geo::Geometry * m_geometry
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
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
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
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.
size_t BuildHitPairMapByTPC(PlaneHitVectorItrPairVec &planeHitVectorItrPairVec, reco::HitPairList &hitPairList) const
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.
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
int DegreesOfFreedom() const
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
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.
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.
bool SetPeakHitPairIteratorOrder(const HitPairList::iterator &left, const HitPairList::iterator &right)
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
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.
art framework interface to geometry description
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
float m_maxHit3DChiSquare
Provide ability to select hits based on "chi square".
bool isValid() const noexcept
unsigned short Status_t
type representing channel status
std::vector< int > m_smallIndexVec
float getAvePeakTime() const
std::map< geo::View_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.
std::vector< art::InputTag > m_hitFinderTagVec
Data members to follow.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
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)
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.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
virtual Status_t Status(raw::ChannelID_t channel) const
Returns a status integer with arbitrary meaning.
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
virtual bool IsGood(raw::ChannelID_t channel) const
Returns whether the specified channel is physical and good.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Hit2DList m_clusterHit2DMasterList
void CollectArtHits(const art::Event &evt) const
Extract the ART hits and the ART hit-particle relationships.
float getXPosition() const
TimeValues
enumerate the possible values for time checking if monitoring timing
std::vector< float > m_maxSideVecVec
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
Class providing information about the quality of channels.
static int max(int a, int b)
The geometry of one entire detector, as served by art.
std::vector< HitMatchPair > HitMatchPairVec
PlaneID_t Plane
Index of the plane within its TPC.
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
float chargeIntegral(float, float, float, float, int, int) const
Perform charge integration between limits.
IHit3DBuilder interface class definiton.
bool m_weHaveAllBeenHereBefore
Detector simulation of raw signals on wires.
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
void findGoodTriplets(HitMatchPairVecMap &, HitMatchPairVecMap &, reco::HitPairList &, bool=false) const
This algorithm takes lists of hit pairs and finds good triplets.
std::set< const reco::ClusterHit2D *, Hit2DSetCompare > Hit2DSet
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
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< reco::ClusterHit2D * > HitVector
What follows are several highly useful typedefs which we want to expose to the outside world...
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
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.
Declaration of signal hit object.
std::pair< const reco::ClusterHit2D *, reco::ClusterHit3D > HitMatchPair
This builds a list of candidate hit pairs from lists of hits on two planes.
std::vector< float > m_qualityMetricVec
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
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
Interface for experiment-specific channel quality info provider.
int trigger_offset(DetectorClocksData const &data)
void WireEndPoints(geo::WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
StandardHit3DBuilder(fhicl::ParameterSet const &pset)
Constructor.
constexpr WireID()=default
Default constructor: an invalid TPC ID.
detail::Node< FrameID, bool > PlaneID
vector< vector< double > > clear
2D representation of charge deposited in the TDC/wire plane
bool makeDeadChannelPair(reco::ClusterHit3D &pairOut, const reco::ClusterHit3D &pair, size_t maxStatus=4, size_t minStatus=0, float minOverlap=0.2) const
Make a 3D HitPair object from a valid pair and a dead channel in the missing plane.
double WireCoordinate(Point const &point) const
Returns the coordinate of the point on the plane, in wire units.
double accumulated_real_time() const
unsigned int ChannelID_t
Type representing the ID of a readout channel.
TPCID_t TPC
Index of the TPC within its cryostat.
Interface for experiment-specific service for channel quality info.
second_as<> second
Type of time stored in seconds, in double precision.
LArSoft geometry interface.
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.
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
Event finding and building.
std::vector< float > m_overlapRangeVec
void BuildChannelStatusVec(PlaneToWireToHitSetMap &planeToWiretoHitSetMap) const
Create the internal channel status vector (assume will eventually be event-by-event) ...
PlaneToHitVectorMap m_planeToHitVectorMap
std::map< unsigned int, Hit2DSet > WireToHitSetMap
unsigned getStatusBits() const
void setStatusBit(unsigned bits) const
std::vector< float > m_overlapFractionVec