HelloAuxDet_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: HelloAuxDet
3 // Plugin Type: analyzer (art v2_10_03)
4 // File: HelloAuxDet_module.cc
5 // Brief: Demonstration of how to access AuxDetGeos and AuxDetDigits
6 // in LArSoft. Checks for presence of AuxDetGeos in geometry
7 // service for ProtoDUNE-SP. Absence may be due to needing
8 // a dedicated ChannelMapAlg to register AuxDets with
9 // the Geometry service.
10 //
11 // Generated at Wed May 16 09:02:34 2018 by Andrew Olivier (aolivier@ur.rochester.edu) using cetskelgen
12 // from cetlib version v3_02_00.
13 ////////////////////////////////////////////////////////////////////////
14 
15 //ART includes
23 #include "fhiclcpp/ParameterSet.h"
25 #include "art_root_io/TFileService.h"
26 
27 //LArSoft includes
33 
34 //ROOT includes
35 #include "TH1D.h"
36 
37 namespace ex {
38  class HelloAuxDet;
39 }
40 
41 //Helper functions
42 namespace
43 {
44  /*template <class STREAM, class FLOAT>
45  STREAM& PrintVec(STREAM& stream, const FLOAT& x, const FLOAT& y, const FLOAT& z)
46  {
47  stream << "(" << x << ", " << y << ", " << z << ")";
48  return stream;
49  }
50 
51  void Print(const raw::AuxDetDigit& digit)
52  {
53  mf::LogInfo("AuxDetDigits") << "Got a digit for a detector named " << digit.AuxDetName() << " at channel " << digit.Channel() << " at time "
54  << digit.TimeStamp() << "\n";
55  }
56 
57  void Print(const sim::AuxDetSimChannel& channel)
58  {
59  mf::LogInfo("AuxDetSimChannels") << "Got an AuxDetSimChannel for ID " << channel.AuxDetID() << " sensitive volume "
60  << channel.AuxDetSensitiveID() << " with " << channel.AuxDetIDEs().size() << " energy deposits:\n";
61  for(const auto& ide: channel.AuxDetIDEs())
62  {
63  auto stream = mf::LogInfo("AuxDetIDEs");
64  stream << "TrackID: " << ide.trackID
65  << "energyDeposit: " << ide.energyDeposited
66  << "entry point: ";
67  ::PrintVec(stream, ide.entryX, ide.entryY, ide.entryZ);
68  stream << "exit point: ";
69  ::PrintVec(stream, ide.exitX, ide.exitY, ide.exitZ);
70  }
71  }
72 
73  //TODO: Member function?
74  //Print all of the data PRODUCTs of a specific type produced by each label in labels. If labels is empty, Print all of the
75  //data PRODUCTs in the event.
76  template <class PRODUCT, class LABEL>
77  void PrintAllIfEmpty(const std::vector<LABEL>& labels, const art::Event& e)
78  {
79  std::vector<art::Handle<std::vector<PRODUCT>>> algs;
80  if(labels.empty()) //If no labels requested, print all PRODUCTs
81  {
82  e.getManyByType(algs);
83  }
84  else
85  {
86  for(const auto& label: labels)
87  {
88  algs.emplace_back();
89  algs.back() = e.getHandle<std::vector<PRODUCT>>(label);
90  }
91  }
92  for(const auto& prods: algs)
93  {
94  for(const auto& prod: *prods) ::Print(prod);
95  }
96  }*/
97 }
98 
100 public:
101  explicit HelloAuxDet(fhicl::ParameterSet const & p);
102  // The compiler-generated destructor is fine for non-base
103  // classes without bare pointers or other resource use.
104 
105  // Plugins should not be copied or assigned.
106  HelloAuxDet(HelloAuxDet const &) = delete;
107  HelloAuxDet(HelloAuxDet &&) = delete;
108  HelloAuxDet & operator = (HelloAuxDet const &) = delete;
109  HelloAuxDet & operator = (HelloAuxDet &&) = delete;
110 
111  // Required functions.
112  void analyze(art::Event const & e) override;
113 
114  // Selected optional functions.
115  void beginJob() override;
116 
117 private:
118 
119  // Configuration data
120  std::vector<art::InputTag> fDigitLabels; //Search for AuxDetDigits produced by modules with these labels
121  std::vector<art::InputTag> fSimLabels; //Search for AuxDetSimChannels produced by modules with these labels
122  art::InputTag fPartLabel; //Label of the module that produced simb::MCParticles
123 
124  // Observer pointers to histograms that will be written
125  TH1D* fXDistToTrueTrackFront; //Distance in x from CRT AuxDetSimChannel to where true trajectory passed through a CRT module.
126  TH1D* fYDistToTrueTrackFront; //Distance in y from CRT AuxDetSimChannel to where true trajectory passed through a CRT module.
127 };
128 
129 
131  :
132  EDAnalyzer(p) // ,
133  // More initializers here.
134 {
135  fDigitLabels = p.get<std::vector<art::InputTag>>("DigitLabels", {});
136  fSimLabels = p.get<std::vector<art::InputTag>>("SimLabels", {});
137  fPartLabel = p.get<art::InputTag>("PartLabel", "largeant");
138 }
139 
141 {
142  //Print() AuxDetDigits
143  //::PrintAllIfEmpty<raw::AuxDetDigit>(fDigitLabels, e);
144 
145  //Print() AuxDetSimChannels
146  //::PrintAllIfEmpty<sim::AuxDetSimChannel>(fSimLabels, e);
147 
148  //Produce a map from TrackId to MCParticle
149  const auto parts = e.getValidHandle<std::vector<simb::MCParticle>>(fPartLabel);
150  std::map<int, simb::MCParticle> idToPart; //Map of Geant TrackId to particle
151  for(const auto& part: *parts) idToPart[part.TrackId()] = part;
152 
153  idToPart[-1] = idToPart[0]; //TODO: Remove this hack that makes sure the primary particle is recognized
154  mf::LogInfo("Number of Particles") << "There are " << parts->size() << " simb::MCParticles in this event.\n";
155 
156  //Make histograms showing that channel mapping works for AuxDetSimChannels
158  for(const auto& label: fSimLabels)
159  {
160  const auto channels = e.getValidHandle<std::vector<sim::AuxDetSimChannel>>(label);
161  for(const auto& channel: *channels)
162  {
163  const auto& auxDet = geom->AuxDet(channel.AuxDetID());
164  const auto& sens = auxDet.SensitiveVolume(channel.AuxDetSensitiveID());
165  const auto center = sens.GetCenter();
166  TLorentzVector centerV(center.X(), center.Y(), center.Z(), 0.); //TODO: Use GenVector when I have time to figure it out
167  for(const auto& ide: channel.AuxDetIDEs())
168  {
169  const auto found = idToPart.find(ide.trackID);
170  if(found != idToPart.end())
171  {
172  const auto& part = found->second;
173  const auto closestPt = std::min_element(part.Trajectory().begin(), part.Trajectory().end(),
174  [&centerV](const auto& first, const auto& second)
175  {
176  //SimulationBase coordinates are in mm, but Geometry service coordinates are in cm!
177  //Convert to cm.
178  return (first.first*0.1-centerV).Vect().Mag() < (second.first*0.1-centerV).Vect().Mag();
179  });
180 
181  if(closestPt != part.Trajectory().end())
182  {
183  //Figure out the x and y positions where the CRT was hit
184  //TODO: This is a hack to partially get around my lack of knowledge about the CRT channel mapping.
185  // I'd like to figure this out by identifying the AuxDet.
186  if(sens.toWorldCoords(geo::AuxDetSensitiveGeo::LocalPoint_t(0, 0, sens.HalfLength())).Y() - center.Y()
187  > sens.toWorldCoords(geo::AuxDetSensitiveGeo::LocalPoint_t(0, 0, sens.HalfLength())).X() - center.X())
188  //If a CRT hit that gives x position
189  {
190  fXDistToTrueTrackFront->Fill(centerV.X() - closestPt->first.X());
191  }
192  else //This is a CRT hit that gives y position
193  {
194  fYDistToTrueTrackFront->Fill(centerV.Y() - closestPt->first.Y());
195  }
196  }
197  else mf::LogWarning("No Closest Point") << "No point found that is considered \"closest\" to AuxDetSensitive!\n";
198  }
199  else mf::LogWarning("No Such TrackID") << "No map entry for TrackID " << ide.trackID << "\n";
200  }
201  }
202  }
203 }
204 
206 {
207  // Print all of the AuxDetGeos that the Geometry service knows about.
208  const auto geom = lar::providerFrom<geo::Geometry>();
209 
210  //Get AuxDetGeos and print their names.
211  for(size_t det = 0; det < geom->NAuxDets(); ++det)
212  {
213  const auto& geo = geom->AuxDet(det);
214  mf::LogInfo("AuxDetGeometry") << "AuxDetGeo number " << det << ", " << geo.Name() << ", is centered at " << geo.GetCenter()
215  << " and has sensitive volumes:\n";
216  for(size_t sens = 0; sens < geo.NSensitiveVolume(); ++sens)
217  {
218  const auto& sensGeo = geo.SensitiveVolume(sens);
219  const auto center = sensGeo.GetCenter();
220  const bool xPos = (sensGeo.toWorldCoords(geo::AuxDetSensitiveGeo::LocalPoint_t(0, 0, sensGeo.HalfLength())).Y() - center.Y()
221  > sensGeo.toWorldCoords(geo::AuxDetSensitiveGeo::LocalPoint_t(0, 0, sensGeo.HalfLength())).X() - center.X());
222  mf::LogInfo("AuxDetGeometry") << "Sensitive volume " << sens << ": " << sensGeo.TotalVolume()->GetName() << " with center "
223  << sensGeo.GetCenter() << " which gives information about " << std::string(xPos?"X":"Y") << " coordinates.\n";
224  }
225  }
226 
227  //Tell the framework that I intend to consume AuxDetDigits and AuxDetSimChannels
228  for(const auto& label: fDigitLabels) consumes<std::vector<raw::AuxDetDigit>>(label);
229  for(const auto& label: fSimLabels) consumes<std::vector<sim::AuxDetSimChannel>>(label);
230  consumes<std::vector<simb::MCParticle>>(fPartLabel);
231 
232  //Create histograms owned by "The Framework" that I will fill
234  fXDistToTrueTrackFront = tfs->make<TH1D>("XDistToTrueTrackFront", "X Distance from True Trajectory to CRT Hits"
235  ";X[mm];Events", 150, -30, 30);
236  fYDistToTrueTrackFront = tfs->make<TH1D>("YDistToTrueTrackFront", "Y Distance from True Trajectory to CRT Hits"
237  ";Y[mm];Events", 150, -30, 30);
238 }
239 
void beginJob() override
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
AuxDetSensitiveGeo const & SensitiveVolume(size_t sv) const
Definition: AuxDetGeo.h:171
HelloAuxDet(fhicl::ParameterSet const &p)
std::vector< art::InputTag > fDigitLabels
uint8_t channel
Definition: CRTFragment.hh:201
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
Particle class.
art framework interface to geometry description
HelloAuxDet & operator=(HelloAuxDet const &)=delete
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
T get(std::string const &key) const
Definition: ParameterSet.h:271
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
p
Definition: test.py:223
void analyze(art::Event const &e) override
art::InputTag fPartLabel
AuxDetGeo const & AuxDet(unsigned int const ad=0) const
Returns the specified auxiliary detector.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
def center(depos, point)
Definition: depos.py:117
geo::Point3DBase_t< AuxDetSensitiveGeoCoordinatesTag > LocalPoint_t
Type of points in the local GDML auxiliary detector frame.
Access the description of detector geometry.
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
LArSoft geometry interface.
Definition: ChannelGeo.h:16
std::vector< art::InputTag > fSimLabels