All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FakeFlash_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: FakeFlash
3 // Plugin Type: producer (art v3_01_01)
4 // File: FakeFlash_module.cc
5 //
6 // Generated at Tue Feb 12 13:46:25 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 "CLHEP/Random/RandFlat.h"
17 #include "CLHEP/Random/RandPoisson.h"
18 #include "CLHEP/Random/RandExponential.h"
19 #include "TRandom.h"
20 #include "nurandom/RandomUtils/NuRandomService.h"
21 #include "canvas/Utilities/InputTag.h"
22 #include "fhiclcpp/ParameterSet.h"
23 #include "messagefacility/MessageLogger/MessageLogger.h"
28 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
30 
31 #include "nusimdata/SimulationBase/MCTruth.h"
32 #include "nusimdata/SimulationBase/MCParticle.h"
33 
34 #include <memory>
35 #include <TLorentzVector.h>
36 
37 class FakeFlash;
38 
39 
40 class FakeFlash : public art::EDProducer {
41 public:
42  explicit FakeFlash(fhicl::ParameterSet const& p);
43  // The compiler-generated destructor is fine for non-base
44  // classes without bare pointers or other resource use.
45 
46  // Plugins should not be copied or assigned.
47  FakeFlash(FakeFlash const&) = delete;
48  FakeFlash(FakeFlash&&) = delete;
49  FakeFlash& operator=(FakeFlash const&) = delete;
50  FakeFlash& operator=(FakeFlash&&) = delete;
51 
52  // Required functions.
53  void produce(art::Event& e) override;
54  void beginRun(art::Run& run) override;
55 private:
56 
57  void GenPosition(double& x, double& y, double& z);
58  void FillSimPhotons(std::vector<sim::SimPhotons>& simph_v,
59  int nphotons,
60  size_t mother_trackid,
61  const TLorentzVector& pos);
62  std::vector<double> GenerateTime(size_t numphotons);
63  // Declare member data here.
64  bool _verbose; ///< verbosity for debugging
65  double _frequency; ///< [MHz]
66  double _duration; ///< [us]
67  double _tstart; ///< [ns]
68  size_t _min_photons; ///< [photons]
69  size_t _max_photons; ///< [photons]
70  std::vector<size_t> _tpc_v; ///< List of TPC ID to be used
71  double _fast_frac; ///< fraction of prompt light
72  double _fast_tau; ///< scintillation emission time constant for fast component
73  double _slow_tau; ///< scintillation emission time constant for slow component
74  size_t _ch_min; ///< channel range min to produce SimPhotons
75  size_t _ch_max; ///< channel range max to produce SimPhotons
76  double _xmax; ///< 0.0-1.0 the x-position range in fraction of a TPC volume
77  double _ymax; ///< 0.0-1.0 the y-position range in fraction of a TPC volume
78  double _zmax; ///< 0.0-1.0 the z-position range in fraction of a TPC volume
79  double _xmin; ///< 0.0-1.0 the x-position range in fraction of a TPC volume
80  double _ymin; ///< 0.0-1.0 the y-position range in fraction of a TPC volume
81  double _zmin; ///< 0.0-1.0 the z-position range in fraction of a TPC volume
82  CLHEP::HepRandomEngine& fFlatEngine;
83  CLHEP::RandFlat *fFlatRandom;
84  CLHEP::RandExponential* fExpoRandom;
85  CLHEP::RandPoisson* fPoisRandom;
86 };
87 
88 
89 FakeFlash::FakeFlash(fhicl::ParameterSet const& p)
90  : EDProducer{p}
91  , fFlatEngine(art::ServiceHandle<rndm::NuRandomService>()->createEngine(*this, "HepJamesRandom", "Gen", p, "Seed"))
92  // More initializers here.
93 {
94  _verbose = p.get<bool>("Verbose",false); // If you want someone to talk to you
95  auto min_photons = p.get<int>("MinPhotons",24000); // Min of the range of photons to be injected in one shot
96  auto max_photons = p.get<int>("MaxPhotons",2400000); // Max of the range of photons to be injected in one shot
97  assert(min_photons < max_photons && min_photons>0 && max_photons>0);
98  _min_photons = min_photons;
99  _max_photons = max_photons;
100 
101  // scintillation params (yeah fine you can replace these w/ service)
102  _fast_frac = p.get<double>("PromptLightFraction",0.23);
103  _fast_tau = p.get<double>("FastTimeConstant",0.006);
104  _slow_tau = p.get<double>("SlowTimeConstant",1.5);
105 
106  // channel range to simulate
107  auto geop = lar::providerFrom<geo::Geometry>();
108  _ch_min = 0;
109  _ch_max = geop->NOpChannels() - 1;
110  _ch_min = p.get<size_t>("ChannelMin",_ch_min);
111  _ch_max = p.get<size_t>("ChannelMax",_ch_max);
112  assert(_ch_min<_ch_max);
113  // Given in micro-seconds as larsoft default time unit, but then we convert to ns to record as photon time
114  _fast_tau *= 1.e3;
115  _slow_tau *= 1.e3;
116  // TPC list + range
117  _tpc_v = p.get<std::vector<size_t> >("TPCList"); // The list of TPC in which flash can happen
118  _xmax = p.get<double>("XMax",1.0);
119  _xmin = p.get<double>("XMin",0.0);
120  _ymax = p.get<double>("YMax",1.0);
121  _ymin = p.get<double>("YMin",0.0);
122  _zmax = p.get<double>("ZMax",1.0);
123  _zmin = p.get<double>("ZMin",0.0);
124  assert(_xmax>=_xmin && _ymax>=_ymin && _zmax>=_zmin &&
125  _xmax<=1.0 && _ymax<=1.0 && _zmax<=1.0 &&
126  _xmin>=0.0 && _ymin>=0.0 && _zmin>=0.0 );
127  // generation timing info
128  _frequency = p.get<double>("Frequency"); // The frequency of photon(s) injection
129  _duration = p.get<double>("Duration"); // The duration of photon(s) injection period
130  _tstart = p.get<double>("G4TStart"); // The start time of photon injection period
131  produces<std::vector<sim::SimPhotons> >();
132  produces<std::vector<simb::MCTruth> >();
133  produces< sumdata::RunData, art::InRun >();
134 
135  fFlatRandom = new CLHEP::RandFlat(fFlatEngine,0,1);
136  fExpoRandom = new CLHEP::RandExponential(fFlatEngine);
137  fPoisRandom = new CLHEP::RandPoisson(fFlatEngine);
138 }
139 
140 void FakeFlash::beginRun(art::Run& run)
141 {
142  // grab the geometry object to see what geometry we are using
143  art::ServiceHandle<geo::Geometry> geo;
144 
145  std::unique_ptr<sumdata::RunData> runData(new sumdata::RunData(geo->DetectorName()));
146 
147  run.put(std::move(runData));
148 
149  return;
150 }
151 
152 void FakeFlash::GenPosition(double& x, double& y, double& z) {
153 
154  size_t tpc_id = (size_t)(fFlatRandom->fire(0,_tpc_v.size()));
155  bool found = false;
156  // Implementation of required member function here.
157  auto geop = lar::providerFrom<geo::Geometry>();
158  for(size_t c=0; c<geop->Ncryostats(); ++c) {
159  auto const& cryostat = geop->Cryostat(c);
160  if(!cryostat.HasTPC(tpc_id)) continue;
161  auto const& tpc = cryostat.TPC(tpc_id);
162  auto const& tpcabox = tpc.ActiveBoundingBox();
163  double xmin = tpcabox.MinX() + (tpcabox.MaxX() - tpcabox.MinX()) * _xmin;
164  double xmax = tpcabox.MinX() + (tpcabox.MaxX() - tpcabox.MinX()) * _xmax;
165  double ymin = tpcabox.MinY() + (tpcabox.MaxY() - tpcabox.MinY()) * _ymin;
166  double ymax = tpcabox.MinY() + (tpcabox.MaxY() - tpcabox.MinY()) * _ymax;
167  double zmin = tpcabox.MinZ() + (tpcabox.MaxZ() - tpcabox.MinZ()) * _zmin;
168  double zmax = tpcabox.MinZ() + (tpcabox.MaxZ() - tpcabox.MinZ()) * _zmax;
169  x = fFlatRandom->fire(xmin,xmax);
170  y = fFlatRandom->fire(ymin,ymax);
171  z = fFlatRandom->fire(zmin,zmax);
172  found = true;
173  break;
174  }
175  if(!found) std::cerr<< "\033[93mTPC " << tpc_id << " not found...\033[00m" << std::endl;
176 }
177 
178 void FakeFlash::FillSimPhotons(std::vector<sim::SimPhotons>& simph_v,
179  int mother_trackid,
180  size_t nphotons,
181  const TLorentzVector& pos)
182 {
183  art::ServiceHandle<phot::PhotonVisibilityService const> pvs;
184  double xyz[3];
185  xyz[0] = pos.X();
186  xyz[1] = pos.Y();
187  xyz[2] = pos.Z();
188  auto const& Visibilities = pvs->GetAllVisibilities(xyz);
189  // Now loop over optical channels and fill SimPhotons array
190  if(simph_v.empty()) {
191  for(size_t opch=_ch_min; opch<=_ch_max; ++opch)
192  simph_v.push_back(sim::SimPhotons(opch));
193  }
194  for(size_t opch=_ch_min; opch <= _ch_max; ++opch) {
195  // get visibility
196  size_t detected = fPoisRandom->fire((double)(nphotons) * Visibilities[opch]);
197  //std::cout<<opch<<","<<detected<<std::endl;
198  auto time_array = this->GenerateTime(detected);
199  assert(time_array.size() == detected);
200  // record
201  auto& simph = simph_v[opch];
202  for(size_t idx=0; idx<detected; ++idx) {
203  sim::OnePhoton phot;
204  phot.Time = pos.T() + time_array[idx];
205  phot.InitialPosition.SetX(pos.X());
206  phot.InitialPosition.SetY(pos.Y());
207  phot.InitialPosition.SetZ(pos.Z());
208  phot.MotherTrackID = mother_trackid;
209  simph.emplace_back(phot);
210  }
211  }
212 }
213 
214 std::vector<double> FakeFlash::GenerateTime(size_t numphotons) {
215 
216  std::vector<double> res(numphotons);
217  for(int i=0; i<((int)numphotons); ++i) {
218  if(fFlatRandom->fire(0.,1.) < _fast_frac)
219  res[i] = fExpoRandom->fire(_fast_tau);
220  else res[i] = fExpoRandom->fire(_slow_tau);
221  }
222  return res;
223 }
224 
225 void FakeFlash::produce(art::Event& e)
226 {
227 
228  auto simph_v = std::unique_ptr<std::vector<sim::SimPhotons> >(new std::vector<sim::SimPhotons>());
229  auto mct_v = std::unique_ptr<std::vector<simb::MCTruth> >(new std::vector<simb::MCTruth>());
230  std::vector<simb::MCParticle> mcp_v;
231  double clock = 0.;
232  while(clock <= _duration) {
233  // Determine photon count
234  int nphotons = _min_photons + (_max_photons - _min_photons) * (fFlatRandom->fire(0,1));
235 
236  // Generate position 4 vector
237  double time = _tstart + clock * 1.e3;
238  double x,y,z;
239  this->GenPosition(x,y,z);
240  TLorentzVector pos(x,y,z,time);
241 
242  // Fill SimPhotons
243  this->FillSimPhotons(*simph_v, (int)(mcp_v.size()), nphotons, pos);
244 
245  // Record a fake photon particle
246  simb::MCParticle part(mcp_v.size(), 22, "primary", 0, 0., 1);
247  TLorentzVector mom(0.,0.,0.,(double)nphotons);
248  part.AddTrajectoryPoint(pos,mom);
249  mcp_v.emplace_back(std::move(part));
250 
251  // count time
252  clock += (1./_frequency);
253  }
254 
255  simb::MCTruth mct;
256  for(auto& part : mcp_v)
257  mct.Add(part);
258  mct_v->emplace_back(std::move(mct));
259 
260  e.put(std::move(simph_v));
261  e.put(std::move(mct_v));
262 }
263 
264 DEFINE_ART_MODULE(FakeFlash)
FakeFlash(fhicl::ParameterSet const &p)
process_name opflash particleana ie ie ie z
CLHEP::HepRandomEngine & fFlatEngine
Utilities related to art service access.
double _frequency
[MHz]
double _zmax
0.0-1.0 the z-position range in fraction of a TPC volume
std::vector< size_t > _tpc_v
List of TPC ID to be used.
double _fast_frac
fraction of prompt light
process_name opflash particleana ie x
BEGIN_PROLOG could also be cerr
double _slow_tau
scintillation emission time constant for slow component
CLHEP::RandExponential * fExpoRandom
pdgs p
Definition: selectors.fcl:22
All information of a photon entering the sensitive optical detector volume.
Definition: SimPhotons.h:64
size_t _ch_max
channel range max to produce SimPhotons
CLHEP::RandFlat * fFlatRandom
std::vector< double > GenerateTime(size_t numphotons)
FakeFlash & operator=(FakeFlash const &)=delete
double _fast_tau
scintillation emission time constant for fast component
bool _verbose
verbosity for debugging
geo::Point_t InitialPosition
Scintillation position in world coordinates [cm].
Definition: SimPhotons.h:67
process_name pandoraGausCryo1 vertexChargeCryo1 vertexStubCryo1 xmin
double _zmin
0.0-1.0 the z-position range in fraction of a TPC volume
Simulation objects for optical detectors.
double _ymax
0.0-1.0 the y-position range in fraction of a TPC volume
process_name opflash particleana ie ie y
double _ymin
0.0-1.0 the y-position range in fraction of a TPC volume
size_t _max_photons
[photons]
double _xmin
0.0-1.0 the x-position range in fraction of a TPC volume
void beginRun(art::Run &run) override
double _xmax
0.0-1.0 the x-position range in fraction of a TPC volume
double _tstart
[ns]
size_t _ch_min
channel range min to produce SimPhotons
void FillSimPhotons(std::vector< sim::SimPhotons > &simph_v, int nphotons, size_t mother_trackid, const TLorentzVector &pos)
CLHEP::RandPoisson * fPoisRandom
double _duration
[us]
Collection of photons which recorded on one channel.
Definition: SimPhotons.h:136
createEngine fFlatRandom
do i e
void produce(art::Event &e) override
void GenPosition(double &x, double &y, double &z)
size_t _min_photons
[photons]
art framework interface to geometry description
int MotherTrackID
ID of the GEANT4 track causing the scintillation.
Definition: SimPhotons.h:85