All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GenCRTFilter_module.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <algorithm>
3 
4 #include "TGeoManager.h"
5 
6 #include "art/Framework/Core/EDFilter.h"
7 #include "art/Framework/Core/ModuleMacros.h"
8 #include "art/Framework/Principal/Event.h"
9 #include "art/Framework/Services/Registry/ServiceDefinitionMacros.h"
11 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
15 #include "nusimdata/SimulationBase/MCTruth.h"
16 
17 namespace filt{
18 
19  class GenFilter : public art::EDFilter {
20  public:
21  explicit GenFilter(fhicl::ParameterSet const & pset);
22  virtual bool filter(art::Event& e) override;
23  void reconfigure(fhicl::ParameterSet const& pset);
24  virtual void beginJob() override;
25 
26  private:
27 
28  std::vector<unsigned int> fTopHighCRTAuxDetIDs;
29  std::vector<unsigned int> fTopLowCRTAuxDetIDs;
30  std::vector<unsigned int> fBottomCRTAuxDetIDs;
31  std::vector<unsigned int> fFrontCRTAuxDetIDs;
32  std::vector<unsigned int> fBackCRTAuxDetIDs;
33  std::vector<unsigned int> fLeftCRTAuxDetIDs;
34  std::vector<unsigned int> fRightCRTAuxDetIDs;
35 
40  bool fUseBackCRTs;
41  bool fUseLeftCRTs;
43  std::vector<int> fPDGs;
44  std::vector<double> fMinMomentums;
45  std::vector<double> fMaxMomentums;
49 
51  double readoutWindow;
52  double driftTime;
53 
54  bool IsInterestingParticle(const simb::MCParticle &particle);
55  void LoadCRTAuxDetIDs();
56  bool UsesCRTAuxDets(const simb::MCParticle &particle, const std::vector<unsigned int> &crt_auxdet_vector);
57  bool UsesCRTAuxDet(const simb::MCParticle &particle, geo::AuxDetGeo const& crt);
58  bool RayIntersectsBox(TVector3 ray_origin, TVector3 ray_direction, TVector3 box_min_extent, TVector3 box_max_extent);
59  std::pair<double, double> XLimitsTPC(const simb::MCParticle &particle);
60  std::pair<TVector3, TVector3> CubeIntersection(TVector3 min, TVector3 max, TVector3 start, TVector3 end);
61  };
62 
63 
64  GenFilter::GenFilter(fhicl::ParameterSet const & pset)
65  : EDFilter(pset)
66  {
67  this->reconfigure(pset);
68 
69  fGeometryService = lar::providerFrom<geo::Geometry>();
70  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
71  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clockData);
72  double rw_ticks = detProp.ReadOutWindowSize();
73  double inv_samp_freq = clockData.TPCClock().Frequency();
74  readoutWindow = rw_ticks/inv_samp_freq;
75  // the function TPCTick2Time does not do what you think it does!
76  // It converts ticks to absolute time where 0 is the trigger time and not the start of the readout
77  // window, so if there is a front porch, this value is larger than the actually readout window
78  // readoutWindow = clockData.TPCTick2Time(static_cast<double>(detProp.ReadOutWindowSize())); // [us]
79  driftTime = (2.*fGeometryService->DetHalfWidth())/detProp.DriftVelocity(); // [us]
80  }
81 
82 
83  void GenFilter::reconfigure(fhicl::ParameterSet const& pset){
84  fUseTopHighCRTs = pset.get<bool>("UseTopHighCRTs");
85  fUseTopLowCRTs = pset.get<bool>("UseTopLowCRTs");
86  fUseBottomCRTs = pset.get<bool>("UseBottomCRTs");
87  fUseFrontCRTs = pset.get<bool>("UseFrontCRTs");
88  fUseBackCRTs = pset.get<bool>("UseBackCRTs");
89  fUseLeftCRTs = pset.get<bool>("UseLeftCRTs");
90  fUseRightCRTs = pset.get<bool>("UseRightCRTs");
91  fPDGs = pset.get<std::vector<int> >("PDGs");
92  fMinMomentums = pset.get<std::vector<double> >("MinMomentums");
93  fMaxMomentums = pset.get<std::vector<double> >("MaxMomentums");
94  fCRTDimensionScaling = pset.get<double>("CRTDimensionScaling");
95  fUseReadoutWindow = pset.get<bool>("UseReadoutWindow");
96  fUseTightReadoutWindow = pset.get<bool>("UseTightReadoutWindow");
97  }
98 
99 
100  bool GenFilter::filter(art::Event & e){
101  //std::vector< art::Handle< std::vector<simb::MCTruth> > > mclists;
102  //e.getManyByType(mclists);
103  auto mclists = e.getMany< std::vector<simb::MCTruth> >();
104 
105  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e);
106 
107  for (unsigned int i = 0; i < mclists.size() ; i++){
108  for (unsigned int j = 0; j < mclists[i]->size(); j++){
109  //Should have the truth record for the event now
110  const art::Ptr<simb::MCTruth> mc_truth(mclists[i],j);
111  // std::cout << " MCtruth particles " << mc_truth->NParticles() << std::endl;
112  for (int part = 0; part < mc_truth->NParticles(); part++){
113  const simb::MCParticle particle = mc_truth->GetParticle(part);
114 
115  if (!IsInterestingParticle(particle)) continue;
116 
117  double time = particle.T() * 1e-3; //[us]
118 
119  if (fUseReadoutWindow){
120  if (time < -driftTime || time > readoutWindow) continue;
121  // Get the minimum and maximum |x| position in the TPC
122  std::pair<double, double> xLimits = XLimitsTPC(particle);
123  // std::cout << xLimits.first << " " << xLimits.second << std::endl;
124  // Calculate the expected time of arrival of those points
125  double minTime = time + (2.0 * fGeometryService->DetHalfWidth() - xLimits.second)/detProp.DriftVelocity();
126  double maxTime = time + (2.0 * fGeometryService->DetHalfWidth() - xLimits.first)/detProp.DriftVelocity();
127  // If both times are below or above the readout window time then skip
128  if((minTime < 0 && maxTime < 0) || (minTime > readoutWindow && maxTime > readoutWindow)) continue;
129  }
131  if (time<0 || time>(readoutWindow-driftTime)) continue;
132  }
133 
134  if (fUseTopHighCRTs){
135  bool OK = UsesCRTAuxDets(particle, fTopHighCRTAuxDetIDs);
136  if (!OK) continue;
137  //std::cout<<"TopHighCRTs: " << OK << std::endl;
138  }
139  if (fUseTopLowCRTs){
140  bool OK = UsesCRTAuxDets(particle, fTopLowCRTAuxDetIDs);
141  if (!OK) continue;
142 
143  //std::cout<<"TopLowCRTs: " << OK << std::endl;
144  }
145  if (fUseBottomCRTs){
146  bool OK = UsesCRTAuxDets(particle, fBottomCRTAuxDetIDs);
147  if (!OK) continue;
148  //std::cout<<"BottomCRTs: " << OK << std::endl;
149  }
150  if (fUseFrontCRTs){
151  bool OK = UsesCRTAuxDets(particle, fFrontCRTAuxDetIDs);
152  if (!OK) continue;
153  //std::cout<<"FrontCRTs: " << OK << std::endl;
154  }
155  if (fUseBackCRTs){
156  bool OK = UsesCRTAuxDets(particle, fBackCRTAuxDetIDs);
157  if (!OK) continue;
158  //std::cout<<"BackCRTs: " << OK << std::endl;
159  }
160  if (fUseLeftCRTs){
161  bool OK = UsesCRTAuxDets(particle, fLeftCRTAuxDetIDs);
162  if (!OK) continue;
163  //std::cout<<"LeftCRTs: " << OK << std::endl;
164  }
165  if (fUseRightCRTs){
166  bool OK = UsesCRTAuxDets(particle, fRightCRTAuxDetIDs);
167  if (!OK) continue;
168  //std::cout<<"RightCRTs: " << OK << std::endl;
169  }
170 
171  return true;
172  }
173  }
174  }
175 
176  return false;
177  }
178 
179 
182  }
183 
184 
185  bool GenFilter::IsInterestingParticle(const simb::MCParticle &particle){
186  double mom = particle.Momentum().Vect().Mag();
187  int pdg = particle.PdgCode();
188 
189  for (unsigned int particle_i = 0; particle_i < fPDGs.size(); particle_i++){
190  bool matched = true;
191  //Check minimum momentum
192  if (fMinMomentums[particle_i] > 0 && mom < fMinMomentums[particle_i]) matched = false;
193  //Check maximum momentum
194  if (fMaxMomentums[particle_i] > 0 && mom > fMaxMomentums[particle_i]) matched = false;
195  //Check PDG
196  if (fPDGs[particle_i]!=0 && pdg!=fPDGs[particle_i]) matched = false;
197  if(matched) return true;
198  }
199  return false;
200  }
201 
202 
204  art::ServiceHandle<geo::Geometry> geom;
205 
206  for (unsigned int auxdet_i = 0; auxdet_i < geom->NAuxDets(); auxdet_i++){
207  geo::AuxDetGeo const& crt = geom->AuxDet(auxdet_i);
208  const TGeoVolume* volModule = crt.TotalVolume();
209  std::set<std::string> volNames = { volModule->GetName() };
210  std::vector<std::vector<TGeoNode const*> > paths = geom->FindAllVolumePaths(volNames);
211 
212  std::string path = "";
213  for (size_t inode=0; inode<paths.at(0).size(); inode++) {
214  path += paths.at(0).at(inode)->GetName();
215  if (inode < paths.at(0).size() - 1) {
216  path += "/";
217  }
218  }
219 
220  TGeoManager* manager = geom->ROOTGeoManager();
221  manager->cd(path.c_str());
222 
223  manager->GetCurrentNode();
224  manager->GetMother(1);
225  TGeoNode* nodeTagger = manager->GetMother(2);
226 
227  std::string taggerName = nodeTagger->GetName();
228 
229  //Now a bunch of if statements so that we can fill our CRT AuxDet ID vectors
230  //BLEH
231  if (taggerName.find("TopHigh")!=std::string::npos){
232  fTopHighCRTAuxDetIDs.push_back(auxdet_i);
233  }
234  else if (taggerName.find("TopLow")!=std::string::npos){
235  fTopLowCRTAuxDetIDs.push_back(auxdet_i);
236  }
237  else if (taggerName.find("Bot")!=std::string::npos){
238  fBottomCRTAuxDetIDs.push_back(auxdet_i);
239  }
240  else if (taggerName.find("South")!=std::string::npos){
241  fFrontCRTAuxDetIDs.push_back(auxdet_i);
242  }
243  else if (taggerName.find("North")!=std::string::npos){
244  fBackCRTAuxDetIDs.push_back(auxdet_i);
245  }
246  else if (taggerName.find("West")!=std::string::npos){
247  fLeftCRTAuxDetIDs.push_back(auxdet_i);
248  }
249  else if (taggerName.find("East")!=std::string::npos){
250  fRightCRTAuxDetIDs.push_back(auxdet_i);
251  }
252  else {
253  std::cout << "Tagger with name: " << taggerName
254  << " does not fit the logic. This should not happen!!!!!!" << std::endl;
255  }
256  }
257 
258  std::cout<< "No. top high CRT AuxDets found: " << fTopHighCRTAuxDetIDs.size() << std::endl;
259  std::cout<< "No. top low CRT AuxDets found: " << fTopLowCRTAuxDetIDs.size() << std::endl;
260  std::cout<< "No. bottom CRT AuxDets found: " << fBottomCRTAuxDetIDs.size() << std::endl;
261  std::cout<< "No. front CRT AuxDets found: " << fFrontCRTAuxDetIDs.size() << std::endl;
262  std::cout<< "No. back CRT AuxDets found: " << fBackCRTAuxDetIDs.size() << std::endl;
263  std::cout<< "No. left CRT AuxDets found: " << fLeftCRTAuxDetIDs.size() << std::endl;
264  std::cout<< "No. right CRT AuxDets found: " << fRightCRTAuxDetIDs.size() << std::endl;
265  return;
266  }
267 
268 
269  bool GenFilter::UsesCRTAuxDets(const simb::MCParticle &particle, const std::vector<unsigned int> &crt_auxdet_vector){
270  //Loop over the aux dets, extract each one and then perform the test
271  art::ServiceHandle<geo::Geometry> geom;
272 
273  for (unsigned int i = 0; i < crt_auxdet_vector.size(); i++){
274  unsigned int auxdet_index = crt_auxdet_vector[i];
275  geo::AuxDetGeo const& crt = geom->AuxDet(auxdet_index);
276  if (UsesCRTAuxDet(particle,crt)){
277  return true;
278  }
279  }
280 
281  return false;
282  }
283 
284  bool GenFilter::UsesCRTAuxDet(const simb::MCParticle &particle, geo::AuxDetGeo const& crt){
285  //We need to prepare the particle's position and direction and construct a bounding box from the CRT for the ray-box collision algorithm
286  //Start with the particle
287  double particle_position_array[3], particle_direction_array[3], particle_local_position_array[3], particle_local_direction_array[3];
288  particle_position_array[0] = particle.Position(0).X();
289  particle_position_array[1] = particle.Position(0).Y();
290  particle_position_array[2] = particle.Position(0).Z();
291  particle_direction_array[0] = particle.Momentum(0).X()/particle.Momentum(0).Vect().Mag();
292  particle_direction_array[1] = particle.Momentum(0).Y()/particle.Momentum(0).Vect().Mag();
293  particle_direction_array[2] = particle.Momentum(0).Z()/particle.Momentum(0).Vect().Mag();
294  crt.WorldToLocal(particle_position_array,particle_local_position_array);
295  crt.WorldToLocalVect(particle_direction_array,particle_local_direction_array);
296  TVector3 particle_local_position(particle_local_position_array[0],particle_local_position_array[1],particle_local_position_array[2]);
297  TVector3 particle_local_direction(particle_local_direction_array[0],particle_local_direction_array[1],particle_local_direction_array[2]);
298  double norm[3], lnorm[3];
299  double center[3];
300  crt.GetNormalVector(norm);
301  crt.WorldToLocalVect(norm,lnorm);
302  crt.GetCenter(center);
303 
304  //Now make the bounding box min and max extent from the CRT
305  //In local coordinates, the normal of the CRT is parallel to the z-axis, the length is parallel to z, width parallel to x and height parallel to y
306  //A gotchya: AuxDets pass half widths and half heights but FULL lengths. So, divide length by 2
307  TVector3 crt_min_extent(-1.*crt.HalfWidth1(),-1.*crt.HalfHeight(),-1.*crt.Length()/2.);
308  //Scale the dimensions if the user wants them scaling
309  crt_min_extent*=fCRTDimensionScaling;
310  //Now make the max extent
311  //Use symmetry to reduce change of a typo
312  TVector3 crt_max_extent = crt_min_extent*-1.;
313 
314  //Now run the algorithm
315  return RayIntersectsBox(particle_local_position,particle_local_direction,crt_min_extent,crt_max_extent);
316  }
317 
318 
319  bool GenFilter::RayIntersectsBox(TVector3 ray_origin, TVector3 ray_direction, TVector3 box_min_extent, TVector3 box_max_extent){
320  double t1 = (box_min_extent.X() - ray_origin.X())/ray_direction.X();
321  double t2 = (box_max_extent.X() - ray_origin.X())/ray_direction.X();
322  double t3 = (box_min_extent.Y() - ray_origin.Y())/ray_direction.Y();
323  double t4 = (box_max_extent.Y() - ray_origin.Y())/ray_direction.Y();
324  double t5 = (box_min_extent.Z() - ray_origin.Z())/ray_direction.Z();
325  double t6 = (box_max_extent.Z() - ray_origin.Z())/ray_direction.Z();
326 
327  double tmin = std::max(std::max(std::min(t1, t2), std::min(t3, t4)), std::min(t5, t6));
328  double tmax = std::min(std::min(std::max(t1, t2), std::max(t3, t4)), std::max(t5, t6));
329 
330  if (tmin > tmax){
331  //std::cout<<"Ray does not intersect the box"<<std::endl;
332  return false;
333  }
334  if (tmax < 0){
335  //std::cout<<"Ray path intersects but ray is aiming the wrong way"<<std::endl;
336  return false;
337  }
338 
339 
340  //std::cout<<"Ray intersects the box"<<std::endl;
341  return true;
342  }
343 
344  std::pair<double, double> GenFilter::XLimitsTPC(const simb::MCParticle &particle){
345 
346  TVector3 start (particle.Position().X(), particle.Position().Y(), particle.Position().Z());
347  TVector3 direction (particle.Momentum().X()/particle.Momentum().Vect().Mag(),
348  particle.Momentum().Y()/particle.Momentum().Vect().Mag(),
349  particle.Momentum().Z()/particle.Momentum().Vect().Mag());
350  TVector3 end = start + direction;
351 
352  double minimum = 99999;
353  double maximum = -99999;
354  for(size_t c = 0; c < fGeometryService->Ncryostats(); c++){
355  const geo::CryostatGeo& cryostat = fGeometryService->Cryostat(c);
356  for(size_t t = 0; t < cryostat.NTPC(); t++){
357  const geo::TPCGeo& tpcGeo = cryostat.TPC(t);
358  // Find the intersection between the track and the TPC
359  TVector3 min (tpcGeo.MinX(), tpcGeo.MinY(), tpcGeo.MinZ());
360  TVector3 max (tpcGeo.MaxX(), tpcGeo.MaxY(), tpcGeo.MaxZ());
361 
362  std::pair<TVector3, TVector3> intersection = CubeIntersection(min, max, start, end);
363  double x1 = std::abs(intersection.first.X());
364  double x2 = std::abs(intersection.second.X());
365  if(x1 != -99999 && x1 > maximum) maximum = x1;
366  if(x1 != -99999 && x1 < minimum) minimum = x1;
367  if(x2 != -99999 && x2 > maximum) maximum = x2;
368  if(x2 != -99999 && x2 < minimum) minimum = x2;
369  }
370  }
371 
372  return std::make_pair(minimum, maximum);
373  }
374 
375  std::pair<TVector3, TVector3> GenFilter::CubeIntersection(TVector3 min, TVector3 max, TVector3 start, TVector3 end){
376 
377  TVector3 dir = (end - start);
378  TVector3 invDir (1./dir.X(), 1./dir.Y(), 1/dir.Z());
379 
380  double tmin, tmax, tymin, tymax, tzmin, tzmax;
381 
382  TVector3 enter (-99999, -99999, -99999);
383  TVector3 exit (-99999, -99999, -99999);
384 
385  // Find the intersections with the X plane
386  if(invDir.X() >= 0){
387  tmin = (min.X() - start.X()) * invDir.X();
388  tmax = (max.X() - start.X()) * invDir.X();
389  }
390  else{
391  tmin = (max.X() - start.X()) * invDir.X();
392  tmax = (min.X() - start.X()) * invDir.X();
393  }
394 
395  // Find the intersections with the Y plane
396  if(invDir.Y() >= 0){
397  tymin = (min.Y() - start.Y()) * invDir.Y();
398  tymax = (max.Y() - start.Y()) * invDir.Y();
399  }
400  else{
401  tymin = (max.Y() - start.Y()) * invDir.Y();
402  tymax = (min.Y() - start.Y()) * invDir.Y();
403  }
404 
405  // Check that it actually intersects
406  if((tmin > tymax) || (tymin > tmax)) return std::make_pair(enter, exit);
407 
408  // Max of the min points is the actual intersection
409  if(tymin > tmin) tmin = tymin;
410 
411  // Min of the max points is the actual intersection
412  if(tymax < tmax) tmax = tymax;
413 
414  // Find the intersection with the Z plane
415  if(invDir.Z() >= 0){
416  tzmin = (min.Z() - start.Z()) * invDir.Z();
417  tzmax = (max.Z() - start.Z()) * invDir.Z();
418  }
419  else{
420  tzmin = (max.Z() - start.Z()) * invDir.Z();
421  tzmax = (min.Z() - start.Z()) * invDir.Z();
422  }
423 
424  // Check for intersection
425  if((tmin > tzmax) || (tzmin > tmax)) return std::make_pair(enter, exit);
426 
427  // Find final intersection points
428  if(tzmin > tmin) tmin = tzmin;
429 
430  // Find final intersection points
431  if(tzmax < tmax) tmax = tzmax;
432 
433  // Calculate the actual crossing points
434  double xmin = start.X() + tmin * dir.X();
435  double xmax = start.X() + tmax * dir.X();
436  double ymin = start.Y() + tmin * dir.Y();
437  double ymax = start.Y() + tmax * dir.Y();
438  double zmin = start.Z() + tmin * dir.Z();
439  double zmax = start.Z() + tmax * dir.Z();
440 
441  // Return pair of entry and exit points
442  enter.SetXYZ(xmin, ymin, zmin);
443  exit.SetXYZ(xmax, ymax, zmax);
444  return std::make_pair(enter, exit);
445 
446  }
447 
448  DEFINE_ART_MODULE(GenFilter)
449 
450 }
bool IsInterestingParticle(const simb::MCParticle &particle)
std::vector< unsigned int > fBackCRTAuxDetIDs
Utilities related to art service access.
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
var pdg
Definition: selectors.fcl:14
void WorldToLocal(const double *world, double *auxdet) const
Transform point from world frame to local auxiliary detector frame.
Definition: AuxDetGeo.h:136
double MinX() const
Returns the world x coordinate of the start of the box.
Definition: BoxBoundedGeo.h:88
Geometry information for a single TPC.
Definition: TPCGeo.h:38
void WorldToLocalVect(const double *world, double *auxdet) const
Transform direction vector from world to local.
Definition: AuxDetGeo.h:144
double MaxX() const
Returns the world x coordinate of the end of the box.
Definition: BoxBoundedGeo.h:91
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
std::vector< double > fMaxMomentums
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
std::vector< int > fPDGs
std::vector< unsigned int > fLeftCRTAuxDetIDs
std::vector< unsigned int > fTopLowCRTAuxDetIDs
process_name pandoraGausCryo1 vertexChargeCryo1 vertexStubCryo1 xmin
BEGIN_PROLOG triggeremu_data_config_icarus settings PMTADCthresholds sequence::icarus_stage0_multiTPC_TPC physics sequence::icarus_stage0_EastHits_TPC physics sequence::icarus_stage0_WestHits_TPC physics producers purityana0 caloskimCalorimetryCryoE physics caloskimCalorimetryCryoW physics path
Access the description of detector geometry.
GenFilter(fhicl::ParameterSet const &pset)
T abs(T value)
std::vector< double > fMinMomentums
std::vector< unsigned int > fRightCRTAuxDetIDs
double HalfHeight() const
Definition: AuxDetGeo.h:105
std::vector< unsigned int > fFrontCRTAuxDetIDs
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
double MinZ() const
Returns the world z coordinate of the start of the box.
unsigned int NTPC() const
Number of TPCs in this cryostat.
Definition: CryostatGeo.h:181
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
geo::Vector_t GetNormalVector() const
Returns the unit normal vector to the detector.
Definition: AuxDetGeo.cxx:72
Description of geometry of one entire detector.
bool UsesCRTAuxDet(const simb::MCParticle &particle, geo::AuxDetGeo const &crt)
bool RayIntersectsBox(TVector3 ray_origin, TVector3 ray_direction, TVector3 box_min_extent, TVector3 box_max_extent)
auto norm(Vector const &v)
Return norm of the specified vector.
double MaxY() const
Returns the world y coordinate of the end of the box.
std::pair< TVector3, TVector3 > CubeIntersection(TVector3 min, TVector3 max, TVector3 start, TVector3 end)
tuple dir
Definition: dropbox.py:28
double Length() const
Definition: AuxDetGeo.h:102
const TGeoVolume * TotalVolume() const
Definition: AuxDetGeo.h:106
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
Definition: CryostatGeo.cxx:93
std::vector< unsigned int > fBottomCRTAuxDetIDs
double MaxZ() const
Returns the world z coordinate of the end of the box.
then filt
std::vector< unsigned int > fTopHighCRTAuxDetIDs
do i e
geo::GeometryCore const * fGeometryService
double HalfWidth1() const
Definition: AuxDetGeo.h:103
virtual void beginJob() override
process_name crt
double MinY() const
Returns the world y coordinate of the start of the box.
void reconfigure(fhicl::ParameterSet const &pset)
std::pair< double, double > XLimitsTPC(const simb::MCParticle &particle)
virtual bool filter(art::Event &e) override
art framework interface to geometry description
BEGIN_PROLOG could also be cout
auto const detProp
void GetCenter(double *xyz, double localz=0.0) const
Return the center position of an AuxDet.
Definition: AuxDetGeo.cxx:62
bool UsesCRTAuxDets(const simb::MCParticle &particle, const std::vector< unsigned int > &crt_auxdet_vector)