33 #include "nurandom/RandomUtils/NuRandomService.h"
36 #include "art/Framework/Core/EDProducer.h"
37 #include "art/Framework/Core/ModuleMacros.h"
38 #include "art/Framework/Principal/Event.h"
39 #include "art/Framework/Principal/Handle.h"
40 #include "art/Framework/Principal/Selector.h"
41 #include "art/Framework/Services/Registry/ServiceHandle.h"
42 #include "messagefacility/MessageLogger/MessageLogger.h"
43 #include "fhiclcpp/ParameterSet.h"
44 #include "canvas/Utilities/Exception.h"
45 #include "canvas/Utilities/InputTag.h"
47 #include "CLHEP/Random/RandomEngine.h"
60 explicit IonAndScint(fhicl::ParameterSet
const& pset);
61 void produce(art::Event& event)
override;
67 std::vector<art::Handle<SimEnergyDepositCollection>>
inputCollections(art::Event
const&)
const;
88 : art::EDProducer{pset}
89 , calcTag{pset.get<art::InputTag>(
"ISCalcAlg")}
90 , fInputModuleLabels{pset.get<std::vector<std::string>>(
"InputModuleLabels", {})}
91 ,
fEngine(art::ServiceHandle<rndm::NuRandomService>()
92 ->createEngine(*
this,
"HepJamesRandom",
"ISCalcAlg", pset,
"SeedISCalcAlg"))
94 pset.get<
string>(
"Instances",
"LArG4DetectorServicevolTPCActive"),
96 , fSavePriorSCE{pset.get<
bool>(
"SavePriorSCE",
false)}
98 std::cout <<
"IonAndScint Module Construct" << std::endl;
101 std::cout <<
"Produce SimEnergyDeposit in default volume - LArG4DetectorServicevolTPCActive"
103 instanceNames.push_back(
"LArG4DetectorServicevolTPCActive");
108 while (std::getline(input, temp,
';')) {
109 instanceNames.push_back(temp);
112 std::cout <<
"Produce SimEnergyDeposit in volumes: " << std::endl;
113 for (
auto instanceName : instanceNames) {
114 std::cout <<
" - " << instanceName << std::endl;
118 produces<std::vector<sim::SimEnergyDeposit>>();
119 if (fSavePriorSCE) produces<std::vector<sim::SimEnergyDeposit>>(
"priorSCE");
126 std::cout <<
"IonAndScint beginJob." << std::endl;
127 std::cout <<
"Using " <<
calcTag.label() <<
" algorithm to calculate IS." << std::endl;
129 if (
calcTag.label() ==
"Separate")
130 fISAlg = std::make_unique<ISCalcSeparate>();
131 else if (
calcTag.label() ==
"Correlated") {
132 auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService>()->DataForJob();
135 else if (
calcTag.label() ==
"NEST")
138 mf::LogWarning(
"IonAndScint") <<
"No ISCalculation set, this can't be good.";
145 std::cout <<
"IonAndScint endJob." << std::endl;
149 std::vector<art::Handle<SimEnergyDepositCollection>>
153 mf::LogDebug(
"IonAndScint") <<
"Retrieving all products" << std::endl;
157 std::vector<art::Handle<SimEnergyDepositCollection>> result;
161 mf::LogDebug(
"IonAndScint") <<
"Retrieving products with module label "
166 if (
empty(handels)) {
167 throw art::Exception(art::errors::ProductNotFound)
168 <<
"IonAndScint module cannot find any SimEnergyDeposits with module label "
169 <<
module <<
" as requested in InputModuleLabels. \n";
172 result.insert(result.end(), handels.begin(), handels.end());
182 std::cout <<
"IonAndScint Module Producer" << std::endl;
184 std::vector<art::Handle<SimEnergyDepositCollection>> edepHandle =
inputCollections(event);
186 if (
empty(edepHandle)) {
187 std::cout <<
"IonAndScint Module Cannot Retrive SimEnergyDeposit" << std::endl;
191 auto sce = lar::providerFrom<spacecharge::SpaceChargeService>();
193 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(event);
195 auto simedep = std::make_unique<std::vector<sim::SimEnergyDeposit>>();
196 auto simedep1 = std::make_unique<std::vector<sim::SimEnergyDeposit>>();
197 for (
auto edeps : edepHandle) {
199 if (!edeps.isValid()) {
200 std::cout <<
"!edeps.isValid()" << std::endl;
204 auto index = std::find(
207 std::cout <<
"Skip SimEnergyDeposit in: " << edeps.provenance()->productInstanceName()
212 std::cout <<
"SimEnergyDeposit input module: " << edeps.provenance()->moduleLabel()
213 <<
", instance name: " << edeps.provenance()->productInstanceName() << std::endl;
216 auto const isCalcData =
fISAlg->CalcIonAndScint(detProp, edepi);
218 int ph_num = round(isCalcData.numPhotons);
219 int ion_num = round(isCalcData.numElectrons);
220 float scintyield = isCalcData.scintillationYieldRatio;
221 float edep_tmp = edepi.Energy();
224 double startTime_tmp = edepi.StartT();
225 double endTime_tmp = edepi.EndT();
226 int trackID_tmp = edepi.TrackID();
227 int pdgCode_tmp = edepi.PdgCode();
229 if (sce->EnableSimSpatialSCE()) {
230 auto posOffsetsStart =
231 sce->GetPosOffsets({edepi.StartX(), edepi.StartY(), edepi.StartZ()});
232 auto posOffsetsEnd = sce->GetPosOffsets({edepi.EndX(), edepi.EndY(), edepi.EndZ()});
234 geo::Point_t{(float)(edepi.StartX() - posOffsetsStart.X()),
235 (
float)(edepi.StartY() + posOffsetsStart.Y()),
236 (
float)(edepi.StartZ() + posOffsetsStart.Z())};
239 (
float)(edepi.EndY() + posOffsetsEnd.Y()),
240 (
float)(edepi.EndZ() + posOffsetsEnd.Z())};
243 simedep->emplace_back(ph_num,
255 simedep1->emplace_back(ph_num,
269 event.put(std::move(simedep));
270 if (
fSavePriorSCE)
event.put(std::move(simedep1),
"priorSCE");
Utilities related to art service access.
IonAndScint(fhicl::ParameterSet const &pset)
CLHEP::HepRandomEngine & fEngine
std::vector< art::Handle< SimEnergyDepositCollection > > inputCollections(art::Event const &) const
std::vector< std::string > fInputModuleLabels
fEngine(art::ServiceHandle< rndm::NuRandomService >() ->createEngine(*this,"HepJamesRandom","ISCalcAlg", pset,"SeedISCalcAlg"))
std::vector< string > instanceNames
contains information for a single step in the detector simulation
Energy deposition in the active material.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
std::unique_ptr< ISCalc > fISAlg
bool empty(FixedBins< T, C > const &) noexcept
void produce(art::Event &event) override
BEGIN_PROLOG could also be cout
std::vector< sim::SimEnergyDeposit > SimEnergyDepositCollection