All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ICARUSMCOpHit_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: ICARUSMCOpHit
3 // Plugin Type: producer (art v3_01_02)
4 // File: ICARUSMCOpHit_module.cc
5 //
6 // Generated at Sun Mar 3 16:52:53 2019 by Kazuhiro Terao using cetskelgen
7 // from cetlib version v3_05_01.
8 ////////////////////////////////////////////////////////////////////////
9 
10 #include "art/Framework/Core/EDProducer.h"
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/Handle.h"
14 #include "art/Framework/Principal/Run.h"
15 #include "art/Framework/Principal/SubRun.h"
16 #include "canvas/Utilities/InputTag.h"
17 #include "fhiclcpp/ParameterSet.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
19 
24 
25 #include <memory>
26 
27 class ICARUSMCOpHit;
28 
29 
30 class ICARUSMCOpHit : public art::EDProducer {
31 public:
32  explicit ICARUSMCOpHit(fhicl::ParameterSet const& p);
33  // The compiler-generated destructor is fine for non-base
34  // classes without bare pointers or other resource use.
35 
36  // Plugins should not be copied or assigned.
37  ICARUSMCOpHit(ICARUSMCOpHit const&) = delete;
38  ICARUSMCOpHit(ICARUSMCOpHit&&) = delete;
39  ICARUSMCOpHit& operator=(ICARUSMCOpHit const&) = delete;
41 
42  // Required functions.
43  void produce(art::Event& e) override;
44 
45 private:
46 
47  // Declare member data here.
48 
49  double _merge_period;
50  std::string _simph_producer;
52 };
53 
54 
55 ICARUSMCOpHit::ICARUSMCOpHit(fhicl::ParameterSet const& p)
56  : EDProducer{p}
57 {
58  _merge_period = p.get<double>("MergePeriod");
59  _simph_producer = p.get<std::string>("SimPhotonsProducer");
60  _spe_area = p.get<double>("SPEArea");
61  _spe_amp = p.get<double>("SPEAmplitude");
62  produces<std::vector<recob::OpHit> >();
63 }
64 
65 void ICARUSMCOpHit::produce(art::Event& e)
66 {
67  auto oph_v = std::unique_ptr<std::vector<recob::OpHit> >(new std::vector<recob::OpHit>());
68 
69  // Get SimPhotons.
70 
71  art::Handle< std::vector< sim::SimPhotons > > simph_h;
72  e.getByLabel(_simph_producer,simph_h);
73 
74  // Get SimPhotonsLite.
75 
76  art::Handle< std::vector< sim::SimPhotonsLite > > simphlite_h;
77  e.getByLabel(_simph_producer,simphlite_h);
78 
79  // At least one, but not both, of the handles should be valid.
80 
81  if(!simph_h.isValid() && !simphlite_h.isValid()) {
82  std::cerr << "Could not retrieve sim::SimPhotons or sim::SimPhotonsLite from producer label: " << _simph_producer << std::endl;
83  throw std::exception();
84  }
85  if(simph_h.isValid() && simphlite_h.isValid()) {
86  std::cerr << "Found both sim::SimPhotons and sim::SimPhotonsLite from producer label: " << _simph_producer << std::endl;
87  throw std::exception();
88  }
89 
90  // Combine the two handles into a single vector so that they can be processed in one loop.
91 
92  typedef std::variant<const sim::SimPhotons*, const sim::SimPhotonsLite*> EitherSimPhoton;
93  std::vector<EitherSimPhoton> sim_photons;
94  if(simph_h.isValid()) {
95  sim_photons.reserve(simph_h->size());
96  for(auto const& simph : *simph_h) {
97  sim_photons.push_back(&simph);
98  }
99  }
100  else if(simphlite_h.isValid()) {
101  sim_photons.reserve(simphlite_h->size());
102  for(auto const& simphlite : *simphlite_h) {
103  sim_photons.push_back(&simphlite);
104  }
105  }
106 
107  // Loop over SimPhotons[Lite]
108 
109  std::vector<bool> processed_v;
110  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
111  for(auto const& simph : sim_photons) {
112  // Make sure channel number is unique (e.g. one sim::SimPhotons per op channel)
113  size_t opch = -1;
114  if(simph_h.isValid())
115  opch = std::get<const sim::SimPhotons*>(simph)->OpChannel();
116  else if(simphlite_h.isValid())
117  opch = std::get<const sim::SimPhotonsLite*>(simph)->OpChannel;
118 
119  if(opch >= processed_v.size()) processed_v.resize(opch+1,false);
120  if(processed_v[opch]) {
121  std::cerr << "Found duplicate channels in std::vector<sim::SimPhotons>! not expected (logic will fail).."<<std::endl;
122  throw std::exception();
123  }
124 
125  processed_v[opch] = true;
126  bool in_window = false;
127  double oph_time = -1.e9;
128  double pe = 0.;
129  // Insert photon times into a sorted set
130  std::map<double,size_t> time_m;
131  if(simph_h.isValid()) {
132  for(auto const& oneph : *std::get<const sim::SimPhotons*>(simph)) {
133  double this_time = clockData.G4ToElecTime(oneph.Time) - clockData.TriggerTime();
134  time_m[this_time] += 1;
135  }
136  }
137  else if(simphlite_h.isValid()) {
138  for(auto const& [ time_ns, nphotons ] : std::get<const sim::SimPhotonsLite*>(simph)->DetectedPhotons) {
139  double this_time = clockData.G4ToElecTime(time_ns + 0.5) - clockData.TriggerTime();
140  time_m[this_time] += nphotons;
141  }
142  }
143 
144  // Loop over the time vector, emplace photons
145  for(auto const& time_photon_pair : time_m) {
146 
147  auto const& this_time = time_photon_pair.first;
148 
149  if(this_time > (oph_time + _merge_period) && in_window) {
150  recob::OpHit oph(opch,
151  oph_time,
152  oph_time + clockData.TriggerTime(),
153  0, // frame
154  1., // width
155  pe * _spe_area, // area,
156  pe * _spe_amp, // peakheight,
157  pe, // pe
158  0.);
159  oph_v->emplace_back(std::move(oph));
160  in_window = false;
161  pe = 0;
162  }
163 
164  if(!in_window) oph_time = this_time;
165  in_window = true;
166  pe += time_photon_pair.second;
167  }
168  if(in_window) {
169  recob::OpHit oph(opch,
170  oph_time,
171  oph_time + clockData.TriggerTime(),
172  0, // frame
173  1., // width
174  pe * _spe_area, // area,
175  pe * _spe_amp, // peakheight,
176  pe, // pe
177  0.);
178  oph_v->emplace_back(std::move(oph));
179  }
180  }
181 
182  e.put(std::move(oph_v));
183 }
184 
185 DEFINE_ART_MODULE(ICARUSMCOpHit)
BEGIN_PROLOG could also be cerr
pdgs p
Definition: selectors.fcl:22
std::string _simph_producer
Simulation objects for optical detectors.
ICARUSMCOpHit(fhicl::ParameterSet const &p)
do i e
void produce(art::Event &e) override
art framework interface to geometry description
ICARUSMCOpHit & operator=(ICARUSMCOpHit const &)=delete