15 #include "art_root_io/TFileDirectory.h" 16 #include "art_root_io/TFileService.h" 18 #include "canvas/Persistency/Common/FindOneP.h" 59 struct Hit2DSetCompare
64 using HitVector = std::vector<const reco::ClusterHit2D*>;
70 using Hit2DSet = std::set<const reco::ClusterHit2D*, Hit2DSetCompare>;
154 using HitMatchTriplet = std::tuple<const reco::ClusterHit2D*,const reco::ClusterHit2D*,const reco::ClusterHit3D>;
171 float hitWidthSclFctr = 1.,
172 size_t hitPairCntr = 0)
const;
195 float closestApproach(
const Eigen::Vector3f&,
const Eigen::Vector3f&,
const Eigen::Vector3f&,
const Eigen::Vector3f&,
float&,
float&)
const;
215 float DistanceFromPointToHitWire(
const Eigen::Vector3f&
position,
const geo::WireID& wireID)
const;
225 float chargeIntegral(
float,
float,
float,
float,
int,
int)
const;
254 float m_wirePitch[3];
285 mutable bool m_weHaveAllBeenHereBefore =
false;
292 m_channelFilter(&
art::ServiceHandle<
lariov::ChannelStatusService
const>()->GetProvider())
302 collector.
produces< std::vector<recob::Hit>>();
311 m_hitFinderTagVec = pset.
get<std::vector<art::InputTag>>(
"HitFinderTagVec", std::vector<art::InputTag>()={
"gaushit"});
334 if (m_outputHistograms)
338 m_tupleTree = tfs->make<TTree>(
"Hit3DBuilderTree",
"Tree by SnippetHit3DBuilder");
413 return (*left).getAvePeakTime() < (*right).getAvePeakTime();
421 if (left->second.size() == right->second.size())
422 return left->first < right->first;
424 return left->second.size() > right->second.size();
438 std::unique_ptr<std::vector<recob::Hit>> outputHitPtrVec(
new std::vector<recob::Hit>);
451 if (!hitPairList.empty())
500 theClockMakeHits.
stop();
505 mf::LogDebug(
"Cluster3D") <<
">>>>> 3D hit building done, found " << numHitPairs <<
" 3D Hits" <<
std::endl;
519 if (left.first == left.second)
return false;
520 if (right.first == right.second)
return true;
523 return left.first->first.first < right.first->first.first;
549 size_t totalNumHits(0);
550 size_t hitPairCntr(0);
553 size_t nDeadChanHits(0);
568 size_t nPlanesWithHits = (mapItr0 != planeToSnippetHitMap.end() && !mapItr0->second.empty() ? 1 : 0)
569 + (mapItr1 != planeToSnippetHitMap.end() && !mapItr1->second.empty() ? 1 : 0)
570 + (mapItr2 != planeToSnippetHitMap.end() && !mapItr2->second.empty() ? 1 : 0);
572 if (nPlanesWithHits < 2)
continue;
591 mf::LogDebug(
"Cluster3D") <<
"Created a total of " << hitPairList.size() <<
" hit pairs, counted: " << hitPairCntr <<
std::endl;
592 mf::LogDebug(
"Cluster3D") <<
"-- Triplets: " << nTriplets <<
", dead channel pairs: " << nDeadChanHits <<
std::endl;
594 return hitPairList.size();
612 while(startItr != endItr)
614 if (startItr->first.second < startTime) startItr++;
622 while(lastItr != endItr)
624 if (lastItr->first.first < endTime) lastItr++;
631 size_t nDeadChanHits(0);
638 std::sort(snippetHitMapItrVec.begin(),snippetHitMapItrVec.end(),
SetStartTimeOrder());
641 int nPlanesWithHits(0);
643 for(
auto& pair : snippetHitMapItrVec)
644 if (pair.first != pair.second) nPlanesWithHits++;
646 if (nPlanesWithHits < 2)
break;
655 SnippetHitMap::iterator snippetHitMapItr1Start = SetStartIterator(snippetHitMapItrVec[1].first, snippetHitMapItrVec[1].
second, firstSnippetItr->first.first);
656 SnippetHitMap::iterator snippetHitMapItr1End = SetEndIterator( snippetHitMapItr1Start, snippetHitMapItrVec[1].second, firstSnippetItr->first.second);
657 SnippetHitMap::iterator snippetHitMapItr2Start = SetStartIterator(snippetHitMapItrVec[2].first, snippetHitMapItrVec[2].second, firstSnippetItr->first.first);
658 SnippetHitMap::iterator snippetHitMapItr2End = SetEndIterator( snippetHitMapItr2Start, snippetHitMapItrVec[2].second, firstSnippetItr->first.second);
661 size_t curHitListSize(hitPairList.size());
665 size_t n12Pairs =
findGoodHitPairs(firstSnippetItr, snippetHitMapItr1Start, snippetHitMapItr1End, pair12Map);
666 size_t n13Pairs =
findGoodHitPairs(firstSnippetItr, snippetHitMapItr2Start, snippetHitMapItr2End, pair13Map);
668 nDeadChanHits += hitPairList.size() - curHitListSize;
669 curHitListSize = hitPairList.size();
671 if (n12Pairs > n13Pairs)
findGoodTriplets(pair12Map, pair13Map, hitPairList);
674 nTriplets += hitPairList.size() - curHitListSize;
676 snippetHitMapItrVec.front().first++;
679 return hitPairList.size();
689 HitVector::iterator firstMaxItr = std::max_element(firstSnippetItr->second.begin(),firstSnippetItr->second.end(),[](
const auto&
left,
const auto&
right){
return left->getHit()->PeakAmplitude() < right->getHit()->PeakAmplitude();});
690 float firstPHCut = firstMaxItr != firstSnippetItr->second.end() ?
m_pulseHeightFrac * (*firstMaxItr)->getHit()->PeakAmplitude() : 4096.;
693 for(
const auto& hit1 : firstSnippetItr->second)
696 if (hit1->getHit()->DegreesOfFreedom() > 1 && hit1->getHit()->PeakAmplitude() < firstPHCut && hit1->getHit()->PeakAmplitude() <
m_PHLowSelection)
continue;
702 while(secondHitItr != endItr)
704 HitVector::iterator secondMaxItr = std::max_element(secondHitItr->second.begin(),secondHitItr->second.end(),[](
const auto&
left,
const auto&
right){
return left->getHit()->PeakAmplitude() < right->getHit()->PeakAmplitude();});
705 float secondPHCut = secondMaxItr != secondHitItr->second.end() ?
m_pulseHeightFrac * (*secondMaxItr)->getHit()->PeakAmplitude() : 0.;
707 for(
const auto& hit2 : secondHitItr->second)
710 if (hit2->getHit()->DegreesOfFreedom() > 1 && hit2->getHit()->PeakAmplitude() < secondPHCut && hit2->getHit()->PeakAmplitude() <
m_PHLowSelection)
continue;
717 std::vector<const recob::Hit*> recobHitVec = {
nullptr,
nullptr,
nullptr};
719 recobHitVec[hit1->WireID().Plane] = hit1->getHit();
720 recobHitVec[hit2->WireID().Plane] = hit2->getHit();
724 hitMatchMap[wireID].emplace_back(hit1,hit2,pair);
739 if (!pair12Map.empty())
742 std::vector<reco::ClusterHit3D> tempDeadChanVec;
746 std::map<const reco::ClusterHit3D*,bool> usedPairMap;
749 for(
const auto& pair13 : pair13Map)
751 for(
const auto& hit2Dhit3DPair : pair13.second) usedPairMap[&std::get<2>(hit2Dhit3DPair)] =
false;
755 for(
const auto& pair12 : pair12Map)
757 if (pair12.second.empty())
continue;
761 for(
const auto& hit2Dhit3DPair12 : pair12.second)
766 usedPairMap[&pair1] =
false;
769 for(
const auto& pair13 : pair13Map)
771 if (pair13.second.empty())
continue;
773 for(
const auto& hit2Dhit3DPair13 : pair13.second)
776 if (std::get<0>(hit2Dhit3DPair12) != std::get<0>(hit2Dhit3DPair13))
continue;
786 triplet.
setID(hitPairList.size());
787 hitPairList.emplace_back(triplet);
788 usedPairMap[&pair1] =
true;
789 usedPairMap[&pair2] =
true;
799 for(
const auto& pairMapPair : usedPairMap)
801 if (pairMapPair.second)
continue;
806 if (
makeDeadChannelPair(deadChanPair, *pair, 4, 0, 0.)) tempDeadChanVec.emplace_back(deadChanPair);
810 if(!tempDeadChanVec.empty())
813 if (tempDeadChanVec.size() > 1)
816 std::sort(tempDeadChanVec.begin(),tempDeadChanVec.end(),[](
const auto&
left,
const auto&
right){
return left.getDeltaPeakTime()/left.getSigmaPeakTime() < right.getDeltaPeakTime()/right.getSigmaPeakTime();});
819 float firstSig = tempDeadChanVec.front().getDeltaPeakTime() / tempDeadChanVec.front().getSigmaPeakTime();
820 float lastSig = tempDeadChanVec.back().getDeltaPeakTime() / tempDeadChanVec.back().getSigmaPeakTime();
821 float sigRange = lastSig - firstSig;
826 float maxSignificance =
std::max(0.75 * (firstSig + lastSig),1.0);
828 std::vector<reco::ClusterHit3D>::iterator firstBadElem = std::find_if(tempDeadChanVec.begin(),tempDeadChanVec.end(),[&maxSignificance](
const auto& pair){
return pair.getDeltaPeakTime()/pair.getSigmaPeakTime() > maxSignificance;});
831 if (
std::distance(tempDeadChanVec.begin(),firstBadElem) > 20) firstBadElem = tempDeadChanVec.begin() + 20;
833 else if (firstBadElem == tempDeadChanVec.begin()) firstBadElem++;
835 tempDeadChanVec.resize(
std::distance(tempDeadChanVec.begin(),firstBadElem));
839 for(
auto& pair : tempDeadChanVec)
841 pair.setID(hitPairList.size());
842 hitPairList.emplace_back(pair);
854 float hitWidthSclFctr,
855 size_t hitPairCntr)
const 877 float hit1Width = hitWidthSclFctr * hit1Sigma;
878 float hit2Width = hitWidthSclFctr * hit2Sigma;
881 if (fabs(hit1Peak - hit2Peak) <= (hit1Width + hit2Width))
884 float hit1SigSq = hit1Sigma * hit1Sigma;
885 float hit2SigSq = hit2Sigma * hit2Sigma;
886 float deltaPeakTime = std::fabs(hit1Peak - hit2Peak);
887 float sigmaPeakTime = std::sqrt(hit1SigSq + hit2SigSq);
901 float oneOverWghts = hit1SigSq * hit2SigSq / (hit1SigSq + hit2SigSq);
902 float avePeakTime = (hit1Peak / hit1SigSq + hit2Peak / hit2SigSq) * oneOverWghts;
904 float hitChiSquare =
std::pow((hit1Peak - avePeakTime),2) / hit1SigSq
905 +
std::pow((hit2Peak - avePeakTime),2) / hit2SigSq;
909 float xPosition = (xPositionHit1 / hit1SigSq + xPositionHit2 / hit2SigSq) * hit1SigSq * hit2SigSq / (hit1SigSq + hit2SigSq);
925 hitVector.resize(3, NULL);
931 unsigned int tpcIdx = hit1->
WireID().
TPC;
934 std::vector<geo::WireID> wireIDVec = {
geo::WireID(cryostatIdx,tpcIdx,0,0),
942 std::vector<float> hitDelTSigVec = {0.,0.,0.};
944 hitDelTSigVec[hit1->
WireID().
Plane] = deltaPeakTime / sigmaPeakTime;
945 hitDelTSigVec[hit2->
WireID().
Plane] = deltaPeakTime / sigmaPeakTime;
1003 if (hitWireDist < wirePitch)
1016 if (!hit0) hit0 = pairHitVec[2];
1017 else if (!hit1) hit1 = pairHitVec[2];
1029 unsigned int statusBits(0x7);
1030 float avePeakTime(0.);
1031 float weightSum(0.);
1032 float xPosition(0.);
1038 for(
size_t planeIdx = 0; planeIdx < 3; planeIdx++)
1042 wireIDVec[planeIdx] = hit2D->
WireID();
1055 float weight = 1. / (hitRMS * hitRMS);
1057 avePeakTime += peakTime *
weight;
1062 avePeakTime /= weightSum;
1063 xPosition /= weightSum;
1068 Eigen::Vector3f
position(xPosition,
1069 float((pairYZVec[0] + pair0hYZVec[0] + pair1hYZVec[0]) / 3.),
1070 float((pairYZVec[1] + pair0hYZVec[1] + pair1hYZVec[1]) / 3.));
1073 float hitChiSquare(0.);
1074 float sigmaPeakTime(std::sqrt(1./weightSum));
1075 std::vector<float> hitDelTSigVec;
1077 for(
const auto& hit2D : hitVector)
1079 float hitRMS = hit2D->getHit()->RMS();
1085 float combRMS = std::sqrt(hitRMS*hitRMS - sigmaPeakTime*sigmaPeakTime);
1086 float peakTime = hit2D->getTimeTicks();
1087 float deltaTime = peakTime - avePeakTime;
1088 float hitSig = deltaTime / combRMS;
1090 hitChiSquare += hitSig * hitSig;
1092 hitDelTSigVec.emplace_back(std::fabs(hitSig));
1103 for(
const auto& hit2D : hitVector)
1111 int hitStart = hit2D->getHit()->PeakTime() - range - 0.5;
1112 int hitStop = hit2D->getHit()->PeakTime() + range + 0.5;
1114 lowMinIndex =
std::min(hitStart, lowMinIndex);
1115 lowMaxIndex =
std::max(hitStart, lowMaxIndex);
1116 hiMinIndex =
std::min(hitStop + 1, hiMinIndex);
1117 hiMaxIndex =
std::max(hitStop + 1, hiMaxIndex);
1121 if (hitChiSquare < m_maxHit3DChiSquare && hiMinIndex > lowMaxIndex)
1124 std::vector<float> chargeVec;
1126 for(
const auto& hit2D : hitVector)
1127 chargeVec.push_back(
chargeIntegral(hit2D->getHit()->PeakTime(),hit2D->getHit()->PeakAmplitude(),hit2D->getHit()->RMS(),1.,lowMaxIndex,hiMinIndex));
1129 float totalCharge = std::accumulate(chargeVec.begin(),chargeVec.end(),0.) /
float(chargeVec.size());
1130 float overlapRange =
float(hiMinIndex - lowMaxIndex);
1131 float overlapFraction = overlapRange /
float(hiMaxIndex - lowMinIndex);
1134 std::vector<float> smallestChargeDiffVec;
1135 std::vector<float> chargeAveVec;
1137 float maxDeltaPeak(0.);
1138 size_t chargeIndex(0);
1140 for(
size_t idx = 0; idx < 3; idx++)
1142 size_t leftIdx = (idx + 2) % 3;
1143 size_t rightIdx = (idx + 1) % 3;
1145 smallestChargeDiffVec.push_back(
std::abs(chargeVec[leftIdx] - chargeVec[rightIdx]));
1146 chargeAveVec.push_back(
float(0.5 * (chargeVec[leftIdx] + chargeVec[rightIdx])));
1148 if (smallestChargeDiffVec.back() < smallestDiff)
1150 smallestDiff = smallestChargeDiffVec.back();
1155 float deltaPeakTime = hitVector[leftIdx]->getTimeTicks() - hitVector[rightIdx]->getTimeTicks();
1157 if (
std::abs(deltaPeakTime) > maxDeltaPeak) maxDeltaPeak =
std::abs(deltaPeakTime);
1162 float chargeAsymmetry = (chargeAveVec[chargeIndex] - chargeVec[chargeIndex]) / (chargeAveVec[chargeIndex] + chargeVec[chargeIndex]);
1165 if (chargeAsymmetry < -1. || chargeAsymmetry > 1.)
1169 std::cout <<
"============> Charge asymmetry out of range: " << chargeAsymmetry <<
" <============" <<
std::endl;
1170 std::cout <<
" hit C: " << hitWireID.
Cryostat <<
", TPC: " << hitWireID.
TPC <<
", Plane: " << hitWireID.
Plane <<
", Wire: " << hitWireID.
Wire <<
std::endl;
1171 std::cout <<
" charge: " << chargeVec[0] <<
", " << chargeVec[1] <<
", " << chargeVec[2] <<
std::endl;
1172 std::cout <<
" index: " << chargeIndex <<
", smallest diff: " << smallestDiff <<
std::endl;
1177 float deltaPeakTime = *std::max_element(hitDelTSigVec.begin(),hitDelTSigVec.end());
1193 if (maxDeltaPeak > 3. * overlapRange)
return result;
1226 bool success(
false);
1236 double wirePosArr[3] = {0.,0.,0.};
1239 Eigen::Vector3f wirePos0(wirePosArr[0],wirePosArr[1],wirePosArr[2]);
1249 Eigen::Vector3f wirePos1(wirePosArr[0],wirePosArr[1],wirePosArr[2]);
1260 if (
closestApproach(wirePos0, wireDir0, wirePos1, wireDir1, arcLen0, arcLen1))
1265 Eigen::Vector3f poca0 = wirePos0 + arcLen0 * wireDir0;
1267 widIntersection.
y = poca0[1];
1268 widIntersection.
z = poca0[2];
1278 const Eigen::Vector3f& u0,
1279 const Eigen::Vector3f& P1,
1280 const Eigen::Vector3f& u1,
1282 float& arcLen1)
const 1285 Eigen::Vector3f w0 = P0 - P1;
1287 float b(u0.dot(u1));
1289 float d(u0.dot(w0));
1290 float e(u1.dot(w0));
1291 float den(a * c -
b *
b);
1293 arcLen0 = (b *
e - c *
d) / den;
1294 arcLen1 = (a *
e - b *
d) / den;
1296 Eigen::Vector3f poca0 = P0 + arcLen0 * u0;
1297 Eigen::Vector3f poca1 = P1 + arcLen1 * u1;
1299 return (poca0 - poca1).norm();
1311 for(
int sigPos = low; sigPos < hi; sigPos++)
1313 float arg = (
float(sigPos) - peakMean + 0.5) / peakSigma;
1314 integral += peakAmp * std::exp(-0.5 * arg * arg);
1322 size_t maxChanStatus,
1323 size_t minChanStatus,
1324 float minOverlap)
const 1332 size_t missPlane(2);
1357 bool wireOneStatus = m_channelStatus[wireID.
Plane][wireID.
Wire+1] < maxChanStatus && m_channelStatus[wireID.
Plane][wireID.
Wire+1] >= minChanStatus;
1360 if(wireStatus || wireOneStatus)
1363 if (!wireStatus) wireID.
Wire += 1;
1376 newPosition[1] = (newPosition[1] + widIntersect0.
y + widIntersect1.
y) / 3.;
1377 newPosition[2] = (newPosition[2] + widIntersect0.
z + widIntersect1.
z - 2. *
m_zPosOffset) / 3.;
1399 static const float minCharge(0.);
1406 for (
const auto& hit2D : hit2DSet)
1408 if (hit2D->getHit()->Integral() < minCharge)
continue;
1410 float hitVPeakTime(hit2D->getTimeTicks());
1411 float deltaPeakTime(pairAvePeakTime-hitVPeakTime);
1413 if (deltaPeakTime > pairDeltaTimeLimits)
continue;
1415 if (deltaPeakTime < -pairDeltaTimeLimits)
break;
1417 pairDeltaTimeLimits = fabs(deltaPeakTime);
1426 static const float minCharge(0.);
1428 int numberInRange(0);
1432 for (
const auto& hit2D : hit2DSet)
1434 if (hit2D->getHit()->Integral() < minCharge)
continue;
1436 float hitVPeakTime(hit2D->getTimeTicks());
1437 float deltaPeakTime(pairAvePeakTime-hitVPeakTime);
1439 if (deltaPeakTime > range)
continue;
1441 if (deltaPeakTime < -range)
break;
1446 return numberInRange;
1459 wireID.
Wire =
int(distanceToWire);
1464 mf::LogWarning(
"Cluster3D") <<
"Exception caught finding nearest wire, position - " << exc.what() <<
std::endl;
1485 double wirePosArr[3] = {0.,0.,0.};
1488 Eigen::Vector3f wirePos(wirePosArr[0],wirePosArr[1],wirePosArr[2]);
1497 Eigen::Vector3f hitPosition(wirePos[0],position[1],position[2]);
1500 double arcLen = (hitPosition - wirePos).
dot(wireDir);
1505 Eigen::Vector3f docaVec = hitPosition - (wirePos + arcLen * wireDir);
1507 distance = docaVec.norm();
1513 mf::LogWarning(
"Cluster3D") <<
"Exception caught finding nearest wire, position - " << exc.what() <<
std::endl;
1543 std::vector<const recob::Hit*> recobHitVec;
1551 if (!recobHitHandle.
isValid() || recobHitHandle->size() == 0)
continue;
1553 recobHitVec.reserve(recobHitVec.size() + recobHitHandle->size());
1555 for(
const auto&
hit : *recobHitHandle) recobHitVec.push_back(&
hit);
1559 if (recobHitVec.empty())
return;
1567 std::map<geo::PlaneID, double> planeOffsetMap;
1589 - det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx,tpcIdx,0));
1591 - det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx,tpcIdx,0));
1596 std::ostringstream outputString;
1598 outputString <<
"***> plane 0 offset: " << planeOffsetMap[
geo::PlaneID(cryoIdx,tpcIdx,0)] <<
", plane 1: " << planeOffsetMap[
geo::PlaneID(cryoIdx,tpcIdx,1)] <<
", plane 2: " << planeOffsetMap[
geo::PlaneID(cryoIdx,tpcIdx,2)] <<
"\n";
1599 debugMessage += outputString.str();
1600 outputString <<
" Det prop plane 0: " << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx,tpcIdx,0)) <<
", plane 1: " << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx,tpcIdx,1)) <<
", plane 2: " << det_prop.GetXTicksOffset(
geo::PlaneID(cryoIdx,tpcIdx,2)) <<
", Trig: " <<
trigger_offset(clock_data) <<
"\n";
1601 debugMessage += outputString.str();
1617 for (
const auto& recobHit : recobHitVec)
1620 if (recobHit->Integral() < 0.)
continue;
1627 HitStartEndPair hitStartEndPair(recobHit->StartTick(),recobHit->EndTick());
1630 if (hitStartEndPair.second <= hitStartEndPair.first)
1632 std::cout <<
"Yes, found a hit with end time less than start time: " << hitStartEndPair.first <<
"/" << hitStartEndPair.second <<
", mult: " << recobHit->Multiplicity() <<
std::endl;
1638 for(
auto wireID : wireIDs)
1647 double hitPeakTime(recobHit->PeakTime() - planeOffsetMap[planeID]);
1648 double xPosition(det_prop.ConvertTicksToX(recobHit->PeakTime(), planeID.
Plane, planeID.
TPC, planeID.
Cryostat));
1663 theClockMakeHits.
stop();
1675 std::vector<recob::Hit>& hitPtrVec,
1687 std::set<const reco::ClusterHit2D*> visitedHit2DSet;
1701 for(
size_t idx = 0; idx < hit3D.getHits().size(); idx++)
1706 if (visitedHit2DSet.find(hit2D) == visitedHit2DSet.end())
1708 visitedHit2DSet.insert(hit2D);
1717 recobHitToPtrMap[newHit] = ptrMaker(hitPtrVec.size()-1);
1725 size_t numNewHits = hitPtrVec.size();
1729 theClockBuildNewHits.
stop();
1746 std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>> channelToWireMap;
1753 art::FindOneP<recob::Wire> hitToWireAssns(hitHandle, evt, inputTag);
1755 if (hitToWireAssns.isValid())
1757 for(
size_t wireIdx = 0; wireIdx < hitToWireAssns.size(); wireIdx++)
1761 channelToWireMap[wire->
Channel()] = wire;
1767 for(
const auto& hitPtrPair : recobHitPtrMap)
1771 std::unordered_map<raw::ChannelID_t, art::Ptr<recob::Wire>>
::iterator chanWireItr = channelToWireMap.find(channel);
1773 if (!(chanWireItr != channelToWireMap.
end()))
1779 wireAssns.
addSingle(chanWireItr->second, hitPtrPair.second);
1792 std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>> channelToRawDigitMap;
1799 art::FindOneP<raw::RawDigit> hitToRawDigitAssns(hitHandle, evt, inputTag);
1801 if (hitToRawDigitAssns.isValid())
1803 for(
size_t rawDigitIdx = 0; rawDigitIdx < hitToRawDigitAssns.size(); rawDigitIdx++)
1807 channelToRawDigitMap[rawDigit->
Channel()] = rawDigit;
1813 for(
const auto& hitPtrPair : recobHitPtrMap)
1817 std::unordered_map<raw::ChannelID_t, art::Ptr<raw::RawDigit>>
::iterator chanRawDigitItr = channelToRawDigitMap.find(channel);
1819 if (chanRawDigitItr == channelToRawDigitMap.
end())
1825 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
double z
z position of intersection
std::list< reco::ClusterHit3D > HitPairList
void BuildChannelStatusVec(PlaneToWireToHitSetMap &planeToWiretoHitSetMap) const
Create the internal channel status vector (assume will eventually be event-by-event) ...
bool m_weHaveAllBeenHereBefore
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
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
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 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
void findGoodTriplets(HitMatchTripletVecMap &, HitMatchTripletVecMap &, reco::HitPairList &, bool=false) const
This algorithm takes lists of hit pairs and finds good triplets.
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.
std::vector< size_t > ChannelStatusVec
define data structure for keeping track of channel status
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
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
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
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.
SnippetHit3DBuilder(fhicl::ParameterSet const &pset)
Constructor.
std::vector< float > m_timeVector
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
WireID_t Wire
Index of the wire within its plane.
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.
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.
float m_maxHit3DChiSquare
Provide ability to select hits based on "chi square".
std::vector< float > m_maxPullVec
art framework interface to geometry description
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.
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::pair< SnippetHitMap::iterator, SnippetHitMap::iterator > SnippetHitMapItrPair
bool isValid() const noexcept
unsigned short Status_t
type representing channel status
float getAvePeakTime() const
std::map< geo::View_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.
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< float > m_maxSideVecVec
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
std::vector< float > m_maxDeltaPeakVec
T get(std::string const &key) const
virtual void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
std::vector< HitMatchTriplet > HitMatchTripletVec
void makeWireAssns(const art::Event &, art::Assns< recob::Wire, recob::Hit > &, RecobHitToPtrMap &) const
Create recob::Wire to recob::Hit associations.
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={})
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.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
Class providing information about the quality of channels.
PlaneToWireToHitSetMap m_planeToWireToHitSetMap
static int max(int a, int b)
The geometry of one entire detector, as served by art.
PlaneID_t Plane
Index of the plane within its TPC.
std::vector< float > m_overlapFractionVec
std::vector< float > m_spacePointChargeVec
IHit3DBuilder interface class definiton.
std::vector< int > m_smallIndexVec
Detector simulation of raw signals on wires.
std::vector< art::InputTag > m_hitFinderTagVec
Data members to follow.
const_iterator end() const
This provides an art tool interface definition for tools which construct 3D hits used in 3D clusterin...
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
std::set< const reco::ClusterHit2D *, Hit2DSetCompare > Hit2DSet
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
std::map< geo::TPCID, PlaneToWireToHitSetMap > TPCToPlaneToWireToHitSetMap
std::vector< reco::ClusterHit2D * > HitVector
What follows are several highly useful typedefs which we want to expose to the outside world...
double HalfL() const
Returns half the length of the wire [cm].
Filters for channels, events, etc.
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
size_t BuildHitPairMap(PlaneToSnippetHitMap &planeToHitVectorMap, reco::HitPairList &hitPairList) const
Given the ClusterHit2D objects, build the HitPairMap.
std::vector< SnippetHitMapItrPair > PlaneSnippetHitMapItrPairVec
std::map< HitStartEndPair, HitVector > SnippetHitMap
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...
bool operator()(const reco::HitPairClusterMap::iterator &left, const reco::HitPairClusterMap::iterator &right)
float PeakTime() const
Time of the signal peak, in tick units.
Declaration of signal hit object.
bool operator()(const SnippetHitMapItrPair &left, const SnippetHitMapItrPair &right) const
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
void setID(const size_t &id) const
virtual void produces(art::ProducesCollector &) override
Each algorithm may have different objects it wants "produced" so use this to let the top level produc...
bool 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.
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
Interface for experiment-specific channel quality info provider.
int trigger_offset(DetectorClocksData const &data)
std::map< geo::WireID, HitMatchTripletVec > HitMatchTripletVecMap
constexpr WireID()=default
Default constructor: an invalid TPC ID.
detail::Node< FrameID, bool > PlaneID
vector< vector< double > > clear
std::vector< float > m_deltaTimeVec
virtual void Hit3DBuilder(art::Event &, reco::HitPairList &, RecobHitToPtrMap &) override
Given a set of recob hits, run DBscan to form 3D clusters.
2D representation of charge deposited in the TDC/wire plane
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
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.
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::unordered_map< const recob::Hit *, art::Ptr< recob::Hit >> RecobHitToPtrMap
Defines a structure mapping art representation to internal.
void setPosition(const Eigen::Vector3f &pos) const
virtual float getTimeToExecute(IHit3DBuilder::TimeValues index) const override
If monitoring, recover the time to execute a particular function.
bool SetPairStartTimeOrder(const reco::ClusterHit3D &left, const reco::ClusterHit3D &right)
const reco::ClusterHit2D * FindBestMatchingHit(const Hit2DSet &hit2DSet, const reco::ClusterHit3D &pair, float pairDeltaTimeLimits) const
A utility routine for finding a 2D hit closest in time to the given pair.
Hit2DList m_clusterHit2DMasterList
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
Event finding and building.
std::map< unsigned int, Hit2DSet > WireToHitSetMap
WireGeo const & WireIDToWireGeo(geo::WireID const &wireid) const
unsigned getStatusBits() const
void setStatusBit(unsigned bits) const
float chargeIntegral(float, float, float, float, int, int) const
Perform charge integration between limits.