Interface for filling histograms.
402 art::Handle< std::vector<sim::SimChannel>> simChannelHandle;
405 art::Handle< std::vector<simb::MCParticle>> mcParticleHandle;
409 if (!simChannelHandle.isValid() || simChannelHandle->empty() || !mcParticleHandle.isValid())
return;
416 using TDCIDEPair = std::pair<unsigned short, const sim::IDE*>;
417 using TickTDCIDEVec = std::vector<TDCIDEPair>;
418 using ChanToTDCIDEMap = std::unordered_map<raw::ChannelID_t,TickTDCIDEVec>;
419 using PartToChanToTDCToIDEMap = std::unordered_map<int, ChanToTDCIDEMap>;
421 PartToChanToTDCToIDEMap partToChanToTDCToIDEMap;
424 for(
const auto& simChannel : *simChannelHandle)
428 for(
const auto& tdcide : simChannel.TDCIDEMap())
430 for(
const auto& ide : tdcide.second)
434 partToChanToTDCToIDEMap[ide.trackID][channel].emplace_back(tdcide.first,&ide);
436 if (ide.energy < std::numeric_limits<float>::epsilon()) mf::LogDebug(
"SpacePointAnalysis") <<
">> epsilon simchan deposited energy: " << ide.energy << std::endl;
444 using ChanToWireMap = std::unordered_map<raw::ChannelID_t,const recob::Wire*>;
446 ChanToWireMap channelToWireMap;
450 using ChanToRawDigitMap = std::unordered_map<raw::ChannelID_t,const raw::RawDigit*>;
452 ChanToRawDigitMap chanToRawDigitMap;
455 art::Handle< std::vector<int>> badChannelHandle;
461 art::Handle< std::vector<raw::RawDigit> > rawDigitHandle;
464 art::Handle< std::vector<recob::Wire> > wireHandle;
467 if (!rawDigitHandle.isValid() || !wireHandle.isValid())
return;
469 for(
const auto& wire : *wireHandle) channelToWireMap[wire.Channel()] = &wire;
471 for(
const auto& rawDigit : *rawDigitHandle) chanToRawDigitMap[rawDigit.Channel()] = &rawDigit;
475 using ChanToHitVecMap = std::unordered_map<raw::ChannelID_t,std::vector<const recob::Hit*>>;
477 ChanToHitVecMap channelToHitVec;
482 art::Handle< std::vector<recob::Hit> > hitHandle;
483 event.getByLabel(hitLabel, hitHandle);
485 for(
const auto&
hit : *hitHandle) channelToHitVec[
hit.Channel()].push_back(&
hit);
489 using TrackIDToMCParticleMap = std::unordered_map<int, const simb::MCParticle*>;
491 TrackIDToMCParticleMap trackIDToMCParticleMap;
493 for(
const auto& mcParticle : *mcParticleHandle)
494 trackIDToMCParticleMap[mcParticle.TrackId()] = &mcParticle;
498 std::vector<int> nSimChannelHitVec = {0,0,0};
499 std::vector<int> nRecobHitVec = {0,0,0};
500 std::vector<int> nFakeHitVec = {0,0,0};
501 std::vector<int> nSimulatedWiresVec = {0,0,0};
503 unsigned int lastwire=-1;
505 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
507 for(
const auto& partToChanInfo : partToChanToTDCToIDEMap)
509 TrackIDToMCParticleMap::const_iterator trackIDToMCPartItr = trackIDToMCParticleMap.find(partToChanInfo.first);
511 if (trackIDToMCPartItr == trackIDToMCParticleMap.end())
continue;
513 int trackPDGCode = trackIDToMCPartItr->second->PdgCode();
514 std::string processName = trackIDToMCPartItr->second->Process();
517 if (fabs(trackPDGCode) != 13 || processName !=
"primary")
continue;
520 Eigen::Vector3f partStartPos(trackIDToMCPartItr->second->Vx(),trackIDToMCPartItr->second->Vy(),trackIDToMCPartItr->second->Vz());
521 Eigen::Vector3f partStartDir(trackIDToMCPartItr->second->Px(),trackIDToMCPartItr->second->Py(),trackIDToMCPartItr->second->Pz());
523 partStartDir.normalize();
525 Eigen::Vector2f partStartDirVecXZ(partStartDir[0],partStartDir[2]);
527 partStartDirVecXZ.normalize();
531 std::vector<Eigen::Vector3f> lastPositionVec = {partStartPos,partStartPos,partStartPos};
533 for(
const auto& chanToTDCToIDEMap : partToChanInfo.second)
542 std::cout <<
"*** skipping bad channel with status: " << chanFilt.
Status(chanToTDCToIDEMap.first) <<
" for channel: " << chanToTDCToIDEMap.first <<
", plane: " << wids[0].Plane <<
", wire: " << wids[0].Wire << std::endl;
549 if (badChannelHandle.isValid())
552 std::vector<int>::const_iterator badItr = std::find(badChannelHandle->begin(),badChannelHandle->end(),chanToTDCToIDEMap.first);
554 if (badItr != badChannelHandle->end())
continue;
575 TickTDCIDEVec tdcToIDEVec = chanToTDCToIDEMap.second;
576 float totalElectrons(0.);
577 float maxElectrons(0.);
578 unsigned short maxElectronsTDC(0);
579 int nMatchedWires(0);
583 std::sort(tdcToIDEVec.begin(),tdcToIDEVec.end(),[](
const auto&
left,
const auto&
right){
return left.first <
right.first;});
590 unsigned int plane = wids[0].Plane;
591 unsigned int wire = wids[0].Wire;
593 Eigen::Vector3f avePosition(0.,0.,0.);
595 if(wire!=lastwire) nSimulatedWiresVec[plane]++;
598 for(
const auto& tdcIdePair : tdcToIDEVec)
600 const sim::IDE* ide = tdcIdePair.second;
602 if (trackPDGCode != ide->
trackID)
continue;
606 if (maxElectrons < ide->numElectrons)
609 maxElectronsTDC = tdcIdePair.first;
612 avePosition += Eigen::Vector3f(ide->
x,ide->
y,ide->
z);
617 avePosition /= float(tdcToIDEVec.size());
619 Eigen::Vector3f partDirVec = avePosition - lastPositionVec[plane];
621 partDirVec.normalize();
623 lastPositionVec[plane] = avePosition;
626 Eigen::Vector2f projPairDirVec(partDirVec[0],partDirVec[2]);
628 projPairDirVec.normalize();
630 float cosThetaXZ = projPairDirVec[0];
632 totalElectrons = std::min(totalElectrons,
float(99900.));
637 nSimChannelHitVec[plane]++;
639 unsigned short startTDC = tdcToIDEVec.begin()->first;
640 unsigned short stopTDC = tdcToIDEVec.rbegin()->first;
643 unsigned short startTick = clockData.TPCTDC2Tick(startTDC) +
fOffsetVec[plane];
644 unsigned short stopTick = clockData.TPCTDC2Tick(stopTDC) +
fOffsetVec[plane];
645 unsigned short maxETick = clockData.TPCTDC2Tick(maxElectronsTDC) +
fOffsetVec[plane];
650 float nElectronsTotalBest(0.);
651 float hitSummedADCBest(0.);
652 float hitIntegralBest(0.);
653 float hitPeakTimeBest(0.);
654 float hitPeakAmpBest(-100.);
655 float hitRMSBest(0.);
656 int hitMultiplicityBest(0);
657 int hitLocalIndexBest(0);
658 float hitGoodnessBest(0.);
659 int hitNumDegreesBest(0);
660 float hitBaselineBest(0.);
661 float hitSnippetLenBest(0.);
662 unsigned short hitStopTickBest(0);
663 unsigned short hitStartTickBest(0);
666 ChanToWireMap::const_iterator wireItr = channelToWireMap.find(chanToTDCToIDEMap.first);
668 if (wireItr != channelToWireMap.end())
674 for(
const auto& range : signalROI.
get_ranges())
681 const std::vector<float>& signal = range.data();
686 if (roiFirstBinTick > stopTick || roiLastBinTick < startTick)
continue;
688 wireRangePtr = ⦥
703 ChanToHitVecMap::iterator hitIter = channelToHitVec.find(chanToTDCToIDEMap.first);
705 if (hitIter != channelToHitVec.end())
711 for(
const auto&
hit : hitIter->second)
713 unsigned short hitStartTick =
hit->PeakTime() -
fSigmaVec[plane] *
hit->RMS();
714 unsigned short hitStopTick =
hit->PeakTime() +
fSigmaVec[plane] *
hit->RMS();
717 if (hitStartTick > stopTick || hitStopTick < startTick)
719 nFakeHitVec[plane]++;
724 float hitHeight =
hit->PeakAmplitude();
727 if (hitHeight < hitPeakAmpBest)
continue;
729 hitPeakAmpBest = hitHeight;
731 hitStartTickBest = hitStartTick;
732 hitStopTickBest = hitStopTick;
738 nElectronsTotalBest = 0.;
739 hitPeakTimeBest = bestHit->
PeakTime();
740 hitIntegralBest = bestHit->
Integral();
742 hitRMSBest = bestHit->
RMS();
748 hitBaselineBest = 0.;
753 for(
int tickIdx = 0; tickIdx < int(tdcToIDEVec.size()); tickIdx++)
756 if (tickIdx > hitStopTickBest - hitStartTickBest)
break;
759 unsigned short hitTDC = clockData.TPCTick2TDC(hitStartTickBest + tickIdx -
fOffsetVec[plane]);
761 if (hitTDC >= tdcToIDEVec[tickIdx].
first)
763 if (tdcToIDEVec[tickIdx].
second->trackID == trackPDGCode) nElectronsTotalBest += tdcToIDEVec[tickIdx].second->numElectrons;
768 if (nMatchedHits > 0)
770 float chgRatioADC = hitSummedADCBest > 0. ? totalElectrons / hitSummedADCBest : 0.;
771 float chgRatioInt = hitIntegralBest > 0. ? totalElectrons / hitIntegralBest : 0.;
777 fHitVsSimChgVec[plane]->Fill(std::min(hitSummedADCBest,
float(999.)), totalElectrons, 1.);
778 fHitVsSimIntVec[plane]->Fill(std::min(hitIntegralBest,
float(999.)), totalElectrons, 1.);
779 fToteVHitEIntVec[plane]->Fill(std::min(totalElectrons,
float(99999.)),std::min(nElectronsTotalBest,
float(99999.)),1.);
783 fHitNumTDCVec[plane]->Fill(std::min(
float(hitStopTickBest - hitStartTickBest),
float(99.5)), 1.);
784 fSnippetLenVec[plane]->Fill(std::min(hitSnippetLenBest,
float(99.5)), 1.);
787 nRecobHitVec[plane]++;
790 else if (rejectedHit)
795 mf::LogDebug(
"TrackHitEfficiencyAnalysis") <<
"**> TPC: " << rejectedHit->
WireID().
TPC <<
", Plane " << rejectedHit->
WireID().
Plane <<
", wire: " << rejectedHit->
WireID().
Wire <<
", hit startstop tick: " << hitStartTick <<
"/" << hitStopTick <<
", start/stop ticks: " << startTick <<
"/" << stopTick << std::endl;
796 mf::LogDebug(
"TrackHitEfficiencyAnalysis") <<
" TPC/Plane/Wire: " << wids[0].TPC <<
"/" << plane <<
"/" << wids[0].Wire <<
", Track # hits: " << partToChanInfo.second.size() <<
", # hits: "<< hitIter->second.size() <<
", # electrons: " << totalElectrons <<
", pulse Height: " << rejectedHit->
PeakAmplitude() <<
", charge: " << rejectedHit->
Integral() <<
", " <<rejectedHit->
SummedADC() << std::endl;
800 mf::LogDebug(
"TrackHitEfficiencyAnalysis") <<
"==> No match, TPC/Plane/Wire: " <<
"/" << wids[0].TPC <<
"/" << wids[0].Plane <<
"/" << wids[0].Wire <<
", # electrons: " << totalElectrons <<
", startTick: " << startTick <<
", stopTick: " << stopTick << std::endl;
806 fWireEfficVec.at(plane)->Fill(totalElectrons, std::min(nMatchedWires,1), 1.);
807 fWireEfficPHVec.at(plane)->Fill(maxElectrons, std::min(nMatchedWires,1), 1.);
809 float matchHit = std::min(nMatchedHits,1);
810 float snippetLen = std::min(
float(stopTick - startTick),
float(99.5));
813 fHitEfficVec[plane]->Fill(totalElectrons, matchHit, 1.);
819 fHitENEvXZVec[plane]->Fill(cosThetaXZ, totalElectrons, matchHit);
823 fCryoVec.push_back(wids[0].Cryostat);
856 if (nSimChannelHitVec[idx] > 10)
858 float hitEfficiency = float(nRecobHitVec[idx]) / float(nSimChannelHitVec[idx]);
861 fNRecobHitVec[idx]->Fill(std::min(nRecobHitVec[idx],1999), 1.);
862 fNFakeHitVec[idx]->Fill(nFakeHitVec[idx]/(
float)nSimulatedWiresVec[idx],1.);
short int LocalIndex() const
How well do we believe we know this hit?
TrackID_t trackID
Geant4 supplied track ID.
std::vector< float > fHitIntegralVec
std::vector< TH1F * > fNFakeHitVec
std::vector< TProfile * > fHitEfficXZVec
float z
z position of ionization [cm]
std::vector< TH1F * > fTotalElectronsHistVec
std::vector< float > fSigmaVec
Window size for matching to SimChannels.
std::vector< TH1F * > fSimDivHitChgVec
std::vector< int > fStopTickVec
float fSimChannelMinEnergy
BEGIN_PROLOG true icarus_rawdigitfilter FilterTools FilterPlane1 Plane
std::vector< TProfile * > fHitEfficPHVec
std::vector< float > fHitPeakAmpVec
std::vector< float > fHitBaselinevec
std::vector< int > fPlaneVec
geo::WireID WireID() const
float RMS() const
RMS of the hit shape, in tick units.
std::vector< TH1F * > fHitEfficiencyVec
std::vector< int > fNumDegreesVec
std::vector< TH1F * > fSnippetLenVec
std::vector< TH2F * > fToteVHitEIntVec
std::vector< int > fMaxETickVec
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.
const range_list_t & get_ranges() const
Returns the internal list of non-void ranges.
std::vector< int > fStartTickVec
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
std::vector< TProfile * > fWireEfficVec
WireID_t Wire
Index of the wire within its plane.
std::vector< float > fMaxElectronsVec
std::vector< TH2F * > fHitVsSimIntVec
float GoodnessOfFit() const
Degrees of freedom in the determination of the hit signal shape (-1 by default)
std::vector< TH1F * > fSimNumTDCVec
short int Multiplicity() const
How many hits could this one be shared with.
float x
x position of ionization [cm]
art::InputTag fBadChannelProducerLabel
std::vector< int > fOffsetVec
Allow offsets for each plane.
float PeakAmplitude() const
The estimated amplitude of the hit at its peak, in ADC units.
int TDCtick_t
Type representing a TDC tick.
std::vector< TH1F * > fDeltaMidTDCVec
std::vector< TH1F * > fHitIntegralHistVec
std::vector< TProfile * > fHitEfficRMSVec
std::vector< TH1F * > fHitNumTDCVec
art::InputTag fMCParticleProducerLabel
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
std::vector< int > fWireVec
std::vector< TProfile * > fWireEfficPHVec
Ionization at a point of the TPC sensitive volume.
std::vector< int > fTPCVec
std::vector< TH1F * > fHitElectronsVec
std::vector< int > fHitMultiplicityVec
std::vector< float > fHitGoodnessVec
std::vector< TH1F * > fNMatchedHitVec
virtual Status_t Status(raw::ChannelID_t channel) const
Returns a status integer with arbitrary meaning.
std::vector< TH1F * > fHitPulseHeightVec
art::InputTag fSimChannelProducerLabel
Class providing information about the quality of channels.
std::vector< TProfile * > fHitEfficVec
PlaneID_t Plane
Index of the plane within its TPC.
std::vector< int > fNMatchedWires
std::vector< art::InputTag > fHitProducerLabelVec
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
std::vector< float > fHitPeakTimeVec
std::vector< TProfile * > fCosXZvRMSVec
float y
y position of ionization [cm]
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
std::vector< art::InputTag > fRawDigitProducerLabelVec
std::vector< TH1F * > fHitPulseWidthVec
std::vector< int > fHitLocalIndexVec
std::vector< TH1F * > fHitSumADCVec
std::vector< int > fCryoVec
float PeakTime() const
Time of the signal peak, in tick units.
std::vector< art::InputTag > fWireProducerLabelVec
std::vector< TProfile2D * > fHitENEvXZVec
std::vector< TH1F * > fNSimChannelHitsVec
std::vector< TH2F * > fHitVsSimChgVec
std::vector< int > fHitStopTickVec
std::vector< int > fHitStartTickVec
std::vector< TH1F * > fNRecobHitVec
int fMinAllowedChanStatus
Don't consider channels with lower status.
std::vector< float > fPartDirY
Range class, with range and data.
float SummedADC() const
The sum of calibrated ADC counts of the hit (0. by default)
std::vector< TH1F * > fSimDivHitChg1Vec
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.
std::vector< float > fPartDirZ
std::vector< float > fHitSummedADCVec
std::vector< float > fTotalElectronsVec
std::vector< float > fHitPeakRMSVec
std::vector< float > fPartDirX
BEGIN_PROLOG could also be cout
float numElectrons
number of electrons at the readout for this track ID and time
std::vector< TH1F * > fMaxElectronsHistVec
std::vector< int > fNMatchedHits
const geo::GeometryCore * fGeometry
pointer to Geometry service