TruthMatching and associations

In MCC8.x (where x>2) a module is run after reconstruction which matches reconstructed objects to truth. Originally (in MCC8.3) this was a direct association between tracks and/or showers, and MCParticles. From MCC8.4 this was updated to save the associations between simb::MCParticles and recob::Hits. The original track<->particle associations were removed as they can be reconstructed using the hit matching.

Currently, one can find an example of how to put this into practice to get reconstructed tracks that match your MCParticles in a gallery macro here: /uboone/app/users/wketchum/dev_areas/mcc8_4_drop/gallery_macros/TruthMatchTracks.C

These associations contain "metadata", which can be obtained along with the association to provide more information about the association. In this case the metadata is a simple struct anab::BackTrackerHitMatchingData which can be found in the lardataobj repository. This auxiliary data will provide, if you're interested, information about how good the match is - i.e. what fraction of the hits charge came from the MCParticle it's matched to, and what fraction came from somewhere else.

To see (a little bit) more information, check out this google doc

Example use for the MCC8.3 matching

This is an example of how to retrieve truth-matching associations in a LArSoft module for the "old" (MCC8.3) way. Most things translate across to hit<->particle matching, but then there is an additional step of getting the hit<->track associations and building your own map of track<->particle matches

In MCC8.3, the following associations were saved:

  • recob::Track <==> simb::MCParticle
  • recob::Shower <==> simb::MCParticle
  • recob::PFParticle <==> simb::MCParticle

These associations contain an auxiliary data object, anab::BackTrackerMatchingData. This is a simple struct with 2 members, completeness and cleanliness. Currently completeness is unfilled (i.e. it contains junk), but cleanliness tells you the fraction of charge in the reco object which comes from the matched MCParticle.

To use these associations, one must follow the following prescription:

First, get the reco objects you want the matches to, as a handle. In this case we get recob::Track's, which were produced by pandoraNu.

auto trackHandle = e.getValidHandle< std::vector< recob::Track > >("pandoraNu");

Then, build a FindManyP object which finds all of the associated MCParticles and auxiliary data. You must use the corresponding truth matching producer here. The convention for these is to use recoProducer_TruthMatch, where "recoProducer" should be replaced with the specific producer you're using (i.e. pandoraNu):

art::FindManyP<simb::MCParticle, anab::BackTrackerMatchingData > FindMatchMCPart(trackHandle, e, "pandoraNuTruthMatch");

Then, we will loop through the tracks vector, and get the track, the MCParticle and the aux data. The MCParticle and auxiliary data are stored in vectors (in principle we would be allowed to match to many MCParticles), but the size will either be 0 (if there was no match) or 1 (if there was a match).

for (unsigned int iTrk(0); iTrk < trackHandle.product()->size() ; iTrk++){
  auto track = trackHandle.product()->at(iTrk);
  std::vector<art::Ptr<simb::MCParticle>> const& mcpart =; // take element 0 of this vector, after checking it has length > 0, to get the matched MCParticle
  auto mcpart_data =; // take element 0 of this vector, after checking it has length > 0, to get the auxiliary data object