21 #include "art/Framework/Core/EDAnalyzer.h"
22 #include "art/Framework/Principal/Event.h"
23 #include "art/Framework/Principal/Handle.h"
24 #include "art/Framework/Services/Registry/ServiceHandle.h"
25 #include "art_root_io/TFileService.h"
26 #include "art/Framework/Core/ModuleMacros.h"
27 #include "art/Utilities/make_tool.h"
28 #include "messagefacility/MessageLogger/MessageLogger.h"
29 #include "fhiclcpp/ParameterSet.h"
30 #include "cetlib_except/exception.h"
31 #include "canvas/Persistency/Common/FindManyP.h"
32 #include "canvas/Persistency/Common/PtrVector.h"
46 #include "cetlib/cpu_timer.h"
140 : EDAnalyzer(parameterSet)
143 fGeometry = lar::providerFrom<geo::Geometry>();
158 art::ServiceHandle<art::TFileService>
tfs;
167 fNumIDEHist = tfs->make<TH1D>(
"NumIDEs",
";# ides", 20, 0., 20.);
168 fDeltaIDEHist = tfs->make<TH1D>(
"DeltaIDE",
";delta", 20, -10., 10.);
169 fNegEnergyHist = tfs->make<TH1D>(
"NegEnergy",
";energy", 500, 0., 10.);
170 fNegNElecHist = tfs->make<TH1D>(
"NegNumElec",
";# electrons", 200, 0., 100.);
171 fIDEMisMatchHist = tfs->make<TH1D>(
"IDEMisMatch",
";# mismatches", 20, 10., 10.);
172 fBTEfficiencyHist = tfs->make<TH1D>(
"BTEfficiency",
";efficiency", 102, 0., 1.02);
174 fEfficiencyCompHist = tfs->make<TH2D>(
"Efficiency",
";BackTrack;Associations", 52, 0., 1.04, 52, 0., 1.04);
175 fBTPurityHist = tfs->make<TH1D>(
"BTPurity",
";Purity", 102, 0., 1.02);
176 fAssocPurityHist = tfs->make<TH1D>(
"AssocPurity",
";Purity", 102, 0., 1.02);
177 fPurityCompHist = tfs->make<TH2D>(
"Purity",
";BackTrack;Associations", 52, 0., 1.04, 52, 0., 1.04);
193 fMCTruthMatching = art::make_tool<truth::IMCTruthMatching>(pset.get<fhicl::ParameterSet>(
"MCTruthMatching"));
202 art::ServiceHandle<cheat::BackTrackerService> backTracker;
203 art::ServiceHandle<cheat::ParticleInventoryService> partInventory;
210 const sim::ParticleList& btPartList = partInventory->ParticleList();
212 if (particleList.size() != btPartList.size())
214 mf::LogInfo(
"MCTruthTestAna") <<
"*** ParticleList size mismatch, BackTracker says: " << btPartList.size() <<
", alternate says: " << particleList.size() << std::endl;
219 art::Handle<std::vector<recob::Hit> > hitHandle;
222 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
223 if (hitHandle.isValid())
225 int nTotalMisMatches(0);
228 for(
const auto&
hit : *hitHandle)
230 int nIDEMisMatches(0);
234 std::vector<sim::TrackIDE> btTrkIDEVec = backTracker->HitToTrackIDEs(clockData,
hit);
236 int deltaIDs = int(btTrkIDEVec.size()) -
int(trackIDEVec.size());
245 int numNeg = std::count_if(btTrkIDEVec.begin(),btTrkIDEVec.end(),[](
const auto& trackIDE){
return trackIDE.trackID < 0;});
249 std::sort(btTrkIDEVec.begin(),btTrkIDEVec.end(),[](
const auto&
left,
const auto&
right){
return left.trackID >
right.trackID;});
251 while(btTrkIDEVec.back().trackID < 0)
253 fNegEnergyHist->Fill(std::min(9.98,
double(btTrkIDEVec.back().energy)), 1.);
254 fNegNElecHist->Fill(std::min(99.9,
double(btTrkIDEVec.back().numElectrons)), 1.);
256 btTrkIDEVec.pop_back();
262 for(
const auto& btTrkID : btTrkIDEVec)
264 std::vector<sim::TrackIDE>::const_iterator trackIDItr = std::find_if(trackIDEVec.begin(),trackIDEVec.end(),[btTrkID](
const auto& id){
return btTrkID.trackID ==
id.trackID && btTrkID.energy ==
id.energy && btTrkID.numElectrons ==
id.numElectrons;});
266 if (trackIDItr == trackIDEVec.end()) nIDEMisMatches++;
270 nTotalMisMatches += nIDEMisMatches;
273 mf::LogInfo(
"MCTruthTestAna") <<
"==> Found " << nTotalMisMatches <<
" between BackTracker and Associations, BT reported " << nNegTrackIDs <<
" negative track ids \n";
278 art::Handle<std::vector<recob::Track>> trackHandle;
281 if (trackHandle.isValid())
284 std::vector<art::Ptr<recob::Hit>> hitPtrVector;
286 art::fill_ptr_vector(hitPtrVector, hitHandle);
291 int nBadEffMatches(0);
292 int nBadPurMatches(0);
294 for(
size_t trackIdx = 0; trackIdx < trackHandle->size(); trackIdx++)
296 art::Ptr<recob::Track>
track(trackHandle,trackIdx);
298 std::vector<art::Ptr<recob::Hit>> trackHitVec = hitTrackAssns.at(track.key());
300 std::set<int> trackIDSet =
fMCTruthMatching->GetSetOfTrackIDs(clockData, trackHitVec);
301 std::set<int> btTrkIDSet = backTracker->GetSetOfTrackIds(clockData, trackHitVec);
304 if (btTrkIDSet.size() > trackIDSet.size())
308 for(std::set<int>::iterator btTrkIDSetItr = btTrkIDSet.begin(); btTrkIDSetItr != btTrkIDSet.end();)
310 if (!(*btTrkIDSetItr < 0))
break;
312 btTrkIDSetItr = btTrkIDSet.erase(btTrkIDSetItr);
316 if (btTrkIDSet.size() != trackIDSet.size())
317 mf::LogDebug(
"MCTruthTestAna") <<
"Mismatch in associated track ids, backtracker: " << btTrkIDSet.size() <<
", associations: " << trackIDSet.size() <<
", track id: " << track.key() <<
"\n";
320 std::vector<int> btTrkIDVec;
322 for(
auto& trackID : btTrkIDSet) btTrkIDVec.emplace_back(trackID);
325 std::vector<std::vector<art::Ptr<recob::Hit>>> trkHitVecVec;
327 for(
const auto& tkID : btTrkIDVec)
329 std::vector<art::Ptr<recob::Hit>> hitVec = backTracker->TrackIdToHits_Ps(clockData, tkID, hitPtrVector);
330 trkHitVecVec.push_back(hitVec);
333 std::vector<std::vector<art::Ptr<recob::Hit>>>::iterator bestTrkHitVecItr = std::max_element(trkHitVecVec.begin(),trkHitVecVec.end(),[](
const auto&
a,
const auto& b){
return a.size() < b.size();});
335 if (bestTrkHitVecItr == trkHitVecVec.end())
338 mf::LogDebug(
"MCTruthTestAna") <<
">>>>>>> ERROR! >>>>>>> ERROR! >>>>>> MUST PURIFY! >>>>>> ERROR!" <<
"\n";
342 int indexToBestMC =
std::distance(trkHitVecVec.begin(),bestTrkHitVecItr);
343 int bestMCTrackID = btTrkIDVec.at(indexToBestMC);
345 std::vector<art::Ptr<recob::Hit>>& bestMCTrackHitVec = *bestTrkHitVecItr;
347 std::set<int> mcTrackIdxSet = {bestMCTrackID};
349 double btTrkEffic = backTracker->HitCollectionEfficiency(clockData, mcTrackIdxSet, trackHitVec, bestMCTrackHitVec,
geo::k3D);
350 double trackEffic =
fMCTruthMatching->HitCollectionEfficiency(clockData, mcTrackIdxSet, trackHitVec, bestMCTrackHitVec,
geo::k3D);
352 if (btTrkEffic != trackEffic)
354 mf::LogDebug(
"MCTruthTestAna") <<
"Efficiency mismatch, track ID: " << bestMCTrackID <<
", track: " << track.key() <<
", # hits: " << trackHitVec.size() <<
", # MC hits: " << bestMCTrackHitVec.size() <<
", btTrkEff: " << btTrkEffic <<
", trackEff: " << trackEffic <<
"\n|";
362 double btTrkPurity = backTracker->HitCollectionPurity(clockData, mcTrackIdxSet, trackHitVec);
363 double trackPurity =
fMCTruthMatching->HitCollectionPurity(clockData, mcTrackIdxSet, trackHitVec);
365 if (btTrkPurity != trackPurity)
367 mf::LogDebug(
"MCTruthTestAna") <<
"Purity mismatch, track ID: " << bestMCTrackID <<
", track: " << track.key() <<
", # hits: " << trackHitVec.size() <<
", # MC hits: " << bestMCTrackHitVec.size() <<
", btTrkPurity: " << btTrkPurity <<
", trackPurity: " << trackPurity <<
"\n|";
373 fPurityCompHist->Fill(std::min(1.01,btTrkPurity),std::min(1.01,trackPurity), 1.);
376 mf::LogDebug(
"MCTruthTestAna") <<
"Event with " << trackHandle->size() <<
" reconstructed tracks, found " << nBadEffMatches <<
" efficiency mismatches, " << nBadPurMatches <<
" purity mismatchs \n";
TH2D * fEfficiencyCompHist
Utilities related to art service access.
TH1D * fAssocEfficiencyHist
Declaration of signal hit object.
const geo::GeometryCore * fGeometry
This provides an interface which defines truth matching functions made available to downstream analys...
void analyze(const art::Event &evt)
MCTruthTestAna(fhicl::ParameterSet const &pset)
process_name use argoneut_mc_hitfinder track
3-dimensional objects, potentially hits, clusters, prongs, etc.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
virtual ~MCTruthTestAna()
art::InputTag fTrackProducerLabel
Description of geometry of one entire detector.
void reconfigure(fhicl::ParameterSet const &pset)
Declaration of cluster object.
Definition of data types for geometry description.
Provides recob::Track data product.
void beginRun(const art::Run &run)
art::ServiceHandle< art::TFileService > tfs
art::InputTag fHitProducerLabel
art framework interface to geometry description
std::unique_ptr< truth::IMCTruthMatching > fMCTruthMatching