All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TruthMatch.cc
Go to the documentation of this file.
1 #include "TruthMatch.h"
2 #include "nusimdata/SimulationBase/MCTruth.h"
3 #include <cassert>
4 
6  if (truth.neutrino.iscc) return numu::mCC;
7  else return numu::mNC;
8 }
9 
10 numu::TruthMatch numu::InteractionTruthMatch(const std::vector<event::Interaction> &truth, const std::map<size_t, numu::RecoTrack> &reco_tracks, const numu::RecoInteraction &reco) {
11  TruthMatch match;
12  // Try to match against truth events
13  // Vertices
14  match.truth_vertex_distance = -1;
15  for (int truth_i = 0; truth_i < truth.size(); truth_i++) {
16  // find the closest vertex
17  if (match.truth_vertex_distance < 0 || (truth[truth_i].neutrino.position - reco.position).Mag() < match.truth_vertex_distance) {
18  match.truth_vertex_distance = (truth[truth_i].neutrino.position - reco.position).Mag();
19  match.mctruth_vertex_id = truth_i;
20  }
21  }
22 
23  // TODO: better way to do matching
24  // only keep match if distance is less than 5cm
25  if (match.truth_vertex_distance < 0. || match.truth_vertex_distance > 5.) {
26  std::cout << "Vertex not matched well.\n";
27  }
28  else {
29  std::cout << "Vertex matched to neutrino.\n";
30  }
31 
32  // Match to the primary track of the event
33  match.mctruth_track_id = -1;
34  if (reco.slice.primary_track_index >= 0) {
35  const numu::TrackTruthMatch &ptrack_match = reco_tracks.at(reco.slice.primary_track_index).match;
36  if (ptrack_match.has_match) {
37  for (int truth_i = 0; truth_i < truth.size(); truth_i++) {
38  if ((truth[truth_i].neutrino.position - ptrack_match.mctruth_vertex).Mag() < 1.) {
39  match.mctruth_track_id = truth_i;
40  }
41  }
42  }
43  std::cout << "Primary track index: " << reco.slice.primary_track_index << std::endl;
44 
45  // return the interaction mode
46  if (ptrack_match.has_match && ptrack_match.mctruth_origin == simb::Origin_t::kCosmicRay) {
47  match.tmode = numu::tmCosmic;
48  std::cout << "Track matched to cosmic.\n";
49  }
50  else if (ptrack_match.has_match && ptrack_match.mctruth_origin == simb::Origin_t::kBeamNeutrino) {
51  match.tmode = numu::tmNeutrino;
52  std::cout << "Track matched to neutrino.\n";
53  }
54  else if (ptrack_match.has_match) {
55  match.tmode = numu::tmOther;
56  std::cout << "Track matched to other: " << ptrack_match.mctruth_origin << std::endl;
57  std::cout << "Match PDG: " << ptrack_match.match_pdg << std::endl;
58  std::cout << "Match completion: " << ptrack_match.completion << std::endl;
59  std::cout << "Is primary: " << ptrack_match.is_primary << std::endl;
60  const numu::RecoTrack &track = reco_tracks.at(reco.slice.primary_track_index);
61  std::cout << "reco start: " << track.start.X() << " " << track.start.Y() << " " << track.start.Z() << std::endl;
62  std::cout << "reco end: " << track.end.X() << " " << track.end.Y() << " " << track.end.Z() << std::endl;
63  }
64  else {
65  match.tmode = numu::tmOther;
66  std::cout << "Track not matched.\n";
67  }
68  }
69  else {
70  match.tmode = numu::tmOther;
71  std::cout << "No track to match.\n";
72  }
73 
74  // Use the track to match the mode of the interaction
75  if (reco.slice.primary_track_index >= 0 &&
76  reco_tracks.at(reco.slice.primary_track_index).match.has_match) {
77  const numu::TrackTruthMatch &ptrack_match = reco_tracks.at(reco.slice.primary_track_index).match;
78  if (ptrack_match.mctruth_origin == simb::Origin_t::kBeamNeutrino && ptrack_match.mctruth_ccnc == simb::kCC) {
79  if (ptrack_match.is_primary) {
80  match.mode = numu::mCC;
81  }
82  else {
83  match.mode = numu::mCCNonPrimary;
84  }
85  }
86  else if (ptrack_match.mctruth_origin == simb::Origin_t::kBeamNeutrino && ptrack_match.mctruth_ccnc == simb::kNC) {
87  if (ptrack_match.is_primary) {
88  match.mode = numu::mNC;
89  }
90  else {
91  match.mode = numu::mNCNonPrimary;
92  }
93  }
94  else if (ptrack_match.mctruth_origin == simb::Origin_t::kCosmicRay) {
95  match.mode = numu::mCosmic;
96  }
97  else {
98  match.mode = numu::mOther;
99  }
100  }
101  // **shrug**
102  else {
103  match.mode = numu::mOther;
104  }
105  match.has_match = true;
106 
107  return match;
108 }
109 
110 void numu::CorrectMultiMatches(numu::RecoEvent &event, std::vector<numu::RecoInteraction> &recos) {
111  // check for no two reco matched to same truth
112  std::map<int, unsigned> matched_vertices;
113  for (unsigned reco_i = 0; reco_i < recos.size(); reco_i++) {
114  numu::RecoInteraction &reco = recos[reco_i];
115  unsigned set_i = reco_i;
116 
117  numu::RecoTrack &primary_track = event.tracks.at(reco.slice.primary_track_index);
118 
119  if (primary_track.match.has_match && primary_track.match.is_primary && reco.match.mctruth_track_id >= 0) {
120  if (matched_vertices.count(reco.match.mctruth_track_id)) {
121  std::cout << "BAAAAAAAAD: two reco matched to same truth." << std::endl;
122  std::cout << "This id: " << reco.match.mctruth_track_id << std::endl;
123  for (const numu::RecoInteraction &reco: recos) {
124  std::cout << "Interaction x: " << reco.position.X() << " match: " << reco.match.mctruth_track_id << " primary track pdg: " << primary_track.match.match_pdg << std::endl;
125  }
126 
127  numu::RecoInteraction &other = recos[matched_vertices[reco.match.mctruth_track_id]];
128  numu::RecoTrack &other_primary_track = event.tracks.at(other.slice.primary_track_index);
129 
130  float dist_reco = std::min( (primary_track.start - event.particles.at(primary_track.match.mcparticle_id).start).Mag(),
131  (primary_track.end - event.particles.at(primary_track.match.mcparticle_id).start).Mag());
132 
133  float dist_other = std::min( (other_primary_track.start - event.particles.at(other_primary_track.match.mcparticle_id).start).Mag(),
134  (other_primary_track.end - event.particles.at(other_primary_track.match.mcparticle_id).start).Mag());
135 
136  // Handle if one of the matched particles in not a muon
137  if (abs(primary_track.match.match_pdg) != 13 && abs(other_primary_track.match.match_pdg) == 13) {
138  set_i = matched_vertices[reco.match.mctruth_track_id];
139  primary_track.match.is_primary = false;
140  std::cout << "Corrected -- matched track is non-muon\n";
141  }
142  else if (abs(primary_track.match.match_pdg) == 13 && abs(other_primary_track.match.match_pdg) != 13) {
143  other_primary_track.match.is_primary = false;
144  std::cout << "Corrected -- matched track is non-muon\n";
145  }
146  // Handle both two different particles neither of which are muons
147  else if (primary_track.match.mcparticle_id != other_primary_track.match.mcparticle_id) {
148  std::cout << "Reco track 1 length: " << primary_track.length << " pdg: " << primary_track.match.match_pdg << std::endl;
149  std::cout << "Reco track 2 length: " << other_primary_track.length << " pdg: " << other_primary_track.match.match_pdg << std::endl;
150  if (primary_track.length > other_primary_track.length) {
151  other_primary_track.match.is_primary = false;
152  std::cout << "Corrected -- used longer track. Track 1 is primary.\n";
153  }
154  else {
155  primary_track.match.is_primary = false;
156  std::cout << "Corrected -- used longer track. Track 2 is primary.\n";
157  }
158  }
159  // Handle if the priamry track was split in two
160  else if (primary_track.match.mcparticle_id == other_primary_track.match.mcparticle_id) {
161  std::cout << "Reco track 1 pos: " << primary_track.start.X() << " " << primary_track.start.Y() << " " << primary_track.start.Z() << " to: " << primary_track.end.X() << " " << primary_track.end.Y() << " " << primary_track.end.Z() << std::endl;
162  std::cout << "Reco track 2 pos: " << other_primary_track.start.X() << " " << other_primary_track.start.Y() << " " << other_primary_track.start.Z() << " to: " << other_primary_track.end.X() << " " << other_primary_track.end.Y() << " " << other_primary_track.end.Z() << std::endl;
163  TVector3 match_start = event.particles.at(other_primary_track.match.mcparticle_id).start;
164  std::cout << "Match start pos: " << match_start.X() << " " << match_start.Y() << " " << match_start.Z() << std::endl;
165  if (dist_reco <= dist_other) {
166  std::cout << "Corrected -- split muon. Track 1 is primary.\n";
167  other_primary_track.match.is_primary = false;
168  }
169  else {
170  std::cout << "Corrected -- split muon. Track 2 is primary.\n";
171  set_i = matched_vertices[reco.match.mctruth_track_id];
172  primary_track.match.is_primary = false;
173  }
174  }
175  else {
176  std::cout << "Unable to correct!\n";
177  std::cerr << "Exiting on failure.\n";
178  assert(false);
179  }
180  }
181  matched_vertices[reco.match.mctruth_track_id] = set_i;
182  }
183  }
184 }
185 
InteractionMode mode
Mode of the interaction.
InteractionMode GetMode(const event::Interaction &truth)
Definition: TruthMatch.cc:5
int mctruth_ccnc
CC (1) / NC (0) value of the MCTruth this object matches to.
Definition: Mode.h:11
int mctruth_origin
Value of Origin_t enum of the MCTruth object this track matches to.
BEGIN_PROLOG could also be cerr
TruthMatch match
Info for mathing to truth.
Definition: RecoEvent.h:42
int mcparticle_id
MCParticle ID of the particle this track matches to (same as the ID of the RecoTrack of that particle...
int primary_track_index
Index of the primary track.
Definition: RecoEvent.h:27
Neutrino neutrino
The neutrino.
Definition: Event.hh:152
InteractionMode
Definition: Mode.h:8
process_name use argoneut_mc_hitfinder track
std::map< size_t, TrueParticle > particles
Map of indices to True particle information.
Definition: RecoEvent.h:49
bool iscc
CC (true) or NC/interference (false)
Definition: Event.hh:75
void CorrectMultiMatches(RecoEvent &event, std::vector< RecoInteraction > &recos)
Definition: TruthMatch.cc:110
T abs(T value)
Charged-current interactions.
Definition: IPrediction.h:38
TVector3 position
location of the vertex
Definition: RecoEvent.h:40
Definition: Mode.h:9
process_name standard_reco_uboone reco
TVector3 start
start position of track
Definition: RecoTrack.h:54
TVector3 mctruth_vertex
The interaction vertex of the MCTruth object this track matches to.
float length
Length of track.
Definition: RecoTrack.h:48
float completion
Fraction of energy deposits by true particle matched by this track.
const Cut kCosmicRay
TruthMatch InteractionTruthMatch(const std::vector< event::Interaction > &truth, const std::map< size_t, numu::RecoTrack > &reco_tracks, const numu::RecoInteraction &reco)
Definition: TruthMatch.cc:10
bool has_match
Whether a track match exists.
bool is_primary
Whether this track was produced as the &quot;primary&quot; process.
TrackTruthMatch match
Truth matching information.
Definition: RecoTrack.h:57
RecoSlice slice
Particle content of the interaction.
Definition: RecoEvent.h:39
int mctruth_vertex_id
index of the truth vertex into the list of MCThruths. -1 if no match
float truth_vertex_distance
Distance from truth interaction vertex to this vertex.
Neutral-current interactions.
Definition: IPrediction.h:39
TVector3 end
end position of track
Definition: RecoTrack.h:55
int mctruth_track_id
index of the primary track into the list of MCTruths. -1 if no match.
TrackMode tmode
Mode of the primary track in this interaction.
bool has_match
Whether a truth match exists.
int match_pdg
PDG of the MCParticle this track matches to.
All truth information associated with one neutrino interaction.
Definition: Event.hh:150
BEGIN_PROLOG could also be cout