3 #include "fhiclcpp/ParameterSet.h"
4 #include "art/Utilities/ToolMacros.h"
5 #include "art/Framework/Services/Registry/ServiceHandle.h"
6 #include "art_root_io/TFileService.h"
7 #include "art/Framework/Core/ModuleMacros.h"
8 #include "art_root_io/TFileDirectory.h"
9 #include "messagefacility/MessageLogger/MessageLogger.h"
11 #include "canvas/Persistency/Common/FindManyP.h"
19 #include "nusimdata/SimulationBase/MCParticle.h"
24 #include "TProfile2D.h"
50 using HitPtrVec = std::vector<art::Ptr<recob::Hit>>;
70 void configure(fhicl::ParameterSet
const & pset)
override;
78 void initializeHists(art::ServiceHandle<art::TFileService>&,
const std::string&)
override;
92 void endJob(
int numEvents)
override;
171 fGeometry = lar::providerFrom<geo::Geometry>();
176 mf::LogInfo(
"HitEfficiencyAnalysis") <<
"HitEfficiencyAnalysis configured\n";
181 HitEfficiencyAnalysis::~HitEfficiencyAnalysis()
191 void HitEfficiencyAnalysis::configure(fhicl::ParameterSet
const & pset)
193 fWireProducerLabelVec = pset.get< std::vector<art::InputTag> >(
"WireModuleLabelVec", std::vector<art::InputTag>() = {
"decon1droi"});
194 fHitProducerLabelVec = pset.get< std::vector<art::InputTag> >(
"HitModuleLabelVec", std::vector<art::InputTag>() = {
"gaushit"});
197 fLocalDirName = pset.get< std::string >(
"LocalDirName", std::string(
"wow"));
198 fOffsetVec = pset.get< std::vector<unsigned short> >(
"OffsetVec", std::vector<unsigned short>()={0,0,0});
199 fSigmaVec = pset.get< std::vector<float> >(
"SigmaVec", std::vector<float>()={1.,1.,1.});
204 void HitEfficiencyAnalysis::initializeHists(art::ServiceHandle<art::TFileService>&
tfs,
const std::string& dirName)
207 art::TFileDirectory
dir = tfs->mkdir(dirName.c_str());
248 fWireEfficVec.at(plane) = dir.make<TProfile>((
"WireEffic" +
std::to_string(plane)).c_str(),
"Wire Efficiency;# electrons", 200, 0., 100000., 0., 1.);
249 fWireEfficPHVec.at(plane) = dir.make<TProfile>((
"WireEfficPH" +
std::to_string(plane)).c_str(),
"Wire Efficiency;# electrons", 200, 0., 20000., 0., 1.);
251 fHitEfficVec.at(plane) = dir.make<TProfile>((
"HitEffic" +
std::to_string(plane)).c_str(),
"Hit Efficiency;# electrons", 200, 0., 100000., 0., 1.);
252 fHitEfficPHVec.at(plane) = dir.make<TProfile>((
"HitEfficPH" +
std::to_string(plane)).c_str(),
"Hit Efficiency;# electrons", 200, 0., 20000., 0., 1.);
258 void HitEfficiencyAnalysis::initializeTuple(TTree* tree)
262 fTree->Branch(
"CryostataVec",
"std::vector<int>", &
fCryoVec);
288 void HitEfficiencyAnalysis::clear()
const
313 void HitEfficiencyAnalysis::fillHistograms(
const art::Event& event)
const
320 art::Handle< std::vector<sim::SimChannel>> simChannelHandle;
324 if (!simChannelHandle.isValid() || simChannelHandle->empty())
return;
329 using TDCToIDEMap = std::map<unsigned short, float>;
330 using ChanToTDCToIDEMap = std::map<raw::ChannelID_t, TDCToIDEMap>;
331 using PartToChanToTDCToIDEMap = std::map<int, ChanToTDCToIDEMap>;
333 PartToChanToTDCToIDEMap partToChanToTDCToIDEMap;
336 for(
const auto& simChannel : *simChannelHandle)
338 for(
const auto& tdcide : simChannel.TDCIDEMap())
340 for(
const auto& ide : tdcide.second) partToChanToTDCToIDEMap[ide.trackID][simChannel.Channel()][tdcide.first] = ide.numElectrons;
344 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
349 art::Handle< std::vector<recob::Wire> > wireHandle;
352 art::Handle< std::vector<recob::Hit> > hitHandle;
355 art::Handle< std::vector<simb::MCParticle>> mcParticleHandle;
358 if (!wireHandle.isValid() || !hitHandle.isValid() || !mcParticleHandle.isValid())
return;
369 using ChanToWireMap = std::map<raw::ChannelID_t,const recob::Wire*>;
371 ChanToWireMap channelToWireMap;
373 for(
const auto& wire : *wireHandle) channelToWireMap[wire.Channel()] = &wire;
377 using ChanToHitVecMap = std::map<raw::ChannelID_t,std::vector<const recob::Hit*>>;
378 ChanToHitVecMap channelToHitVec;
380 for(
const auto&
hit : *hitHandle) channelToHitVec[
hit.Channel()].push_back(&
hit);
383 using TrackIDToMCParticleMap = std::map<int, const simb::MCParticle*>;
385 TrackIDToMCParticleMap trackIDToMCParticleMap;
387 for(
const auto& mcParticle : *mcParticleHandle) trackIDToMCParticleMap[mcParticle.TrackId()] = &mcParticle;
389 std::vector<int> nSimChannelHitVec = {0,0,0};
390 std::vector<int> nRecobHitVec = {0,0,0};
392 for(
const auto& partToChanInfo : partToChanToTDCToIDEMap)
394 TrackIDToMCParticleMap::const_iterator trackIDToMCPartItr = trackIDToMCParticleMap.find(partToChanInfo.first);
396 if (trackIDToMCPartItr == trackIDToMCParticleMap.end())
continue;
398 int trackPDGCode = trackIDToMCPartItr->second->PdgCode();
399 std::string processName = trackIDToMCPartItr->second->Process();
402 if (fabs(trackPDGCode) != 13 || processName !=
"primary")
continue;
404 for(
const auto& chanToTDCToIDEMap : partToChanInfo.second)
406 TDCToIDEMap tdcToIDEMap = chanToTDCToIDEMap.second;
407 float totalElectrons(0.);
408 float maxElectrons(0.);
409 int nMatchedWires(0);
417 unsigned int plane = wids[0].Plane;
420 for(
const auto& ideVal : tdcToIDEMap)
422 totalElectrons += ideVal.second;
424 maxElectrons = std::max(maxElectrons,ideVal.second);
427 totalElectrons = std::min(totalElectrons,
float(99900.));
432 nSimChannelHitVec.at(plane)++;
434 unsigned short startTDC = tdcToIDEMap.begin()->first;
435 unsigned short stopTDC = tdcToIDEMap.rbegin()->first;
438 unsigned short startTick = clockData.TPCTDC2Tick(startTDC) +
fOffsetVec.at(plane);
439 unsigned short stopTick = clockData.TPCTDC2Tick(stopTDC) +
fOffsetVec.at(plane);
440 unsigned short midTick = (startTick + stopTick) / 2;
445 float nElectronsTotalBest(0.);
446 float hitSummedADCBest(0.);
447 float hitIntegralBest(0.);
448 float hitPeakTimeBest(0.);
449 float hitPeakAmpBest(-100.);
450 float hitRMSBest(0.);
451 float hitBaselineBest(0.);
452 unsigned short hitStopTickBest(0);
453 unsigned short hitStartTickBest(0);
454 unsigned short midHitTickBest(0);
457 ChanToWireMap::const_iterator wireItr = channelToWireMap.find(chanToTDCToIDEMap.first);
459 if (wireItr != channelToWireMap.end())
465 for(
const auto& range : signalROI.
get_ranges())
472 const std::vector<float>& signal = range.data();
477 if (roiFirstBinTick > stopTick || roiLastBinTick < startTick)
continue;
479 wireRangePtr = ⦥
493 ChanToHitVecMap::iterator hitIter = channelToHitVec.find(chanToTDCToIDEMap.first);
495 if (hitIter != channelToHitVec.end())
502 for(
const auto&
hit : hitIter->second)
504 unsigned short hitStartTick =
hit->PeakTime() -
fSigmaVec.at(plane) *
hit->RMS();
505 unsigned short hitStopTick =
hit->PeakTime() +
fSigmaVec.at(plane) *
hit->RMS();
506 unsigned short midHitTick = (hitStopTick + hitStartTick) / 2;
509 if (hitStartTick > stopTick || hitStopTick < startTick)
511 if (plane == 1) rejectedHit =
hit;
515 float hitHeight =
hit->PeakAmplitude();
518 if (hitHeight < hitPeakAmpBest)
continue;
520 hitPeakAmpBest = hitHeight;
522 hitStartTickBest = hitStartTick;
523 hitStopTickBest = hitStopTick;
524 midHitTickBest = midHitTick;
530 nElectronsTotalBest = 0.;
531 hitPeakTimeBest = bestHit->
PeakTime();
532 hitIntegralBest = bestHit->
Integral();
534 hitRMSBest = bestHit->
RMS();
535 hitBaselineBest = 0.;
540 for(
unsigned short tick = hitStartTickBest;
tick <= hitStopTickBest;
tick++)
542 unsigned short hitTDC = clockData.TPCTick2TDC(
tick -
fOffsetVec.at(plane));
544 TDCToIDEMap::iterator ideIterator = tdcToIDEMap.find(hitTDC);
546 if (ideIterator != tdcToIDEMap.end()) nElectronsTotalBest += ideIterator->second;
550 if (nMatchedHits > 0)
553 fHitVsSimChgVec.at(plane)->Fill(std::min(hitSummedADCBest,
float(4999.)), totalElectrons, 1.);
557 fHitNumTDCVec.at(plane)->Fill(hitStopTickBest - hitStartTickBest, 1.);
560 nRecobHitVec.at(plane)++;
562 else if (rejectedHit)
564 unsigned short hitStartTick = rejectedHit->
PeakTime() -
fSigmaVec.at(plane) * rejectedHit->
RMS();
565 unsigned short hitStopTick = rejectedHit->
PeakTime() +
fSigmaVec.at(plane) * rejectedHit->
RMS();
567 std::cout <<
"**> TPC: " << rejectedHit->
WireID().
TPC <<
", Plane " << rejectedHit->
WireID().
Plane <<
", wire: " << rejectedHit->
WireID().
Wire <<
", hit start/ stop tick: " << hitStartTick <<
"/" << hitStopTick <<
", start/stop ticks: " << startTick <<
"/" << stopTick << std::endl;
568 std::cout <<
" 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;
572 std::cout <<
"==> No match, TPC/Plane/Wire: " <<
"/" << wids[0].TPC <<
"/" << wids[0].Plane <<
"/" << wids[0].Wire <<
", # electrons: " << totalElectrons <<
", startTick: " << startTick <<
", stopTick: " << stopTick << std::endl;
578 fWireEfficVec.at(plane)->Fill(totalElectrons, std::min(nMatchedWires,1), 1.);
579 fWireEfficPHVec.at(plane)->Fill(maxElectrons, std::min(nMatchedWires,1), 1.);
582 fHitEfficVec.at(plane)->Fill(totalElectrons, std::min(nMatchedHits,1), 1.);
583 fHitEfficPHVec.at(plane)->Fill(maxElectrons, std::min(nMatchedHits,1), 1.);
587 fCryoVec.push_back(wids[0].Cryostat);
612 if (nSimChannelHitVec.at(idx) > 10)
614 float hitEfficiency = float(nRecobHitVec.at(idx)) /
float(nSimChannelHitVec.at(idx));
617 fNRecobHitVec.at(idx)->Fill(std::min(nRecobHitVec.at(idx),1999), 1.);
627 void HitEfficiencyAnalysis::endJob(
int numEvents)
std::vector< TH1F * > fNSimChannelHitsVec
Utilities related to art service access.
BEGIN_PROLOG true icarus_rawdigitfilter FilterTools FilterPlane1 Plane
geo::WireID WireID() const
float RMS() const
RMS of the hit shape, in tick units.
Declaration of signal hit object.
std::vector< TH1F * > fHitPulseHeightVec
std::vector< TH1F * > fHitEfficiencyVec
std::vector< float > fTotalElectronsVec
std::vector< TProfile * > fWireEfficVec
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.
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.
art::InputTag fSimChannelProducerLabel
void initializeTuple(TTree *) override
Interface for initializing the tuple variables.
std::map< size_t, HitPtrVec > ViewHitMap
const geo::GeometryCore * fGeometry
pointer to Geometry service
std::vector< unsigned short > fOffsetVec
Allow offsets for each plane.
std::vector< int > fCryoVec
std::vector< TH1F * > fSimNumTDCVec
std::vector< TH1F * > fHitPulseWidthVec
std::vector< float > fSigmaVec
Window size for matching to SimChannels.
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< int > fStartTickVec
std::vector< TH1F * > fNMatchedHitVec
std::vector< TProfile * > fHitEfficVec
std::vector< float > fHitBaselinevec
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< float > fHitPeakTimeVec
std::vector< TH1F * > fHitNumTDCVec
std::string fLocalDirName
Fraction for truncated mean.
std::vector< float > fHitIntegralVec
std::vector< int > fWireVec
std::vector< TProfile * > fHitEfficPHVec
std::vector< float > fMaxElectronsVec
std::vector< int > fTPCVec
HitEfficiencyAnalysis(fhicl::ParameterSet const &pset)
Constructor.
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
std::vector< int > fHitStopTickVec
void initializeHists(art::ServiceHandle< art::TFileService > &, const std::string &) override
Interface for initializing the histograms to be filled.
std::vector< int > fStopTickVec
std::vector< int > fHitStartTickVec
PlaneID_t Plane
Index of the plane within its TPC.
Description of geometry of one entire detector.
void endJob(int numEvents) override
Interface for method to executve at the end of run processing.
std::vector< float > fHitPeakAmpVec
art::InputTag fMCParticleProducerLabel
std::vector< float > fHitSummedADCVec
std::vector< TH1F * > fHitElectronsVec
std::vector< art::InputTag > fHitProducerLabelVec
float PeakTime() const
Time of the signal peak, in tick units.
std::vector< TH1F * > fTotalElectronsHistVec
std::string to_string(WindowPattern const &pattern)
std::vector< art::Ptr< recob::Hit >> HitPtrVec
std::vector< TH1F * > fHitSumADCVec
object containing MC truth information necessary for making RawDigits and doing back tracking ...
std::vector< int > fPlaneVec
Range class, with range and data.
std::vector< TH1F * > fNRecobHitVec
float SummedADC() const
The sum of calibrated ADC counts of the hit (0. by default)
Declaration of basic channel signal object.
~HitEfficiencyAnalysis()
Destructor.
2D representation of charge deposited in the TDC/wire plane
art::ServiceHandle< art::TFileService > tfs
std::map< int, ViewHitMap > TrackViewHitMap
std::vector< TH1F * > fMaxElectronsHistVec
TPCID_t TPC
Index of the TPC within its cryostat.
std::vector< TProfile * > fWireEfficPHVec
std::vector< art::InputTag > fWireProducerLabelVec
void configure(fhicl::ParameterSet const &pset) override
std::vector< TH1F * > fDeltaMidTDCVec
art framework interface to geometry description
BEGIN_PROLOG could also be cout
void fillHistograms(const art::Event &) const override
Interface for filling histograms.
std::vector< TH2F * > fHitVsSimChgVec
std::vector< float > fHitPeakRMSVec