All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DumpSimPhotons_module.cc
Go to the documentation of this file.
1 /**
2  * @file DumpSimPhotons_module.cc
3  * @brief Module dumping SimPhotons information on screen
4  * @date March 30, 2016
5  * @author Gianluca Petrillo (petrillo@fnal.gov)
6  *
7  */
8 
9 
10 // lar libraries
12 #include "larcorealg/CoreUtils/SortByPointers.h" // util::makePointerVector()
13 
14 // framework libraries
15 #include "art/Framework/Core/EDAnalyzer.h"
16 #include "art/Framework/Core/ModuleMacros.h"
17 #include "art/Framework/Principal/Event.h"
18 #include "art/Framework/Principal/Handle.h"
19 #include "canvas/Utilities/InputTag.h"
20 #include "fhiclcpp/types/Atom.h"
21 #include "messagefacility/MessageLogger/MessageLogger.h"
22 
23 
24 
25 namespace sim {
26  class DumpSimPhotons;
27 } // namespace sim
28 
29 namespace {
30  using namespace fhicl;
31 
32  /// Collection of configuration parameters for the module
33  struct Config {
34  using Name = fhicl::Name;
35  using Comment = fhicl::Comment;
36 
37  fhicl::Atom<art::InputTag> InputPhotons {
38  Name("InputPhotons"),
39  Comment("data product with the SimPhotons to be dumped")
40  };
41 
42  fhicl::Atom<std::string> OutputCategory {
43  Name("OutputCategory"),
44  Comment("name of the output stream (managed by the message facility)"),
45  "DumpSimPhotons" /* default value */
46  };
47 
48  }; // struct Config
49 
50 
51  /**
52  * @brief Sorts `sim::OnePhoton` objects.
53  *
54  * The sorting criteria are:
55  *
56  * 1. arrival time
57  * 2. particle identificator (GEANT4 track ID)
58  * 3. energy
59  * 4. starting position: _z_, then _y_, then _x_
60  *
61  * Comparison of objects with all these values the same yields `false` and the
62  * two objects are considered equivalent.
63  */
64  struct OnePhotonSorter {
65 
66  /// Direct comparison of `sim::OnePhoton` objects.
67  bool operator() (sim::OnePhoton const& a, sim::OnePhoton const& b) const
68  {
69  auto res = cmp(a.Time, b.Time);
70  if (res < 0) return true;
71  if (res > 0) return false;
72 
73  res = cmp(a.MotherTrackID, b.MotherTrackID);
74  if (res < 0) return true;
75  if (res > 0) return false;
76 
77  res = cmp(a.Energy, b.Energy);
78  if (res < 0) return true;
79  if (res > 0) return false;
80 
81  res = cmp(a.InitialPosition.Z(), b.InitialPosition.Z());
82  if (res < 0) return true;
83  if (res > 0) return false;
84 
85  res = cmp(a.InitialPosition.Y(), b.InitialPosition.Y());
86  if (res < 0) return true;
87  if (res > 0) return false;
88 
89  res = cmp(a.InitialPosition.X(), b.InitialPosition.X());
90  if (res < 0) return true;
91  if (res > 0) return false;
92 
93  return false; //
94  } // operator()
95 
96  /// Comparison of `sim::OnePhoton` via their pointers.
97  bool operator() (sim::OnePhoton const* a, sim::OnePhoton const* b) const
98  { return operator() (*a, *b); }
99 
100 
101  // TODO when C++20 is supported, this becomes `return a <=> b;`
102  template <typename T, typename U>
103  static int cmp(T const& a, U const& b)
104  {
105  if (a < b) return -1;
106  if (a == b) return 0;
107  else return +1;
108  }
109 
110  }; // struct OnePhotonSorter
111 
112 } // local namespace
113 
114 
115 class sim::DumpSimPhotons: public art::EDAnalyzer {
116  public:
117  // type to enable module parameters description by art
118  using Parameters = art::EDAnalyzer::Table<Config>;
119 
120  /// Configuration-checking constructor
121  explicit DumpSimPhotons(Parameters const& config);
122 
123  // Plugins should not be copied or assigned.
124  DumpSimPhotons(DumpSimPhotons const&) = delete;
125  DumpSimPhotons(DumpSimPhotons &&) = delete;
126  DumpSimPhotons& operator = (DumpSimPhotons const&) = delete;
127  DumpSimPhotons& operator = (DumpSimPhotons &&) = delete;
128 
129 
130  // Operates on the event
131  void analyze(art::Event const& event) override;
132 
133 
134  /**
135  * @brief Dumps the content of the specified SimPhotons in the output stream
136  * @tparam Stream the type of output stream
137  * @param out the output stream
138  * @param simphotons the SimPhotons to be dumped
139  * @param indent base indentation string (default: none)
140  * @param bIndentFirst if first output line should be indented (default: yes)
141  *
142  * The indent string is prepended to every line of output, with the possible
143  * exception of the first one, in case bIndentFirst is true.
144  *
145  * The output starts on the current line, and the last line is NOT broken.
146  */
147  template <typename Stream>
148  void DumpElement(
149  Stream&& out, sim::SimPhotons const& simphotons,
150  std::string indent = "", bool bIndentFirst = true
151  ) const;
152 
153  /// Dumps a sim::OnePhoton on a single line
154  template <typename Stream>
155  void DumpOnePhoton(Stream&& out, sim::OnePhoton const& photon) const;
156 
157 
158  private:
159 
160  art::InputTag fInputPhotons; ///< name of SimPhotons's data product
161  std::string fOutputCategory; ///< name of the stream for output
162 
163 }; // class sim::DumpSimPhotons
164 
165 
166 //------------------------------------------------------------------------------
167 //--- module implementation
168 //---
169 //------------------------------------------------------------------------------
171  : EDAnalyzer(config)
172  , fInputPhotons(config().InputPhotons())
173  , fOutputCategory(config().OutputCategory())
174 {}
175 
176 //------------------------------------------------------------------------------
177 template <typename Stream>
179  (Stream&& out, sim::OnePhoton const& onephoton) const
180 {
181  out << "E=" << onephoton.Energy << " t=" << onephoton.Time
182  << " from " << onephoton.InitialPosition << " cm"
183  << " to " << onephoton.FinalLocalPosition << " cm"
184  ;
185  if (onephoton.SetInSD) out << " [in SD]"; // in sensitive detector?
186  out << " from track ID=" << onephoton.MotherTrackID;
187 } // sim::DumpSimPhotons::DumpOnePhoton()
188 
189 
190 //------------------------------------------------------------------------------
191 template <typename Stream>
193  Stream&& out, sim::SimPhotons const& simphotons,
194  std::string indent /* = "" */, bool bIndentFirst /* = true */
195 ) const {
196  if (bIndentFirst) out << indent;
197  out << "channel=" << simphotons.OpChannel() << " has ";
198  if (simphotons.empty()) {
199  out << simphotons.size() << " no photons";
200  }
201  else {
202  out << simphotons.size() << " photons:";
203 
204  auto sortedPhotonPtrs = util::makePointerVector(simphotons);
205  std::sort
206  (sortedPhotonPtrs.begin(), sortedPhotonPtrs.end(), OnePhotonSorter());
207 
208  for (auto const* onephoton: sortedPhotonPtrs) {
209  out << "\n" << indent << " ";
210  DumpOnePhoton(out, *onephoton);
211  } // for
212 
213  }
214 
215 } // sim::DumpSimPhotons::DumpSimPhotons()
216 
217 
218 //------------------------------------------------------------------------------
219 void sim::DumpSimPhotons::analyze(art::Event const& event) {
220 
221  // get the particles from the event
222  auto const& SimPhotons
223  = *(event.getValidHandle<std::vector<sim::SimPhotons>>(fInputPhotons));
224 
225  mf::LogVerbatim(fOutputCategory) << "Event " << event.id()
226  << " : data product '" << fInputPhotons.encode() << "' contains "
227  << SimPhotons.size() << " SimPhotons";
228 
229  unsigned int iPhoton = 0;
230  for (sim::SimPhotons const& photons: SimPhotons) {
231 
232  mf::LogVerbatim log(fOutputCategory);
233  // a bit of a header
234  log << "[#" << (iPhoton++) << "] ";
235  DumpElement(log, photons, " ", false);
236 
237  } // for
238  mf::LogVerbatim(fOutputCategory) << "\n"; // just an empty line
239 
240 } // sim::DumpSimPhotons::analyze()
241 
242 
243 //------------------------------------------------------------------------------
244 DEFINE_ART_MODULE(sim::DumpSimPhotons)
245 
246 //------------------------------------------------------------------------------
process_name opflashCryo1 flashfilter analyze
process_name can override from command line with o or output photon
Definition: runPID.fcl:28
int OpChannel() const
Returns the optical channel number this object is associated to.
Definition: SimPhotons.h:254
void DumpElement(Stream &&out, sim::SimPhotons const &simphotons, std::string indent="", bool bIndentFirst=true) const
Dumps the content of the specified SimPhotons in the output stream.
Silly utility to sort vectors indirectly.
All information of a photon entering the sensitive optical detector volume.
Definition: SimPhotons.h:64
art::InputTag fInputPhotons
name of SimPhotons&#39;s data product
auto makePointerVector(Coll &coll)
Creates a STL vector with pointers to data from another collection.
geo::Point_t InitialPosition
Scintillation position in world coordinates [cm].
Definition: SimPhotons.h:67
process_name gaushit a
Simulation objects for optical detectors.
BEGIN_PROLOG vertical distance to the surface Name
std::string fOutputCategory
name of the stream for output
void DumpOnePhoton(Stream &&out, sim::OnePhoton const &photon) const
Dumps a sim::OnePhoton on a single line.
void analyze(art::Event const &event) override
DumpSimPhotons(Parameters const &config)
Configuration-checking constructor.
Collection of photons which recorded on one channel.
Definition: SimPhotons.h:136
bool SetInSD
Whether the photon reaches the sensitive detector.
Definition: SimPhotons.h:88
geo::OpticalPoint_t FinalLocalPosition
Where photon enters the optical detector in local coordinates [cm].
Definition: SimPhotons.h:75
art::EDAnalyzer::Table< Config > Parameters
float Energy
Scintillation photon energy [GeV].
Definition: SimPhotons.h:82
bnb BNB Stream
int MotherTrackID
ID of the GEANT4 track causing the scintillation.
Definition: SimPhotons.h:85