LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
IonAndScint_module.cc
Go to the documentation of this file.
1 // Class: IonAndScint
3 // Plugin Type: producer
4 // File: IonAndScint_module.cc
5 // Description:
6 // - acts on sim::SimEnergyDeposit from LArG4Main,
7 // - calculate the number of photons and electrons
8 // Input: 'sim::SimEnergyDeposit'
9 // Output: updated 'sim::SimEnergyDeposit' with numPhotons and numElectrons
10 //
11 //This module calculate the number of photons and electrons produced at each step where energy is deposited.
12 //The Separate algorithm is used by default, but this can be changed via the "ISCalcAlg"
13 //fhicl parameter tag.
14 //At the end of this module the numPhotons and numElectrons of sim:SimEnergyDeposit have been updated.
15 //
16 // Aug.18 by Mu Wei
17 //
18 // 10/28/2019 Wenqiang Gu (wgu@bnl.gov)
19 // Add the Space Charge Effect (SCE) if the option is enabled
21 
22 // LArSoft includes
23 
32 
34 
35 // Framework includes
44 #include "fhiclcpp/ParameterSet.h"
46 
47 #include "CLHEP/Random/RandomEngine.h"
48 
49 #include <iostream>
50 #include <sstream> // std::stringstream
51 #include <string>
52 #include <vector>
53 
54 using std::string;
55 using SimEnergyDepositCollection = std::vector<sim::SimEnergyDeposit>;
56 
57 namespace larg4 {
58  class IonAndScint : public art::EDProducer {
59  public:
60  explicit IonAndScint(fhicl::ParameterSet const& pset);
61  void produce(art::Event& event) override;
62  void beginJob() override;
63  void endJob() override;
64 
65  private:
66  std::vector<art::Handle<SimEnergyDepositCollection>> inputCollections(art::Event const&) const;
67 
68  // name of calculator: Separate, Correlated, or NEST
70 
71  // The input module labels to specify which SimEnergyDeposit
72  // collections to use as input. Specify only the module label,
73  // not the instance name(s). Instances to be used have to be
74  // passed via the Instances parameter.
75  // If empty, this module uses all the available collections.
76  std::vector<std::string> fInputModuleLabels;
77 
78  std::unique_ptr<ISCalc> fISAlg;
79  CLHEP::HepRandomEngine& fEngine;
80  string Instances;
81  std::vector<string> instanceNames;
83  };
84 
85  //......................................................................
87  : art::EDProducer{pset}
88  , calcTag{pset.get<art::InputTag>("ISCalcAlg")}
89  , fInputModuleLabels{pset.get<std::vector<std::string>>("InputModuleLabels", {})}
91  -> registerAndSeedEngine(createEngine(0, "HepJamesRandom", "ISCalcAlg"),
92  "HepJamesRandom",
93  "ISCalcAlg",
94  pset,
95  "SeedISCalcAlg"))
96  , Instances{pset.get<string>("Instances", "LArG4DetectorServicevolTPCActive")}
97  , fSavePriorSCE{pset.get<bool>("SavePriorSCE", false)}
98  {
99  std::cout << "IonAndScint Module Construct" << std::endl;
100 
101  if (Instances.empty()) {
102  std::cout << "Produce SimEnergyDeposit in default volume - LArG4DetectorServicevolTPCActive"
103  << std::endl;
104  instanceNames.push_back("LArG4DetectorServicevolTPCActive");
105  }
106  else {
107  std::stringstream input(Instances);
108  string temp;
109  while (std::getline(input, temp, ';')) {
110  instanceNames.push_back(temp);
111  }
112 
113  std::cout << "Produce SimEnergyDeposit in volumes: " << std::endl;
114  for (auto instanceName : instanceNames) {
115  std::cout << " - " << instanceName << std::endl;
116  }
117  }
118 
119  produces<std::vector<sim::SimEnergyDeposit>>();
120  if (fSavePriorSCE) produces<std::vector<sim::SimEnergyDeposit>>("priorSCE");
121  }
122 
123  //......................................................................
125  {
126  std::cout << "IonAndScint beginJob." << std::endl;
127  std::cout << "Using " << calcTag.label() << " algorithm to calculate IS." << std::endl;
128 
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();
133  fISAlg = std::make_unique<ISCalcCorrelated>(detProp, fEngine);
134  }
135  else if (calcTag.label() == "NEST")
136  fISAlg = std::make_unique<ISCalcNESTLAr>(fEngine);
137  else
138  mf::LogWarning("IonAndScint") << "No ISCalculation set, this can't be good.";
139  }
140 
141  //......................................................................
143  {
144  std::cout << "IonAndScint endJob." << std::endl;
145  }
146 
147  //......................................................................
148  std::vector<art::Handle<SimEnergyDepositCollection>> IonAndScint::inputCollections(
149  art::Event const& e) const
150  {
151  if (empty(fInputModuleLabels)) {
152  mf::LogDebug("IonAndScint") << "Retrieving all products" << std::endl;
154  }
155 
156  std::vector<art::Handle<SimEnergyDepositCollection>> result;
157 
158  for (auto const& module : fInputModuleLabels) {
159 
160  mf::LogDebug("IonAndScint") << "Retrieving products with module label " << module
161  << std::endl;
162 
164 
165  if (empty(handels)) {
167  << "IonAndScint module cannot find any SimEnergyDeposits with module label " << module
168  << " as requested in InputModuleLabels. \n";
169  }
170 
171  result.insert(result.end(), handels.begin(), handels.end());
172  }
173 
174  return result;
175  }
176 
177  //......................................................................
179  {
180  std::cout << "IonAndScint Module Producer" << std::endl;
181 
182  std::vector<art::Handle<SimEnergyDepositCollection>> edepHandle = inputCollections(event);
183 
184  if (empty(edepHandle)) {
185  std::cout << "IonAndScint Module Cannot Retrive SimEnergyDeposit" << std::endl;
186  return;
187  }
188 
189  auto sce = lar::providerFrom<spacecharge::SpaceChargeService>();
190  auto const detProp =
192 
193  auto simedep = std::make_unique<std::vector<sim::SimEnergyDeposit>>();
194  auto simedep1 = std::make_unique<std::vector<sim::SimEnergyDeposit>>(); // for prior-SCE depos
195  for (auto edeps : edepHandle) {
196  // Do some checking before we proceed
197  if (!edeps.isValid()) {
198  std::cout << "!edeps.isValid()" << std::endl;
199  continue;
200  }
201 
202  auto index = std::find(
203  instanceNames.begin(), instanceNames.end(), edeps.provenance()->productInstanceName());
204  if (index == instanceNames.end()) {
205  std::cout << "Skip SimEnergyDeposit in: " << edeps.provenance()->productInstanceName()
206  << std::endl;
207  continue;
208  }
209 
210  std::cout << "SimEnergyDeposit input module: " << edeps.provenance()->moduleLabel()
211  << ", instance name: " << edeps.provenance()->productInstanceName() << std::endl;
212 
213  for (sim::SimEnergyDeposit const& edepi : *edeps) {
214  auto const isCalcData = fISAlg->CalcIonAndScint(detProp, edepi);
215 
216  int ph_num = round(isCalcData.numPhotons);
217  int ion_num = round(isCalcData.numElectrons);
218  float scintyield = isCalcData.scintillationYieldRatio;
219  float edep_tmp = edepi.Energy();
220  geo::Point_t startPos_tmp = edepi.Start();
221  geo::Point_t endPos_tmp = edepi.End();
222  double startTime_tmp = edepi.StartT();
223  double endTime_tmp = edepi.EndT();
224  int trackID_tmp = edepi.TrackID();
225  int pdgCode_tmp = edepi.PdgCode();
226  int origTrackID_tmp = edepi.OrigTrackID();
227 
228  if (sce->EnableSimSpatialSCE()) {
229  auto posOffsetsStart =
230  sce->GetPosOffsets({edepi.StartX(), edepi.StartY(), edepi.StartZ()});
231  auto posOffsetsEnd = sce->GetPosOffsets({edepi.EndX(), edepi.EndY(), edepi.EndZ()});
232  startPos_tmp =
233  geo::Point_t{(float)(edepi.StartX() - posOffsetsStart.X()), //x should be subtracted
234  (float)(edepi.StartY() + posOffsetsStart.Y()),
235  (float)(edepi.StartZ() + posOffsetsStart.Z())};
236  endPos_tmp =
237  geo::Point_t{(float)(edepi.EndX() - posOffsetsEnd.X()), //x should be subtracted
238  (float)(edepi.EndY() + posOffsetsEnd.Y()),
239  (float)(edepi.EndZ() + posOffsetsEnd.Z())};
240  }
241 
242  simedep->emplace_back(ph_num,
243  ion_num,
244  scintyield,
245  edep_tmp,
246  startPos_tmp,
247  endPos_tmp,
248  startTime_tmp,
249  endTime_tmp,
250  trackID_tmp,
251  pdgCode_tmp,
252  origTrackID_tmp);
253 
254  if (fSavePriorSCE) {
255  simedep1->emplace_back(ph_num,
256  ion_num,
257  scintyield,
258  edepi.Energy(),
259  edepi.Start(),
260  edepi.End(),
261  edepi.StartT(),
262  edepi.EndT(),
263  edepi.TrackID(),
264  edepi.PdgCode(),
265  edepi.OrigTrackID());
266  }
267  }
268  }
269  event.put(std::move(simedep));
270  if (fSavePriorSCE) event.put(std::move(simedep1), "priorSCE");
271  }
272 } // namespace
void beginJob() override
base_engine_t & createEngine(seed_t seed)
Utilities related to art service access.
IonAndScint(fhicl::ParameterSet const &pset)
CLHEP::HepRandomEngine & fEngine
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.cc:6
std::vector< std::string > fInputModuleLabels
Geant4 interface.
std::string const & label() const noexcept
Definition: InputTag.cc:79
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
std::vector< string > instanceNames
std::vector< art::Handle< SimEnergyDepositCollection > > inputCollections(art::Event const &) const
An art service to assist in the distribution of guaranteed unique seeds to all engines within an art ...
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
void endJob() override
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:180
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
contains information for a single step in the detector simulation
Energy deposition in the active material.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Definition: MVAAlg.h:12
Float_t e
Definition: plot.C:35
std::unique_ptr< ISCalc > fISAlg
void produce(art::Event &event) override
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:109
Event finding and building.
std::vector< Handle< PROD > > getMany(SelectorBase const &selector=MatchAllSelector{}) const
std::vector< sim::SimEnergyDeposit > SimEnergyDepositCollection