All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ICARUSMCOpFlash_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: ICARUSMCOpFlash
3 // Plugin Type: producer (art v3_01_02)
4 // File: ICARUSMCOpFlash_module.cc
5 //
6 // Generated at Sun Mar 3 17:53:36 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 
20 #include "nusimdata/SimulationBase/MCTruth.h"
24 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
27 
28 #include <memory>
29 
30 class ICARUSMCOpFlash;
31 
32 
33 class ICARUSMCOpFlash : public art::EDProducer {
34 public:
35  explicit ICARUSMCOpFlash(fhicl::ParameterSet const& p);
36  // The compiler-generated destructor is fine for non-base
37  // classes without bare pointers or other resource use.
38 
39  // Plugins should not be copied or assigned.
40  ICARUSMCOpFlash(ICARUSMCOpFlash const&) = delete;
41  ICARUSMCOpFlash(ICARUSMCOpFlash&&) = delete;
42  ICARUSMCOpFlash& operator=(ICARUSMCOpFlash const&) = delete;
44 
45  // Required functions.
46  void produce(art::Event& e) override;
47 
48 private:
49 
50  void GetFlashLocation(std::vector<double> pePerOpChannel,
51  double& Ycenter,
52  double& Zcenter,
53  double& Ywidth,
54  double& Zwidth) const;
55 
56  // Declare member data here.
57  double _merge_period;
58  double _pe_threshold;
60  std::string _hit_label;
61  std::string _mct_label;
62  std::vector<bool> _enabled_opch_v;
63 };
64 
65 
66 ICARUSMCOpFlash::ICARUSMCOpFlash(fhicl::ParameterSet const& p)
67  : EDProducer{p} // ,
68  // More initializers here.
69 {
70  _pe_threshold = p.get<double>("PEThresholdHit",0.5);
71  _store_empty_flash = p.get<bool>("StoreEmptyFlash",false);
72  _mct_label = p.get<std::string>("MCTruthProducer");
73  _hit_label = p.get<std::string>("OpHitProducer");
74  _merge_period = p.get<double>("MergePeriod");
75  _enabled_opch_v.clear();
76  std::vector<size_t> enabled_ch_v;
77  enabled_ch_v = p.get<std::vector<size_t> >("OpChannel",enabled_ch_v);
78  if(enabled_ch_v.empty()) {
79  auto opch_range = p.get<std::vector<size_t> >("OpChannelRange");
80  if(opch_range.size()!=2) {
81  std::cerr << "OpChannelRange must be a vector of length two!" << std::endl;
82  throw std::exception();
83  }else if(opch_range[0] > opch_range[1]) {
84  std::cerr << "OpChannelRange 0th element (" << opch_range[0]
85  << ") must be larger than the 1st element (" << opch_range[1]
86  << ")" << std::endl;
87  throw std::exception();
88  }
89  for(size_t opch=opch_range[0]; opch<=opch_range[1]; ++opch)
90  enabled_ch_v.push_back(opch);
91  }
92  for(auto const& opch : enabled_ch_v) {
93  if(_enabled_opch_v.size() <= opch) _enabled_opch_v.resize(opch+1,false);
94  _enabled_opch_v[opch] = true;
95  }
96 
97  produces<std::vector<recob::OpFlash> >();
98 }
99 
100 void ICARUSMCOpFlash::produce(art::Event& e)
101 {
102  auto const geop = lar::providerFrom<geo::Geometry>();
103  auto opf_v = std::unique_ptr<std::vector<recob::OpFlash> >(new std::vector<recob::OpFlash>());
104 
105  art::Handle< std::vector< simb::MCTruth > > mct_h;
106  e.getByLabel(_mct_label,mct_h);
107  if(!mct_h.isValid()) {
108  std::cerr << "std::vector<simb::MCTruth> could not be found with a label: " << _mct_label << std::endl;
109  throw std::exception();
110  }
111 
112  art::Handle< std::vector< recob::OpHit > > oph_h;
113  e.getByLabel(_hit_label,oph_h);
114  if(!oph_h.isValid()) {
115  std::cerr << "std::vector<recob::OpHit> could not be found with a label: " << _hit_label << std::endl;
116  throw std::exception();
117  }
118 
119  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
120  std::set<double> flash_time_s;
121  for(auto const& mct : *mct_h) {
122  for(int i=0; i<mct.NParticles(); ++i) {
123  auto const& part = mct.GetParticle(i);
124  if( (int)(part.StatusCode()) != 1 ) continue;
125  double flash_time = clockData.G4ToElecTime(part.T()) - clockData.TriggerTime();
126  flash_time_s.insert(flash_time);
127  }
128  }
129  std::vector<double> flash_time_v;
130  flash_time_v.reserve(flash_time_s.size());
131  double last_time = -1.1e20;
132  for(auto const& time : flash_time_s) {
133  if(time > (last_time + _merge_period)) flash_time_v.push_back(time);
134  last_time = time;
135  }
136 
137  for(auto const& flash_time : flash_time_v) {
138  std::vector<double> pe_v(geop->NOpChannels(),0.);
139  double pe_total=-1.;
140  double pe_sum=0.;
141  double pe_sum1=0.;
142  double pe_sum2=0.;
143  for(auto const& oph : *oph_h) {
144  auto opch = oph.OpChannel();
145  if(oph.PE()<_pe_threshold) continue;
146  pe_sum += oph.PE();
147  if((int)(_enabled_opch_v.size()) <= opch || !_enabled_opch_v[opch]) continue;
148  pe_sum1 += oph.PE();
149  if(oph.PeakTime() < flash_time || oph.PeakTime() > (flash_time + _merge_period)) {
150  /*
151  std::cout << "Ch " << opch << " Time: " << oph.PeakTime()
152  << " PE " << oph.PE()
153  << " ... dt " << oph.PeakTime() - flash_time <<std::endl;
154  */
155  continue;
156  }
157  pe_sum2 += oph.PE();
158  pe_v[opch] += oph.PE();
159  pe_total = (pe_total < 0. ? oph.PE() : pe_total + oph.PE());
160  }
161  //std::cout<<"PE sum " << pe_sum << " " << pe_sum1 << " " << pe_sum2 << std::endl;
162  if(pe_total < 0. && !_store_empty_flash) continue;
163  double y,z,ywidth,zwidth;
164  GetFlashLocation(pe_v,y,z,ywidth,zwidth);
165  recob::OpFlash f(flash_time, _merge_period, flash_time + clockData.TriggerTime(), 0,
166  pe_v, false, 0, 0, 0, 0, 0, 0);
167  opf_v->emplace_back(std::move(f));
168  }
169  e.put(std::move(opf_v));
170 }
171 
172 void ICARUSMCOpFlash::GetFlashLocation(std::vector<double> pePerOpChannel,
173  double& Ycenter,
174  double& Zcenter,
175  double& Ywidth,
176  double& Zwidth) const
177 {
178 
179  // Reset variables
180  auto const geop = lar::providerFrom<geo::Geometry>();
181  Ycenter = Zcenter = -1.e20;
182  Ywidth = Zwidth = -1.e20;
183  double totalPE = 0.;
184  double sumy = 0., sumz = 0., sumy2 = 0., sumz2 = 0.;
185 
186  for (unsigned int opch = 0; opch < pePerOpChannel.size(); opch++) {
187 
188  // Get physical detector location for this opChannel
189  double PMTxyz[3];
190  geop->OpDetGeoFromOpChannel(opch).GetCenter(PMTxyz);
191 
192  // Add up the position, weighting with PEs
193  sumy += pePerOpChannel[opch]*PMTxyz[1];
194  sumy2 += pePerOpChannel[opch]*PMTxyz[1]*PMTxyz[1];
195  sumz += pePerOpChannel[opch]*PMTxyz[2];
196  sumz2 += pePerOpChannel[opch]*PMTxyz[2]*PMTxyz[2];
197 
198  totalPE += pePerOpChannel[opch];
199  }
200 
201  Ycenter = sumy/totalPE;
202  Zcenter = sumz/totalPE;
203 
204  // This is just sqrt(<x^2> - <x>^2)
205  if ( (sumy2*totalPE - sumy*sumy) > 0. )
206  Ywidth = std::sqrt(sumy2*totalPE - sumy*sumy)/totalPE;
207 
208  if ( (sumz2*totalPE - sumz*sumz) > 0. )
209  Zwidth = std::sqrt(sumz2*totalPE - sumz*sumz)/totalPE;
210 }
211 
212 DEFINE_ART_MODULE(ICARUSMCOpFlash)
ICARUSMCOpFlash(fhicl::ParameterSet const &p)
process_name opflash particleana ie ie ie z
Utilities related to art service access.
BEGIN_PROLOG could also be cerr
pdgs p
Definition: selectors.fcl:22
ICARUSMCOpFlash & operator=(ICARUSMCOpFlash const &)=delete
void GetFlashLocation(std::vector< double > pePerOpChannel, double &Ycenter, double &Zcenter, double &Ywidth, double &Zwidth) const
void produce(art::Event &e) override
Simulation objects for optical detectors.
process_name opflash particleana ie ie y
do i e
art framework interface to geometry description
std::vector< bool > _enabled_opch_v