PionAbsCexSelection_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: PionAbsCexSelection
3 // Plugin Type: filter (art v3_02_06)
4 // File: PionAbsCexSelection_module.cc
5 //
6 // Generated at Tue Jul 9 08:37:33 2019 by Jacob Calcutt using cetskelgen
7 // from cetlib version v3_07_02.
8 ////////////////////////////////////////////////////////////////////////
9 
17 #include "fhiclcpp/ParameterSet.h"
19 
20 #include <memory>
21 
26 
31 #include "canvas/Persistency/Common/FindManyP.h"
34 
35 #include "TFile.h"
36 #include "TProfile.h"
37 
39 
40 
42 public:
43  explicit PionAbsCexSelection(fhicl::ParameterSet const& p);
44  // The compiler-generated destructor is fine for non-base
45  // classes without bare pointers or other resource use.
46 
47  // Plugins should not be copied or assigned.
52 
53  // Required functions.
54  bool filter(art::Event& e) override;
55 
56 private:
57 
63 
66 
67  std::pair< double, double > fTrackStartXCut;
68  std::pair< double, double > fTrackStartYCut;
69  std::pair< double, double > fTrackStartZCut;
70  double fTrackEndZCut;
71  double fTrackDirCut;
73  bool fUseMVA;
75  double fChi2PIDCut;
76 
79  TProfile * profile;
80 
81  bool InRange(double, double, double);
82 };
83 
84 
86  : EDFilter{p} ,
87 
88  beamlineUtil( p.get< fhicl::ParameterSet >("BeamlineUtils")),
89  fPFParticleTag( p.get< std::string >("PFParticleTag")),
90  fTrackerTag( p.get< std::string >("TrackerTag")),
91  fShowerTag( p.get< std::string >("ShowerTag")),
92  fCalorimetryTag( p.get< std::string >("CalorimetryTag")),
93  fCalorimetryParameters( p.get< fhicl::ParameterSet >("CalorimetryParameters")),
94  fGeneratorTag( p.get< std::string >("GeneratorTag") ),
95 
96  fTrackStartXCut( p.get< std::pair< double, double> >("TrackStartXCut") ),
97  fTrackStartYCut( p.get< std::pair< double, double> >("TrackStartYCut") ),
98  fTrackStartZCut( p.get< std::pair< double, double> >("TrackStartZCut") ),
99  fTrackEndZCut( p.get< double >("TrackEndZCut") ),
100  fTrackDirCut( p.get< double>("TrackDirCut") ),
101  fStrictNTracks( p.get< bool >("StrictNTracks") ),
102  fUseMVA( p.get< bool >("UseMVA") ),
103  fDaughterCNNCut( p.get< double >("DaughterCNNCut") ),
104  fChi2PIDCut( p.get< double >("Chi2PIDCut") ),
105 
106  dEdX_template_name(p.get<std::string>("dEdX_template_name")),
107  dEdX_template_file( dEdX_template_name.c_str(), "OPEN" )
108 
109 {
110  profile = (TProfile*)dEdX_template_file.Get( "dedx_range_pro" );
111 }
112 
114 {
118 
119  if( e.isRealData() ){
120  if( !fBeamlineUtils.IsGoodBeamlineTrigger( e ) ){
121  MF_LOG_INFO("AbsCexSelection") << "Failed Beamline Trigger Check" << "\n";
122  return false;
123  }
124  }
125 
126 
127  std::vector<const recob::PFParticle*> beamParticles = pfpUtil.GetPFParticlesFromBeamSlice(e,fPFParticleTag);
128  if(beamParticles.size() == 0){
129  MF_LOG_INFO("AbsCexSelection") << "We found no beam particles for this event... moving on" << "\n";
130  return false;
131  }
132 
133  // Get the reconstructed PFParticle tagged as beam by Pandora
134  const recob::PFParticle* particle = beamParticles.at(0);
135 
136  // Determine if the beam particle is track-like or shower-like
137  const recob::Track* thisTrack = pfpUtil.GetPFParticleTrack(*particle,e,fPFParticleTag,fTrackerTag);
138  const recob::Shower* thisShower = pfpUtil.GetPFParticleShower(*particle,e,fPFParticleTag,fShowerTag);
139 
140  if( !thisTrack && thisShower ){
141  MF_LOG_INFO("AbsCexSelection") << "Beam Particle Reconstructed as shower" << "\n";
142  return false;
143  }
144  else if( !thisShower && !thisTrack ){
145  MF_LOG_INFO("AbsCexSelection") << "Beam Particle Not Reconstructed" << "\n";
146  return false;
147  }
148  else{
149  MF_LOG_INFO("AbsCexSelection") << "Beam Particle Reconstructed as track" << "\n";
150  }
151  ////////////////////////////////////////////////////////////////////
152 
153 
154  //Get some objects to use for CNN output checking later
155  anab::MVAReader< recob::Hit, 4 > * hitResults = 0x0;
156  if( fUseMVA ) hitResults = new anab::MVAReader<recob::Hit,4>(e, "emtrkmichelid:emtrkmichel" );
157  auto recoTracks = e.getValidHandle<std::vector<recob::Track> >(fTrackerTag);
158  art::FindManyP<recob::Hit> findHits(recoTracks,e,fTrackerTag);
159  ////////////////////////////
160 
161 
162  //Here add in the cuts for the position of the beam and the incident angle
163  //First: need to switch reversed tracks
164  double endX = thisTrack->Trajectory().End().X();
165  double endY = thisTrack->Trajectory().End().Y();
166  double endZ = thisTrack->Trajectory().End().Z();
167  double startX = thisTrack->Trajectory().Start().X();
168  double startY = thisTrack->Trajectory().Start().Y();
169  double startZ = thisTrack->Trajectory().Start().Z();
170 
171  double dirX = 0., dirY = 0., dirZ = 1.;
172  if( startZ > endZ ){
173  double tempX = endX;
174  double tempY = endY;
175  double tempZ = endZ;
176 
177  endX = startX;
178  endY = startY;
179  endZ = startZ;
180 
181  startX = tempX;
182  startY = tempY;
183  startZ = tempZ;
184 
185  auto endDir = thisTrack->EndDirection();
186  dirX = -1. * endDir.X();
187  dirY = -1. * endDir.Y();
188  dirZ = -1. * endDir.Z();
189  }
190  else{
191  auto startDir = thisTrack->StartDirection();
192  dirX = startDir.X();
193  dirY = startDir.Y();
194  dirZ = startDir.Z();
195  }
196 
197  std::cout << startZ << " " << endZ << std::endl;
198  std::cout << startY << " " << endY << std::endl;
199  std::cout << startX << " " << endX << std::endl;
200  std::cout << dirX << " " << dirY << " " << dirZ << std::endl;
201 
202  if( e.isRealData() ){
203  auto beamEvent = fBeamlineUtils.GetBeamEvent(e);
204  std::cout << beamEvent.GetTOF() << std::endl;
205 
206  const std::vector< recob::Track > & beamEventTracks = beamEvent.GetBeamTracks();
207  if( beamEventTracks.size() < 1 ){
208  MF_LOG_INFO("AbsCexSelection") << "No tracks associated to beam event" << "\n";
209  return false;
210  }
211  else if( fStrictNTracks && (beamEventTracks.size() > 1) ){
212  MF_LOG_INFO("AbsCexSelection") << "Too many tracks associated to beam event" << "\n";
213  return false;
214  }
215 
216  auto beamEventTrack = beamEventTracks.at(0);
217  double deltaX = startX - beamEventTrack.End().X();
218  double deltaY = startY - beamEventTrack.End().Y();
219  double deltaZ = startZ - beamEventTrack.End().Z();
220 
221  if( !InRange(deltaZ, fTrackStartZCut.first, fTrackStartZCut.second) ||
222  !InRange(deltaY, fTrackStartYCut.first, fTrackStartYCut.second) ||
223  !InRange(deltaX, fTrackStartXCut.first, fTrackStartXCut.second) ){
224 
225  MF_LOG_INFO("AbsCexSelection") << "Beam track is outside of good start region" << "\n";
226  return false;
227  }
228 
229  double beamDirX = beamEventTrack.EndDirection().X();
230  double beamDirY = beamEventTrack.EndDirection().Y();
231  double beamDirZ = beamEventTrack.EndDirection().Z();
232 
233  double cos_theta = (beamDirX*dirX + beamDirY*dirY + beamDirZ*dirZ);
234  if( cos_theta < fTrackDirCut ){
235  MF_LOG_INFO("AbsCexSelection") << "Bad track angle" << "\n";
236  return false;
237  }
238  }
239  else{
240 
242 
243  auto mcTruths = e.getValidHandle<std::vector<simb::MCTruth>>(fGeneratorTag);
244  const simb::MCParticle* true_beam_particle = truthUtil.GetGeantGoodParticle((*mcTruths)[0],e);
245  if( !true_beam_particle ){
246  MF_LOG_INFO("AbsCexSelection") << "No true beam particle" << "\n";
247  return false;
248  }
249 
250  double deltaX = startX - true_beam_particle->Position(0).X();
251  double deltaY = startY - true_beam_particle->Position(0).Y();
252  double deltaZ = startZ - true_beam_particle->Position(0).Z();
253 
254  if( !InRange(deltaZ, fTrackStartZCut.first, fTrackStartZCut.second) ||
255  !InRange(deltaY, fTrackStartYCut.first, fTrackStartYCut.second) ||
256  !InRange(deltaX, fTrackStartXCut.first, fTrackStartXCut.second) ){
257 
258  MF_LOG_INFO("AbsCexSelection") << "Beam track is outside of good start region" << "\n";
259  return false;
260  }
261 
262  double beamDirX = true_beam_particle->Px() / true_beam_particle->P();
263  double beamDirY = true_beam_particle->Py() / true_beam_particle->P();
264  double beamDirZ = true_beam_particle->Pz() / true_beam_particle->P();
265 
266  double cos_theta = (beamDirX*dirX + beamDirY*dirY + beamDirZ*dirZ);
267  if( cos_theta < fTrackDirCut ){
268  MF_LOG_INFO("AbsCexSelection") << "Bad track angle" << "\n";
269  return false;
270  }
271 
272 
273  }
274 
275  //Cut for track length to cut out muons/keep the track within the APA3?
276  if( endZ > fTrackEndZCut ){
277  MF_LOG_INFO("AbsCexSelection") << "Failed End Z cut" << "\n";
278  return false;
279  }
280 
281  //Look at the daughters and check for track-like daughters that look like showers
282  //to try to pick out misreco'd pi0 gammas
283  const std::vector< const recob::Track* > trackDaughters = pfpUtil.GetPFParticleDaughterTracks( *particle, e, fPFParticleTag, fTrackerTag );
284 
285  for( size_t i = 0; i < trackDaughters.size(); ++i ){
286  auto daughterTrack = trackDaughters.at(i);
287 
288 
289  auto daughterHits = findHits.at( daughterTrack->ID() );
290 
291  if( fUseMVA ){
292  double track_total = 0.;
293  for( size_t h = 0; h < daughterHits.size(); ++h ){
294  std::array<float,4> cnn_out = hitResults->getOutput( daughterHits[h] );
295  track_total += cnn_out[ hitResults->getIndex("track") ];
296  }
297 
298  if( track_total < fDaughterCNNCut ){
299  MF_LOG_INFO("AbsCexSelection") << "Found daughter track that looks like shower" << "\n";
300  continue;
301  }
302  }
303 
304  //Now: If it's not a potential gamma, pass the calorimetry through the
305  // Chi2 PID and see if any MIP-like daughters are associated
306 
307  auto daughter_calo = trackUtil.GetRecoTrackCalorimetry( *daughterTrack, e, fTrackerTag, fCalorimetryTag );
308  std::vector<float> calo_range = daughter_calo[0].ResidualRange();
309  std::vector<float> calo_dEdX;
310  if( e.isRealData() ) calo_dEdX = trackUtil.CalibrateCalorimetry( *daughterTrack, e, fTrackerTag, fCalorimetryTag, fCalorimetryParameters );
311  else calo_dEdX = daughter_calo[0].dEdx();
312 
313  std::vector<double> daughter_range, daughter_dEdX;
314  for( size_t j = 0; j < calo_range.size(); ++j ){
315  daughter_range.push_back( calo_range[i] );
316  daughter_dEdX.push_back( calo_dEdX[i] );
317  }
318 
319  std::pair< double,int > chi2_pid_results = trackUtil.Chi2PID( daughter_dEdX, daughter_range, profile );
320 
321  if( chi2_pid_results.first > fChi2PIDCut ){
322  MF_LOG_INFO("AbsCexSelection") << "Found daughter with MIP-like Chi2 PID" << "\n";
323  return false;
324  }
325  }
326 
327 
328 
329  return true;
330 }
331 
332 bool PionAbsCexSelection::InRange(double input, double low, double high){
333  return ( (input >= low) && (input <= high) );
334 }
335 
std::pair< double, double > fTrackStartYCut
const simb::MCParticle * GetGeantGoodParticle(const simb::MCTruth &genTruth, const art::Event &evt) const
PionAbsCexSelection & operator=(PionAbsCexSelection const &)=delete
const recob::Shower * GetPFParticleShower(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string showerLabel) const
Get the shower associated to this particle. Returns a null pointer if not found.
bool InRange(double, double, double)
std::string string
Definition: nybbler.cc:12
const recob::TrackTrajectory & Trajectory() const
Access to the stored recob::TrackTrajectory.
Definition: Track.h:98
std::vector< anab::Calorimetry > GetRecoTrackCalorimetry(const recob::Track &track, art::Event const &evt, const std::string trackModule, const std::string caloModule) const
Get the Calorimetry(s) from a given reco track.
int getIndex(const std::string &name) const
Index of column with given name, or -1 if name not found.
Definition: MVAReader.h:82
Particle class.
PionAbsCexSelection(fhicl::ParameterSet const &p)
bool isRealData() const
Vector_t StartDirection() const
Access to track direction at different points.
Definition: Track.h:131
const double e
std::pair< double, double > fTrackStartXCut
static int input(void)
Definition: code.cpp:15695
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
const double & GetTOF() const
const recob::Track * GetPFParticleTrack(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Get the track associated to this particle. Returns a null pointer if not found.
std::pair< double, double > fTrackStartZCut
p
Definition: test.py:223
const std::vector< const recob::PFParticle * > GetPFParticlesFromBeamSlice(art::Event const &evt, const std::string particleLabel) const
Return the pointers for the PFParticles in the beam slice. Returns an empty vector is no beam slice w...
bool IsGoodBeamlineTrigger(art::Event const &evt) const
#define MF_LOG_INFO(category)
bool filter(art::Event &e) override
std::pair< double, int > Chi2PID(const std::vector< double > &track_dedx, const std::vector< double > &range, TProfile *profile)
Hierarchical representation of particle flow.
Definition: PFParticle.h:44
Vector_t EndDirection() const
Definition: Track.h:133
Point_t const & End() const
Returns the position of the last valid point of the trajectory [cm].
Provides recob::Track data product.
EDFilter(fhicl::ParameterSet const &pset)
Definition: EDFilter.h:21
fhicl::ParameterSet beamlineUtil
Point_t const & Start() const
Returns the position of the first valid point of the trajectory [cm].
std::array< float, N > getOutput(size_t key) const
Get copy of the MVA output vector at index "key".
Definition: MVAReader.h:129
fhicl::ParameterSet fCalorimetryParameters
const std::vector< const recob::Track * > GetPFParticleDaughterTracks(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Get the daughter tracks from the PFParticle.
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:49
const beam::ProtoDUNEBeamEvent GetBeamEvent(art::Event const &evt) const
QTextStream & endl(QTextStream &s)
std::vector< float > CalibrateCalorimetry(const recob::Track &track, art::Event const &evt, const std::string trackModule, const std::string caloModule, const fhicl::ParameterSet &ps)
Calibrate a Calorimetry object for a given plane from a given track.