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
TH1D * fAssocEfficiencyHist
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.
art::InputTag fTrackProducerLabel
art::InputTag fHitProducerLabel
std::unique_ptr< truth::IMCTruthMatching > fMCTruthMatching