PDFastSimPVS_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: PDFastSimPVS
3 // Plugin Type: producer
4 // File: PDFastSimPVS_module.cc
5 // Description:
6 // - acts on sim::SimEnergyDeposit from LArG4Main,
7 // - simulate (fast, photon visibility service) the OpDet response to optical photons
8 // Input: 'sim::SimEnergyDeposit'
9 // Output: 'sim::OpDetBacktrackerRecord'
10 //Fast simulation of propagating the photons created from SimEnergyDeposits.
11 
12 //This module does a fast simulation of propagating the photons created from SimEnergyDeposits,
13 //This simulation is done using the PhotonLibrary, which stores the visibilities of each optical channel
14 //with respect to each optical voxel in the TPC volume, to avoid propagating single photons using Geant4.
15 //At the end of this module a collection of the propagated photons either as
16 //'sim::OpDetBacktrackerRecord' are placed into the art event.
17 
18 //The steps this module takes are:
19 // - to take number of photon and the vertex information from 'sim::SimEnergyDeposits',
20 // - use the PhotonLibrary (visibilities) to determine the amount of visible photons at each optical channel,
21 // - visible photons: the number of photons times the visibility at the middle of the Geant4 step for a given optical channel.
22 // - other photon information is got from 'sim::SimEnergyDeposits'
23 // - add 'sim::OpDetBacktrackerRecord' to event
24 // Aug. 19 by Mu Wei
25 // Restructured Nov. 21 by P. Green
26 ////////////////////////////////////////////////////////////////////////
27 
28 // Art libraries
38 #include "nurandom/RandomUtils/NuRandomService.h"
39 #include "fhiclcpp/ParameterSet.h"
40 
41 // LArSoft libraries
51 
52 // Random number engine
53 #include "CLHEP/Random/RandFlat.h"
54 #include "CLHEP/Random/RandPoissonQ.h"
55 
56 #include <memory>
57 #include <vector>
58 
59 namespace phot
60 {
62  {
63  public:
64  explicit PDFastSimPVS(fhicl::ParameterSet const&);
65  void produce(art::Event&) override;
66  void AddOpDetBTR(std::vector< sim::OpDetBacktrackerRecord > & opbtr,
67  std::map<int, int> & ChannelMap,
69 
70  private:
74  std::unique_ptr<ScintTime> fScintTime; // Tool to retrive timing of scintillation
75  CLHEP::HepRandomEngine& fPhotonEngine;
76  CLHEP::HepRandomEngine& fScintTimeEngine;
77  std::map<int, int> PDChannelToSOCMapDirect; // Where each OpChan is.
78  std::map<int, int> PDChannelToSOCMapReflect; // Where each OpChan is.
79 
80  // propagation time model
81  std::unique_ptr<PropagationTimeModel> fPropTimeModel;
82 
85 
87  };
88 
89  //......................................................................
91  : art::EDProducer{pset}
92  , fDoFastComponent(pset.get<bool>("DoFastComponent", true))
93  , fDoSlowComponent(pset.get<bool>("DoSlowComponent", true))
94  , simTag{pset.get<art::InputTag>("SimulationLabel")}
95  , fScintTime{art::make_tool<ScintTime>(pset.get<fhicl::ParameterSet>("ScintTimeTool"))}
96  , fPhotonEngine(art::ServiceHandle<rndm::NuRandomService>{}->createEngine(*this, "HepJamesRandom", "photon", pset, "SeedPhoton"))
97  , fScintTimeEngine(art::ServiceHandle<rndm::NuRandomService>()->createEngine(*this, "HepJamesRandom", "scinttime", pset, "SeedScintTime"))
98  , fIncludePropTime(pset.get<bool>("IncludePropTime", false))
99  {
100  std::cout << "PDFastSimPVS Module Construct" << std::endl;
101 
104  if (lgp->UseLitePhotons())
105  {
106  std::cout << "Use Lite Photon." << std::endl;
107  produces< std::vector<sim::SimPhotonsLite> >();
108  produces< std::vector<sim::OpDetBacktrackerRecord> >();
109 
110  if(pvs->StoreReflected())
111  {
112  std::cout << "Store Reflected Photons" << std::endl;
113  produces< std::vector<sim::SimPhotonsLite> >("Reflected");
114  produces< std::vector<sim::OpDetBacktrackerRecord> >("Reflected");
115  }
116  }
117  else
118  {
119  std::cout << "Use Sim Photon." << std::endl;
120  produces< std::vector<sim::SimPhotons> >();
121  if(pvs->StoreReflected())
122  {
123  std::cout << "Store Reflected Photons" << std::endl;
124  produces< std::vector<sim::SimPhotons> >("Reflected");
125  }
126  }
127 
128  // Propagation times
129  // validate configuration
130  if(fIncludePropTime && !pset.get_if_present<fhicl::ParameterSet>("VUVTiming", fVUVTimingParams))
131  {
133  << "Propagation time simulation requested, but VUVTiming not specified." << "\n";
134  }
135 
136  if (pvs->StoreReflected() && fIncludePropTime && !pset.get_if_present<fhicl::ParameterSet>("VISTiming", fVISTimingParams))
137  {
139  << "Reflected light propagation time simulation requested, but VISTiming not specified." << "\n";
140  }
141 
142  // construct propagation time class
143  if (fIncludePropTime) fPropTimeModel = std::make_unique<PropagationTimeModel>(fVUVTimingParams, fVISTimingParams, fScintTimeEngine, pvs->StoreReflected());
144  }
145 
146  //......................................................................
148  {
149  std::cout << "PDFastSimPVS Module Producer" << std::endl;
150 
153  auto const nOpChannels = pvs->NOpChannels();
154 
155  CLHEP::RandPoissonQ randpoisphot{fPhotonEngine};
156 
157  std::unique_ptr< std::vector< sim::SimPhotons > > phot (new std::vector<sim::SimPhotons>);
158  std::unique_ptr< std::vector< sim::SimPhotonsLite > > phlit (new std::vector<sim::SimPhotonsLite>);
159  std::unique_ptr< std::vector< sim::OpDetBacktrackerRecord > > opbtr (new std::vector<sim::OpDetBacktrackerRecord>);
160 
161  std::unique_ptr< std::vector< sim::SimPhotons > > phot_ref (new std::vector<sim::SimPhotons>);
162  std::unique_ptr< std::vector< sim::SimPhotonsLite > > phlit_ref (new std::vector<sim::SimPhotonsLite>);
163  std::unique_ptr< std::vector< sim::OpDetBacktrackerRecord > > opbtr_ref (new std::vector<sim::OpDetBacktrackerRecord>);
164 
165  auto& dir_photcol(*phot);
166  auto& ref_photcol(*phot_ref);
167  auto& dir_phlitcol(*phlit);
168  auto& ref_phlitcol(*phlit_ref);
169  dir_photcol.resize(nOpChannels);
170  ref_photcol.resize(nOpChannels);
171  dir_phlitcol.resize(nOpChannels);
172  ref_phlitcol.resize(nOpChannels);
173  for (unsigned int i = 0; i < nOpChannels; i ++) {
174  dir_photcol[i].fOpChannel = i;
175  ref_photcol[i].fOpChannel = i;
176  dir_phlitcol[i].OpChannel = i;
177  ref_phlitcol[i].OpChannel = i;
178  }
179 
181  if (!event.getByLabel(simTag, edepHandle))
182  {
183  std::cout << "PDFastSimPVS Module Cannot getByLabel: " << simTag << std::endl;
184  return;
185  }
186  else
187  {
188  std::cout << "PDFastSimPVS Module getByLabel: " << simTag << std::endl;
189  }
190 
191  auto const& edeps = edepHandle;
192 
193  int num_points = 0;
194 
195  for (auto const& edepi: *edeps) {
196  num_points ++;
197 
198  MappedCounts_t Visibilities;
199  MappedCounts_t Visibilities_Ref;
200 
201  auto const& prt = edepi.MidPoint();
202  Visibilities = pvs->GetAllVisibilities(prt);
203  if(pvs->StoreReflected()) {
204  Visibilities_Ref = pvs->GetAllVisibilities(prt, true);
205  if(!Visibilities_Ref) std::cout << "Fail to get visibilities for reflected photons." << std::endl;
206  }
207 
208  if(!Visibilities)
209  {
210  //throw cet::exception("PDFastSimPVS")
211  std::cout << "There is no entry in the PhotonLibrary for this position in space. Position: " << edepi.MidPoint();
212  std::cout << "\n Move to next point" << std::endl;
213  continue;
214  }
215 
216  int trackID = edepi.TrackID();
217  int nphot = edepi.NumPhotons();
218  double edeposit = edepi.Energy()/nphot;
219  double pos[3] = {edepi.MidPointX(), edepi.MidPointY(), edepi.MidPointZ()};
220  int nphot_fast = edepi.NumFPhotons();
221  int nphot_slow = edepi.NumSPhotons();
222 
223  // propagation time
224  std::vector<double> transport_time;
225 
226  geo::Point_t const ScintPoint = {pos[0], pos[1], pos[2]};
227 
228  // loop through direct photons then reflected photons cases
229  for (size_t Reflected = 0; Reflected <= 1; ++Reflected) {
230 
231  // only do the reflected loop if including reflected light
232  if (Reflected && !pvs->StoreReflected()) continue;
233 
234  // loop over each photo-detector
235  for (unsigned int channel = 0; channel < nOpChannels; ++ channel) {
236 
237  // visibility
238  double visibleFraction;
239  if (Reflected) visibleFraction = Visibilities_Ref[channel];
240  else visibleFraction = Visibilities[channel];
241 
242  if (visibleFraction == 0.0) continue; // voxel is not visible at this optical channel
243 
244  // number of detected photons
245  int ndetected_fast = 0;
246  int ndetected_slow = 0;
247 
248  if (nphot_fast > 0) ndetected_fast = static_cast<int>(randpoisphot.fire(nphot_fast * visibleFraction));
249  if (nphot_slow > 0) ndetected_slow = static_cast<int>(randpoisphot.fire(nphot_slow * visibleFraction));
250 
251  // calculate propagation times if included, does not matter whether fast or slow photon
252  if (fIncludePropTime) {
253  transport_time.resize(ndetected_fast + ndetected_slow);
254  fPropTimeModel->propagationTime(transport_time, ScintPoint, channel, Reflected);
255  }
256 
257  // SimPhotonsLite case
258  if (lgp->UseLitePhotons()) {
259 
261 
262  if (ndetected_fast > 0 && fDoFastComponent) {
263  for (long i = 0; i < ndetected_fast; ++i) {
264  // calculate the time at which each photon is seen
265  fScintTime->GenScintTime(true, fScintTimeEngine);
266  int time;
267  if (fIncludePropTime) time = static_cast<int>(edepi.StartT() + fScintTime->GetScintTime() + transport_time[i]);
268  else time = static_cast<int>(edepi.StartT() + fScintTime->GetScintTime());
269  if (Reflected) ++ref_phlitcol[channel].DetectedPhotons[time];
270  else ++dir_phlitcol[channel].DetectedPhotons[time];
271  tmpbtr.AddScintillationPhotons(trackID, time, 1, pos, edeposit);
272  }
273  }
274 
275  if ((ndetected_slow > 0) && fDoSlowComponent) {
276  for (long i = 0; i < ndetected_slow; ++i) {
277  // calculate the time at which each photon is seen
278  fScintTime->GenScintTime(false, fScintTimeEngine);
279  int time;
280  if (fIncludePropTime) time = static_cast<int>(edepi.StartT() + fScintTime->GetScintTime() + transport_time[ndetected_fast + i]);
281  else time = static_cast<int>(edepi.StartT() + fScintTime->GetScintTime());
282  if (Reflected) ++ref_phlitcol[channel].DetectedPhotons[time];
283  else ++dir_phlitcol[channel].DetectedPhotons[time];
284  tmpbtr.AddScintillationPhotons(trackID, time, 1, pos, edeposit);
285  }
286  }
287 
288  if (Reflected) AddOpDetBTR(*opbtr_ref, PDChannelToSOCMapReflect, tmpbtr);
289  else AddOpDetBTR(*opbtr, PDChannelToSOCMapDirect, tmpbtr);
290  }
291 
292  // SimPhotons case
293  else {
294 
295  sim::OnePhoton photon;
296  photon.SetInSD = false;
297  photon.InitialPosition = edepi.End();
298  if (Reflected) photon.Energy = 2.9 * CLHEP::eV; // 430 nm
299  else photon.Energy = 9.7 * CLHEP::eV; // 128 nm
300 
301  if (ndetected_fast > 0 && fDoFastComponent) {
302  for (long i = 0; i < ndetected_fast; ++i) {
303  // calculates the time at which the photon was produced
304  fScintTime->GenScintTime(true, fScintTimeEngine);
305  int time;
306  if (fIncludePropTime) time = static_cast<int>(edepi.StartT() + fScintTime->GetScintTime() + transport_time[i]);
307  else time = static_cast<int>(edepi.StartT() + fScintTime->GetScintTime());
308  photon.Time = time;
309  if(Reflected) ref_photcol[channel].insert(ref_photcol[channel].end(), 1, photon);
310  else dir_photcol[channel].insert(dir_photcol[channel].end(), 1, photon);
311  }
312  }
313 
314  if (ndetected_slow > 0 && fDoSlowComponent) {
315  for (long i = 0; i < ndetected_slow; ++i) {
316  fScintTime->GenScintTime(false, fScintTimeEngine);
317  int time;
318  if (fIncludePropTime) time = static_cast<int>(edepi.StartT() + fScintTime->GetScintTime() + transport_time[ndetected_fast + i]);
319  else time = static_cast<int>(edepi.StartT() + fScintTime->GetScintTime());
320  photon.Time = time;
321  if(Reflected) ref_photcol[channel].insert(ref_photcol[channel].end(), 1, photon);
322  else dir_photcol[channel].insert(dir_photcol[channel].end(), 1, photon);
323  }
324  }
325  }
326  }
327  }
328  }
329 
330  PDChannelToSOCMapDirect.clear();
331  PDChannelToSOCMapReflect.clear();
332 
333  if (lgp->UseLitePhotons())
334  {
335  event.put(move(phlit));
336  event.put(move(opbtr));
337  if (pvs->StoreReflected())
338  {
339  event.put(move(phlit_ref), "Reflected");
340  event.put(move(opbtr_ref), "Reflected");
341  }
342  }
343  else
344  {
345  event.put(move(phot));
346  if (pvs->StoreReflected())
347  {
348  event.put(move(phot_ref), "Reflected");
349  }
350  }
351 
352  return;
353  }
354 
355  //......................................................................
356  void PDFastSimPVS::AddOpDetBTR(std::vector< sim::OpDetBacktrackerRecord > & opbtr,
357  std::map<int, int> & ChannelMap,
359  {
360  int iChan = btr.OpDetNum();
361  std::map<int, int>::iterator channelPosition = ChannelMap.find(iChan);
362 
363  if (channelPosition == ChannelMap.end() )
364  {
365  ChannelMap[iChan] = opbtr.size();
366  opbtr.emplace_back(std::move(btr));
367  }
368  else
369  {
370  unsigned int idtest = channelPosition->second;
371  auto const& timePDclockSDPsMap = btr.timePDclockSDPsMap();
372 
373  for(auto const& timePDclockSDP : timePDclockSDPsMap)
374  {
375  for(auto const& sdp : timePDclockSDP.second)
376  {
377  double xyz[3] = {sdp.x, sdp.y, sdp.z};
378  opbtr.at(idtest).AddScintillationPhotons(sdp.trackID,
379  timePDclockSDP.first,
380  sdp.numPhotons,
381  xyz,
382  sdp.energy);
383  }
384  }
385  }
386  }
387 } // namespace
388 
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
intermediate_table::iterator iterator
Store parameters for running LArG4.
CLHEP::HepRandomEngine & fPhotonEngine
std::unique_ptr< ScintTime > fScintTime
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
All information of a photon entering the sensitive optical detector volume.
Definition: SimPhotons.h:64
uint8_t channel
Definition: CRTFragment.hh:201
fhicl::ParameterSet fVISTimingParams
Energy deposited on a readout Optical Detector by simulated tracks.
geo::Point_t InitialPosition
Scintillation position in world coordinates [cm].
Definition: SimPhotons.h:67
art framework interface to geometry description
Simulation objects for optical detectors.
std::map< int, int > PDChannelToSOCMapReflect
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
int OpDetNum() const
Returns the readout Optical Detector this object describes.
void AddOpDetBTR(std::vector< sim::OpDetBacktrackerRecord > &opbtr, std::map< int, int > &ChannelMap, sim::OpDetBacktrackerRecord btr)
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
static constexpr double eV
Definition: Units.h:127
def move(depos, offset)
Definition: depos.py:107
fhicl::ParameterSet fVUVTimingParams
PDFastSimPVS(fhicl::ParameterSet const &)
std::map< int, int > PDChannelToSOCMapDirect
void AddScintillationPhotons(TrackID_t trackID, timePDclock_t timePDclock, double numberPhotons, double const *xyz, double energy)
Add scintillation photons and energy to this OpticalDetector.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
General LArSoft Utilities.
A container for photon visibility mapping data.
bool SetInSD
Whether the photon reaches the sensitive detector.
Definition: SimPhotons.h:88
contains information for a single step in the detector simulation
float Energy
Scintillation photon energy [GeV].
Definition: SimPhotons.h:82
std::unique_ptr< PropagationTimeModel > fPropTimeModel
void produce(art::Event &) override
timePDclockSDPs_t const & timePDclockSDPsMap() const
Returns all the deposited energy information as stored.
bool UseLitePhotons() const
QTextStream & endl(QTextStream &s)
CLHEP::HepRandomEngine & fScintTimeEngine
Event finding and building.