38 #include "nurandom/RandomUtils/NuRandomService.h"
41 #include "art/Framework/Core/EDProducer.h"
42 #include "art/Framework/Core/ModuleMacros.h"
43 #include "art/Framework/Principal/Event.h"
44 #include "art/Framework/Principal/Handle.h"
45 #include "art/Framework/Services/Registry/ServiceHandle.h"
46 #include "art/Utilities/make_tool.h"
47 #include "canvas/Utilities/Exception.h"
48 #include "canvas/Utilities/InputTag.h"
49 #include "messagefacility/MessageLogger/MessageLogger.h"
50 #include "fhiclcpp/ParameterSet.h"
52 #include "CLHEP/Random/RandPoissonQ.h"
53 #include "CLHEP/Units/SystemOfUnits.h"
66 void produce(art::Event&)
override;
67 void AddOpDetBTR(std::vector< sim::OpDetBacktrackerRecord > & opbtr,
68 std::vector<int> & ChannelMap,
72 art::ServiceHandle<PhotonVisibilityService const>
fPVS;
93 : art::EDProducer{pset}
94 , fPVS(art::ServiceHandle<PhotonVisibilityService const>())
95 , fDoFastComponent(pset.get<
bool>(
"DoFastComponent",
true))
96 , fDoSlowComponent(pset.get<
bool>(
"DoSlowComponent",
true))
97 , fIncludePropTime(pset.get<
bool>(
"IncludePropTime",
false))
98 , fUseLitePhotons(art::ServiceHandle<sim::LArG4Parameters const>()->
UseLitePhotons())
99 , fStoreReflected(fPVS->StoreReflected())
100 , fNOpChannels(fPVS->NOpChannels())
101 , simTag{pset.get<art::InputTag>(
"SimulationLabel")}
102 ,
fScintTimeEngine(art::ServiceHandle<rndm::NuRandomService>()->createEngine(*
this,
"HepJamesRandom",
"scinttime", pset,
"SeedScintTime"))
103 , fScintTime{art::make_tool<phot::ScintTime>(pset.get<fhicl::ParameterSet>(
"ScintTimeTool"))}
104 , fPhotonEngine(art::ServiceHandle<rndm::NuRandomService>{}->createEngine(*
this,
"HepJamesRandom",
"photon", pset,
"SeedPhoton"))
107 mf::LogInfo(
"PDFastSimPVS") <<
"PDFastSimPVS Module Construct";
109 if (fUseLitePhotons) {
110 mf::LogInfo(
"PDFastSimPVS") <<
"Use Lite Photon." << std::endl;
111 produces< std::vector<sim::SimPhotonsLite> >();
112 produces< std::vector<sim::OpDetBacktrackerRecord> >();
114 if(fStoreReflected) {
115 mf::LogInfo(
"PDFastSimPVS") <<
"Store Reflected Photons";
116 produces< std::vector<sim::SimPhotonsLite> >(
"Reflected");
117 produces< std::vector<sim::OpDetBacktrackerRecord> >(
"Reflected");
121 mf::LogInfo(
"PDFastSimPVS") <<
"Use Sim Photon.";
122 produces< std::vector<sim::SimPhotons> >();
125 mf::LogInfo(
"PDFastSimPVS") <<
"Store Reflected Photons";
126 produces< std::vector<sim::SimPhotons> >(
"Reflected");
132 if(fIncludePropTime &&
133 !pset.get_if_present<fhicl::ParameterSet>(
"VUVTiming", fVUVTimingParams)) {
134 throw art::Exception(art::errors::Configuration)
135 <<
"Propagation time simulation requested, but VUVTiming not specified." <<
"\n";
138 if (fIncludePropTime && fStoreReflected &&
139 !pset.get_if_present<fhicl::ParameterSet>(
"VISTiming", fVISTimingParams)) {
140 throw art::Exception(art::errors::Configuration)
141 <<
"Reflected light propagation time simulation requested, but VISTiming not specified." <<
"\n";
145 if (fIncludePropTime) fPropTimeModel = std::make_unique<PropagationTimeModel>(fVUVTimingParams, fVISTimingParams,
fScintTimeEngine, fStoreReflected);
151 std::vector<int> PDChannelToSOCMapDirect(
fNOpChannels, -1);
152 std::vector<int> PDChannelToSOCMapReflect(
fNOpChannels, -1);
155 auto phlit = std::make_unique<std::vector<sim::SimPhotonsLite>>();
156 auto opbtr = std::make_unique<std::vector<sim::OpDetBacktrackerRecord>>();
157 auto phlit_ref = std::make_unique<std::vector<sim::SimPhotonsLite>>();
158 auto opbtr_ref = std::make_unique<std::vector<sim::OpDetBacktrackerRecord>>();
159 auto& dir_phlitcol(*phlit);
160 auto& ref_phlitcol(*phlit_ref);
162 auto phot = std::make_unique<std::vector<sim::SimPhotons>>();
163 auto phot_ref = std::make_unique<std::vector<sim::SimPhotons>>();
164 auto& dir_photcol(*phot);
165 auto& ref_photcol(*phot_ref);
170 dir_phlitcol[i].OpChannel = i;
171 ref_phlitcol[i].OpChannel = i;
178 dir_photcol[i].fOpChannel = i;
179 ref_photcol[i].fOpChannel = i;
183 art::Handle< std::vector<sim::SimEnergyDeposit> > edepHandle;
184 if (!event.getByLabel(
simTag, edepHandle)) {
185 mf::LogWarning(
"PDFastSimPVS") <<
"PDFastSimPVS Module Cannot getByLabel: " <<
simTag;
190 auto const& edeps = edepHandle;
191 for (
auto const& edepi: *edeps) {
194 int nphot_fast = edepi.NumFPhotons();
195 int nphot_slow = edepi.NumSPhotons();
199 auto const& prt = edepi.MidPoint();
204 Visibilities_Ref =
fPVS->GetAllVisibilities(prt,
true);
205 if(!Visibilities_Ref) mf::LogWarning(
"PDFastSimPVS") <<
"Fail to get visibilities for reflected photons.";
210 mf::LogWarning(
"PDFastSimPVS")
211 <<
"There is no entry in the PhotonLibrary for this position in space. Position: " << edepi.MidPoint()
212 <<
"\n Move to next point";
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()};
221 geo::Point_t const ScintPoint = {pos[0], pos[1], pos[2]};
225 for (
size_t Reflected = 0; Reflected <= DoReflected; ++Reflected) {
226 for (
unsigned int channel = 0; channel <
fNOpChannels; ++ channel) {
228 double visibleFraction = (Reflected) ? Visibilities_Ref[channel] : Visibilities[channel];
229 if (visibleFraction < 1
e-9)
continue;
232 int ndetected_fast = (nphot_fast > 0) ?
fRandPoissPhot->fire(nphot_fast * visibleFraction) : 0;
233 int ndetected_slow = (nphot_slow > 0) ?
fRandPoissPhot->fire(nphot_slow * visibleFraction) : 0;
238 std::vector<double> transport_time;
240 transport_time.resize(ndetected_fast + ndetected_slow);
241 fPropTimeModel->propagationTime(transport_time, ScintPoint, channel, Reflected);
248 for (
int i = 0; i < ndetected_fast; ++i) {
253 else time =
static_cast<int>(edepi.StartT() +
fScintTime->GetScintTime());
254 if (Reflected) ++ref_phlitcol[channel].DetectedPhotons[time];
255 else ++dir_phlitcol[channel].DetectedPhotons[time];
260 for (
int i = 0; i < ndetected_slow; ++i) {
264 if (
fIncludePropTime) time =
static_cast<int>(edepi.StartT() +
fScintTime->GetScintTime() + transport_time[ndetected_fast + i]);
265 else time =
static_cast<int>(edepi.StartT() +
fScintTime->GetScintTime());
266 if (Reflected) ++ref_phlitcol[channel].DetectedPhotons[time];
267 else ++dir_phlitcol[channel].DetectedPhotons[time];
271 if (Reflected)
AddOpDetBTR(*opbtr_ref, PDChannelToSOCMapReflect, tmpbtr);
272 else AddOpDetBTR(*opbtr, PDChannelToSOCMapDirect, tmpbtr);
280 if (Reflected) photon.
Energy = 2.9 * CLHEP::eV;
281 else photon.
Energy = 9.7 * CLHEP::eV;
283 for (
int i = 0; i < ndetected_fast; ++i) {
288 else time =
static_cast<int>(edepi.StartT() +
fScintTime->GetScintTime());
290 if(Reflected) ref_photcol[channel].insert(ref_photcol[channel].
end(), 1, photon);
291 else dir_photcol[channel].insert(dir_photcol[channel].
end(), 1, photon);
295 for (
int i = 0; i < ndetected_slow; ++i) {
298 if (
fIncludePropTime) time =
static_cast<int>(edepi.StartT() +
fScintTime->GetScintTime() + transport_time[ndetected_fast + i]);
299 else time =
static_cast<int>(edepi.StartT() +
fScintTime->GetScintTime());
301 if(Reflected) ref_photcol[channel].insert(ref_photcol[channel].
end(), 1, photon);
302 else dir_photcol[channel].insert(dir_photcol[channel].
end(), 1, photon);
311 event.put(move(phlit));
312 event.put(move(opbtr));
314 event.put(move(phlit_ref),
"Reflected");
315 event.put(move(opbtr_ref),
"Reflected");
319 event.put(move(phot));
321 event.put(move(phot_ref),
"Reflected");
330 std::vector<int> & ChannelMap,
334 if (ChannelMap[iChan] < 0) {
335 ChannelMap[iChan] = opbtr.size();
336 opbtr.emplace_back(std::move(btr));
339 size_t idtest = ChannelMap[iChan];
341 for(
auto const& timePDclockSDP : timePDclockSDPsMap) {
342 for(
auto const& sdp : timePDclockSDP.second) {
343 double xyz[3] = {sdp.x, sdp.y, sdp.z};
344 opbtr.at(idtest).AddScintillationPhotons(sdp.trackID,
345 timePDclockSDP.first,
Store parameters for running LArG4.
process_name can override from command line with o or output photon
CLHEP::HepRandomEngine & fPhotonEngine
std::unique_ptr< ScintTime > fScintTime
void AddOpDetBTR(std::vector< sim::OpDetBacktrackerRecord > &opbtr, std::vector< int > &ChannelMap, const sim::OpDetBacktrackerRecord &btr) const
art::ServiceHandle< PhotonVisibilityService const > fPVS
All information of a photon entering the sensitive optical detector volume.
std::unique_ptr< CLHEP::RandPoissonQ > fRandPoissPhot
fhicl::ParameterSet fVISTimingParams
Energy deposited on a readout Optical Detector by simulated tracks.
geo::Point_t InitialPosition
Scintillation position in world coordinates [cm].
const bool fIncludePropTime
const bool fDoSlowComponent
const size_t fNOpChannels
Simulation objects for optical detectors.
int OpDetNum() const
Returns the readout Optical Detector this object describes.
createEngine fRandPoissPhot(std::make_unique< CLHEP::RandPoissonQ >(fPhotonEngine))
fhicl::ParameterSet fVUVTimingParams
PDFastSimPVS(fhicl::ParameterSet const &)
auto end(FixedBins< T, C > const &) noexcept
void AddScintillationPhotons(TrackID_t trackID, timePDclock_t timePDclock, double numberPhotons, double const *xyz, double energy)
Add scintillation photons and energy to this OpticalDetector.
const art::InputTag simTag
A container for photon visibility mapping data.
bool SetInSD
Whether the photon reaches the sensitive detector.
contains information for a single step in the detector simulation
const bool fDoFastComponent
const bool fUseLitePhotons
float Energy
Scintillation photon energy [GeV].
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
std::unique_ptr< PropagationTimeModel > fPropTimeModel
void produce(art::Event &) override
timePDclockSDPs_t const & timePDclockSDPsMap() const
Returns all the deposited energy information as stored.
CLHEP::HepRandomEngine & fScintTimeEngine
const bool fStoreReflected
services LArG4Parameters UseLitePhotons
createEngine fScintTimeEngine(art::ServiceHandle< rndm::NuRandomService >() ->createEngine(*this,"HepJamesRandom","scinttime", p,"SeedScintTime"))