LArG4ExtCounterFilter_module.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <utility>
3 #include <set>
4 
5 
13 #include "lardataobj/RawData/raw.h"
15 
16 namespace filt{
17 
19  public:
20  explicit LArG4ExtCounterFilter(fhicl::ParameterSet const & pset);
21  virtual ~LArG4ExtCounterFilter() {};
22  virtual bool filter(art::Event& e);
23  void reconfigure(fhicl::ParameterSet const& pset);
24  void beginJob() ;
25 
26  private:
27 
28  //Small class to hold the opposing set of counters
30  std::vector<unsigned int> setA; //First set
31  std::vector<unsigned int> setB; //Second set
32  bool IsRequested; //Check if we care about a particular pairwise set of counters (e.g. does the user care about the EW counters etc)
33  };
34  std::vector<CounterSetPair> fCounterSetPairs;
35 
36  //Adjustable parameters
37  bool fUseEWCounterPair; //Use the EW counter pair
38  bool fUseNupSdownCounterPair; //Use North (up) South (down) counter pair
39  bool fUseNdownSupCounterPair; //Use the North (down) South (up) counter pair
40  std::vector<int> fInterestingPDGs; //A vector of particle PDGs which want to be filtered on
41  double fParticleMinEnergy; //The minimum energy of a particle to be filtered
42  double fParticleMaxEnergy; //The maximum energy of a particle to be filtered
43 
44  bool IsInterestingParticle(const art::Ptr<simb::MCParticle> particle); //Define whether a particular particle is initially worth saving e.g. is it a muon, pion etc
45  bool UsesCounterSetPair(const CounterSetPair &CSP, const std::set<unsigned int> &usedCounterIDs); //Check if a list of counter IDs matches with those in a particular set pair
46  bool UsesCounterSet(const std::vector<unsigned int> &counterIDs, const std::set<unsigned int> &usedCounterIDs); //Check if any of a list of counters are counter in a particular counter set
47 
48  };
49 
50  LArG4ExtCounterFilter::LArG4ExtCounterFilter::LArG4ExtCounterFilter(fhicl::ParameterSet const & pset) : EDFilter{pset}
51  {
52  this->reconfigure(pset);
53  }
54 
56  fUseEWCounterPair = pset.get<bool>("UseEWCounterPair",1);
57  std::cout<<"Use EW counter pair: " << fUseEWCounterPair<<std::endl;
58  fUseNupSdownCounterPair = pset.get<bool>("UseNupSdownCounterPair",1);
59  std::cout<<"Use N (up) S (down) counter pair: " << fUseNupSdownCounterPair << std::endl;
60  fUseNdownSupCounterPair = pset.get<bool>("UseNdownSupCounterPair",1);
61  std::cout<<"Use N (down) S (up) counter pair: " << fUseNdownSupCounterPair << std::endl;
62  fInterestingPDGs = pset.get<std::vector<int> >("InterestingPDGs");
63  std::cout<<"NInteresting PDGs: " << fInterestingPDGs.size() << std::endl;
64  for (unsigned int i = 0; i < fInterestingPDGs.size(); i++){
65  std::cout<<"-- PDG: " << fInterestingPDGs[i] << std::endl;
66  }
67  fParticleMinEnergy = pset.get<double>("ParticleMinEnergy",0);
68  std::cout<<"Particle min energy: " << fParticleMinEnergy << std::endl;
69  fParticleMaxEnergy = pset.get<double>("ParticleMaxEnergy",999999999);
70  std::cout<<"Particle max energy: " << fParticleMaxEnergy << std::endl;
71  }
72 
74 
76 
77 
78  //Get the vector of particles
79  auto particles = e.getHandle<std::vector<simb::MCParticle> >("largeant");
80  //Loop through the particles
81  for (unsigned int part_i = 0; part_i < particles->size(); part_i++){
82  //Get the particle
83  const art::Ptr<simb::MCParticle> particle(particles,part_i);
84  //Check if the particle is initially worth considering
85  if (IsInterestingParticle(particle)){
86  //OK so the particle matches the criteria we need. Now we need to get the IDs of all external counters it passes through
87  //To do this, get the trajectory points and find which counter (if any) said points are contained in
88  //Use a set to store the counter IDs the particle passes through
89  std::set<unsigned int> usedExtCounterIDs;
90  //Now get the trajcectory points
91  unsigned int npts = particle->NumberTrajectoryPoints();
92  //Loop over those points
93  for (unsigned int pt = 0; pt < npts; pt++){
94  //Get the position at the point
95  TLorentzVector pos4 = particle->Position(pt);
96  //The function which checks whether a position is contained in a counter requires a double[3]. So convert the position to that format
97  double pos[3];
98  pos[0] = pos4.X();
99  pos[1] = pos4.Y();
100  pos[2] = pos4.Z();
101  //If the position is not contained in a counter, the function throws an exception. We don't want to end the process when this happens
102  try{
103  //std::cout<<"AuxDetID: " << geom->FindAuxDetAtPosition(pos) << " pdg: " << particle->PdgCode() << std::endl;
104  unsigned int counterID = geom->FindAuxDetAtPosition(pos);
105  usedExtCounterIDs.insert(counterID);
106  }
107  catch(...){};
108  }
109  std::cout<<"NCounters (any) passed through: " << usedExtCounterIDs.size() << std::endl;
110  //We now have a list (set) of the counter IDs which the particles passed through. Now compare this list with the information stored in the CounterSetPairs
111  for (unsigned int csp_i = 0; csp_i < fCounterSetPairs.size(); csp_i++){
112  //Only bother comparing the information if a particlar counter set pair has been requested
113  if (!fCounterSetPairs[csp_i].IsRequested) continue;
114  if (UsesCounterSetPair(fCounterSetPairs[csp_i],usedExtCounterIDs)){
115  std::cout<<"SELECTED EVENT"<<std::endl;
116  return true;
117  }
118  }
119  }
120  }
121 
122  //Assume that the event is not worth saving
123  return false;
124  }
125 
127 
128  //Need to get the counter information. By doing this at the start of the job, rather than per event, the code assumes the geomtry is not going to change between events
130  //Create the pairwise counter sets
131  CounterSetPair EWCounterSetPair;
132  CounterSetPair NupSdownCounterSetPair;
133  CounterSetPair NdownSupCounterSetPair;
134  //A stupid way of storing the IDs of the counters, this REALLY needs changing
135  //The code loops through all of the counters in the geomtry, and if the number matches a particular counter number e.g. one of the east counters, store it in the correct, pairwise set
136  for (unsigned int i = 0; i < geom->NAuxDets(); i++){
137  //The WE counter pairs
138  if (i >=6 && i <= 15) EWCounterSetPair.setA.push_back(i);
139  else if (i >= 28 && i <=37) EWCounterSetPair.setB.push_back(i);
140  //The N (up) S (down) counter pairs
141  else if (i >= 22 && i <= 27) NupSdownCounterSetPair.setA.push_back(i);
142  else if (i <= 5) NupSdownCounterSetPair.setB.push_back(i);
143  //The N (down) S (up) counter pairs
144  else if (i >= 16 && i <= 21) NdownSupCounterSetPair.setA.push_back(i);
145  else if (i >= 38 && i <= 43) NdownSupCounterSetPair.setB.push_back(i);
146  }
147 
148  //Enable/disable the counter set pairs
149  EWCounterSetPair.IsRequested = fUseEWCounterPair;
150  NupSdownCounterSetPair.IsRequested = fUseNupSdownCounterPair;
151  NdownSupCounterSetPair.IsRequested = fUseNdownSupCounterPair;
152 
153  //Store them onto the vector of counter set pairs
154  fCounterSetPairs.push_back(EWCounterSetPair);
155  fCounterSetPairs.push_back(NupSdownCounterSetPair);
156  fCounterSetPairs.push_back(NdownSupCounterSetPair);
157 
158 
159  for (unsigned int i = 0; i < fCounterSetPairs.size(); i++){
160  std::cout<<"Counter set pair: "<<i<<std::endl;
161  std::cout<<"--setA size: " << fCounterSetPairs[i].setA.size() << std::endl;
162  std::cout<<"--setB size: " << fCounterSetPairs[i].setB.size() << std::endl;
163 
164  }
165  }
166 
168  //Loop over the list of requested PDGs. See if that matches the particle under consideration
169  for (unsigned int i = 0; i < fInterestingPDGs.size(); i++){
170  //Check if the particle under consideration has a requested PDG
171  if (particle->PdgCode() == fInterestingPDGs[i]){
172  //Got a requested PDG, now check that the energy matches the requested range
173  TLorentzVector mom4 = particle->Momentum();
174  if (mom4.T() > fParticleMinEnergy && mom4.T() < fParticleMaxEnergy){
175  //std::cout<<"FOUND INTERESTING PARTICLE"<<std::endl;
176  return true;
177  }
178  }
179  }
180  return false;
181  }
182 
183  bool LArG4ExtCounterFilter::UsesCounterSetPair(const CounterSetPair &CSP, const std::set<unsigned int> &usedCounterIDs){
184 
185  bool usesSetA = UsesCounterSet(CSP.setA,usedCounterIDs);
186  bool usesSetB = UsesCounterSet(CSP.setB,usedCounterIDs);
187  if (usesSetA && usesSetB){
188  std::cout<<"USES BOTH SETS OF COUNTERS"<<std::endl;
189  return true;
190  }
191 
192  return false;
193  }
194 
195  bool LArG4ExtCounterFilter::UsesCounterSet(const std::vector<unsigned int> &counterIDs, const std::set<unsigned int> &userCounterIDs){
196  //Iterate over the used counter IDs and compare them with every counter ID in the vector. If a match is found, this means the particle of interest passed through one of the counters in the vector
197  for (std::set<unsigned int>::iterator setIt = userCounterIDs.begin(); setIt != userCounterIDs.end(); setIt++){
198  unsigned int usedCounterID = (*setIt);
199  //Now loop through the IDs in the vector
200  for (unsigned int i = 0; i < counterIDs.size(); i++){
201  //Compare the elements. If there is a match, return true
202  if (usedCounterID == counterIDs[i]){
203  std::cout<<"Counter ID match"<<std::endl;
204  return true;
205  }
206  }
207  }
208 
209  //None of the used counters matched the counters in the set
210  return false;
211  }
212 
214 }
intermediate_table::iterator iterator
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:218
const TLorentzVector & Position(const int i=0) const
Definition: MCParticle.h:219
int PdgCode() const
Definition: MCParticle.h:212
unsigned int FindAuxDetAtPosition(double const worldLoc[3], double tolerance=0) const
Returns the index of the auxiliary detector at specified location.
bool IsInterestingParticle(const art::Ptr< simb::MCParticle > particle)
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
LArG4ExtCounterFilter(fhicl::ParameterSet const &pset)
art framework interface to geometry description
void reconfigure(fhicl::ParameterSet const &pset)
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
T get(std::string const &key) const
Definition: ParameterSet.h:271
std::vector< CounterSetPair > fCounterSetPairs
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:220
EDFilter(fhicl::ParameterSet const &pset)
Definition: EDFilter.h:21
Declaration of basic channel signal object.
bool UsesCounterSetPair(const CounterSetPair &CSP, const std::set< unsigned int > &usedCounterIDs)
bool UsesCounterSet(const std::vector< unsigned int > &counterIDs, const std::set< unsigned int > &usedCounterIDs)
virtual bool filter(art::Event &e)
QTextStream & endl(QTextStream &s)
unsigned int NAuxDets() const
Returns the number of auxiliary detectors.