15 #include "nurandom/RandomUtils/NuRandomService.h"
17 #include "art/Framework/Core/EDProducer.h"
18 #include "art/Framework/Core/ModuleMacros.h"
19 #include "art/Framework/Principal/Event.h"
20 #include "art/Framework/Principal/Handle.h"
21 #include "art/Framework/Services/Registry/ServiceHandle.h"
22 #include "canvas/Utilities/InputTag.h"
23 #include "fhiclcpp/ParameterSet.h"
24 #include "cetlib_except/exception.h"
26 #include "CLHEP/Random/RandFlat.h"
27 #include "CLHEP/Random/RandPoissonQ.h"
37 single_exp(
double t,
double tau2)
39 return exp((-1.0 * t) / tau2) / tau2;
43 bi_exp(
double t,
double tau1,
double tau2)
45 return (((
exp((-1.0 * t) / tau2) * (1.0 -
exp((-1.0 * t) / tau1))) / tau2) / tau2) *
54 GetScintTime(
double tau1,
double tau2, CLHEP::RandFlat& randflatscinttime)
58 if ((tau1 == 0.0) || (tau1 == -1.0)) {
return -tau2 * log(randflatscinttime()); }
60 auto ran1 = randflatscinttime();
61 auto ran2 = randflatscinttime();
62 auto d = (tau1 + tau2) / tau2;
63 auto t = -tau2 * log(1 - ran1);
64 auto g = d * single_exp(t, tau2);
65 if (ran2 <= bi_exp(t, tau1, tau2) /
g) {
return t; }
155 void produce(art::Event&)
override;
165 PhotonLibraryPropagation::PhotonLibraryPropagation(fhicl::ParameterSet
const&
p)
167 , fRiseTimeFast{
p.get<
double>(
"RiseTimeFast", 0.0)}
168 , fRiseTimeSlow{
p.get<
double>(
"RiseTimeSlow", 0.0)}
169 , fDoSlowComponent{
p.get<
bool>(
"DoSlowComponent")}
170 , fEDepTags{
p.get<vector<art::InputTag>>(
"EDepModuleLabels")}
171 , fPhotonEngine(art::ServiceHandle<rndm::NuRandomService> {}
172 ->createEngine(*
this,
"HepJamesRandom",
"photon",
p,
"SeedPhoton"))
174 ->createEngine(*
this,
"HepJamesRandom",
"scinttime",
p,
"SeedScintTime"))
176 if (art::ServiceHandle<sim::LArG4Parameters const> {}->UseLitePhotons()) {
177 produces<vector<sim::SimPhotonsLite>>();
180 produces<vector<sim::SimPhotons>>();
187 art::ServiceHandle<PhotonVisibilityService const> pvs;
188 art::ServiceHandle<sim::LArG4Parameters const> lgp;
189 auto const* larp = lar::providerFrom<detinfo::LArPropertiesService>();
190 auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e);
193 auto const nOpChannels = pvs->NOpChannels();
194 unique_ptr<vector<sim::SimPhotons>> photCol{
new vector<sim::SimPhotons>{}};
195 auto& photonCollection{*photCol};
196 photonCollection.resize(nOpChannels);
197 unique_ptr<vector<sim::SimPhotonsLite>> photLiteCol{
new vector<sim::SimPhotonsLite>{}};
198 auto& photonLiteCollection{*photLiteCol};
199 photonLiteCollection.resize(nOpChannels);
200 for (
unsigned int i = 0; i < nOpChannels; ++i) {
201 photonLiteCollection[i].OpChannel = i;
202 photonCollection[i].SetChannel(i);
204 vector<vector<sim::SimEnergyDeposit>
const*> edep_vecs;
206 auto const& edep_handle = e.getValidHandle<vector<sim::SimEnergyDeposit>>(label);
207 edep_vecs.push_back(edep_handle);
209 for (
auto const& edeps : edep_vecs) {
210 for (
auto const& edep : *edeps) {
213 auto const& Visibilities = pvs->GetAllVisibilities(
p);
215 throw cet::exception(
"PhotonLibraryPropagation")
216 <<
"There is no entry in the PhotonLibrary for this position in space. "
222 double nphot =
static_cast<int>(isCalcData.numPhotons);
224 double nphot_fast =
static_cast<int>(GetScintYield(edep, *larp) * nphot);
226 double nphot_slow = nphot - nphot_fast;
227 for (
unsigned int channel = 0; channel < nOpChannels; ++channel) {
228 auto visibleFraction = Visibilities[channel];
229 if (visibleFraction == 0.0) {
233 if (lgp->UseLitePhotons()) {
234 if (nphot_fast > 0) {
236 auto n =
static_cast<int>(randpoisphot.fire(nphot_fast * visibleFraction));
237 for (
long i = 0; i <
n; ++i) {
242 ++photonLiteCollection[channel].DetectedPhotons[time];
247 auto n = randpoisphot.fire(nphot_slow * visibleFraction);
248 for (
long i = 0; i <
n; ++i) {
253 ++photonLiteCollection[channel].DetectedPhotons[time];
262 if (nphot_fast > 0) {
264 auto n = randpoisphot.fire(nphot_fast * visibleFraction);
271 photonCollection[channel].insert(photonCollection[channel].
end(),
n, photon);
276 auto n = randpoisphot.fire(nphot_slow * visibleFraction);
283 photonCollection[channel].insert(photonCollection[channel].
end(),
n, photon);
290 if (lgp->UseLitePhotons()) {
292 e.put(move(photLiteCol));
296 e.put(move(photCol));
Store parameters for running LArG4.
virtual double ScintFastTimeConst() const =0
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
process_name can override from command line with o or output photon
Utilities related to art service access.
virtual double ScintSlowTimeConst() const =0
virtual double ProtonScintYieldRatio() const =0
void produce(art::Event &) override
virtual double PionScintYieldRatio() const =0
All information of a photon entering the sensitive optical detector volume.
CLHEP::HepRandomEngine & fScintTimeEngine
ISCalcData CalcIonAndScint(detinfo::DetectorPropertiesData const &detProp, sim::SimEnergyDeposit const &edep) override
geo::Point_t InitialPosition
Scintillation position in world coordinates [cm].
virtual double AlphaScintYieldRatio() const =0
virtual double MuonScintYieldRatio() const =0
Simulation objects for optical detectors.
virtual double ScintYieldRatio() const =0
Fast simulation of propagating the photons created from SimEnergyDeposits.
larg4::ISCalcSeparate fISAlg
auto end(FixedBins< T, C > const &) noexcept
geo::Point_t MidPoint() const
vector< art::InputTag > fEDepTags
CLHEP::HepRandomEngine & fPhotonEngine
virtual double KaonScintYieldRatio() const =0
bool SetInSD
Whether the photon reaches the sensitive detector.
contains information for a single step in the detector simulation
virtual double ElectronScintYieldRatio() const =0
Energy deposition in the active material.
virtual bool ScintByParticleType() const =0
float Energy
Scintillation photon energy [GeV].
createEngine fScintTimeEngine(art::ServiceHandle< rndm::NuRandomService >() ->createEngine(*this,"HepJamesRandom","scinttime", p,"SeedScintTime"))