Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
evgen::RadioGen Class Reference

Module to generate particles created by radiological decay, patterned off of SingleGen. More...

Inheritance diagram for evgen::RadioGen:
art::EDProducer art::detail::Producer art::detail::LegacyModule art::Modifier art::ModuleBase art::ProductRegistryHelper

Public Member Functions

 RadioGen (fhicl::ParameterSet const &pset)
 
- Public Member Functions inherited from art::EDProducer
 EDProducer (fhicl::ParameterSet const &pset)
 
template<typename Config >
 EDProducer (Table< Config > const &config)
 
std::string workerType () const
 
- Public Member Functions inherited from art::detail::Producer
virtual ~Producer () noexcept
 
 Producer (fhicl::ParameterSet const &)
 
 Producer (Producer const &)=delete
 
 Producer (Producer &&)=delete
 
Produceroperator= (Producer const &)=delete
 
Produceroperator= (Producer &&)=delete
 
void doBeginJob (SharedResources const &resources)
 
void doEndJob ()
 
void doRespondToOpenInputFile (FileBlock const &fb)
 
void doRespondToCloseInputFile (FileBlock const &fb)
 
void doRespondToOpenOutputFiles (FileBlock const &fb)
 
void doRespondToCloseOutputFiles (FileBlock const &fb)
 
bool doBeginRun (RunPrincipal &rp, ModuleContext const &mc)
 
bool doEndRun (RunPrincipal &rp, ModuleContext const &mc)
 
bool doBeginSubRun (SubRunPrincipal &srp, ModuleContext const &mc)
 
bool doEndSubRun (SubRunPrincipal &srp, ModuleContext const &mc)
 
bool doEvent (EventPrincipal &ep, ModuleContext const &mc, std::atomic< std::size_t > &counts_run, std::atomic< std::size_t > &counts_passed, std::atomic< std::size_t > &counts_failed)
 
- Public Member Functions inherited from art::Modifier
 ~Modifier () noexcept
 
 Modifier ()
 
 Modifier (Modifier const &)=delete
 
 Modifier (Modifier &&)=delete
 
Modifieroperator= (Modifier const &)=delete
 
Modifieroperator= (Modifier &&)=delete
 
- Public Member Functions inherited from art::ModuleBase
virtual ~ModuleBase () noexcept
 
 ModuleBase ()
 
ModuleDescription const & moduleDescription () const
 
void setModuleDescription (ModuleDescription const &)
 
std::array< std::vector< ProductInfo >, NumBranchTypes > const & getConsumables () const
 
void sortConsumables (std::string const &current_process_name)
 
template<typename T , BranchType BT>
ViewToken< T > consumesView (InputTag const &tag)
 
template<typename T , BranchType BT>
ViewToken< T > mayConsumeView (InputTag const &tag)
 

Private Types

typedef int ti_PDGID
 
typedef double td_Mass
 

Private Member Functions

void produce (art::Event &evt)
 
void beginRun (art::Run &run)
 
std::size_t addvolume (std::string const &volumeName)
 
void SampleOne (unsigned int i, simb::MCTruth &mct)
 Checks that the node represents a box well aligned to world frame axes. More...
 
TLorentzVector dirCalc (double p, double m)
 
void readfile (std::string nuclide, std::string const &filename)
 
void samplespectrum (std::string nuclide, int &itype, double &t, double &m, double &p)
 
void Ar42Gamma2 (std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
 
void Ar42Gamma3 (std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
 
void Ar42Gamma4 (std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
 
void Ar42Gamma5 (std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
 
double samplefromth1d (TH1D &hist)
 
template<typename Stream >
void dumpNuclideSettings (Stream &&out, std::size_t iNucl, std::string const &volumeName={}) const
 Prints the settings for the specified nuclide and volume. More...
 
std::pair< double, double > defaulttimewindow () const
 Returns the start and end of the readout window. More...
 

Private Attributes

std::vector< std::stringfNuclide
 List of nuclides to simulate. Example: "39Ar". More...
 
std::vector< std::stringfMaterial
 List of regexes of materials in which to generate the decays. Example: "LAr". More...
 
std::vector< double > fBq
 Radioactivity in Becquerels (decay per sec) per cubic cm. More...
 
std::vector< double > fT0
 Beginning of time window to simulate in ns. More...
 
std::vector< double > fT1
 End of time window to simulate in ns. More...
 
std::vector< double > fX0
 Bottom corner x position (cm) in world coordinates. More...
 
std::vector< double > fY0
 Bottom corner y position (cm) in world coordinates. More...
 
std::vector< double > fZ0
 Bottom corner z position (cm) in world coordinates. More...
 
std::vector< double > fX1
 Top corner x position (cm) in world coordinates. More...
 
std::vector< double > fY1
 Top corner y position (cm) in world coordinates. More...
 
std::vector< double > fZ1
 Top corner z position (cm) in world coordinates. More...
 
bool fIsFirstSignalSpecial
 
int trackidcounter
 Serial number for the MC track ID. More...
 
std::vector< std::stringspectrumname
 
std::vector< std::unique_ptr< TH1D > > alphaspectrum
 
std::vector< double > alphaintegral
 
std::vector< std::unique_ptr< TH1D > > betaspectrum
 
std::vector< double > betaintegral
 
std::vector< std::unique_ptr< TH1D > > gammaspectrum
 
std::vector< double > gammaintegral
 
std::vector< std::unique_ptr< TH1D > > neutronspectrum
 
std::vector< double > neutronintegral
 
CLHEP::HepRandomEngine & fEngine
 

Additional Inherited Members

- Public Types inherited from art::EDProducer
using ModuleType = EDProducer
 
using WorkerType = WorkerT< EDProducer >
 
- Public Types inherited from art::detail::Producer
template<typename UserConfig , typename KeysToIgnore = void>
using Table = Modifier::Table< UserConfig, KeysToIgnore >
 
- Public Types inherited from art::Modifier
template<typename UserConfig , typename UserKeysToIgnore = void>
using Table = ProducerTable< UserConfig, detail::ModuleConfig, UserKeysToIgnore >
 
- Static Public Member Functions inherited from art::EDProducer
static void commitEvent (EventPrincipal &ep, Event &e)
 
- Protected Member Functions inherited from art::ModuleBase
ConsumesCollectorconsumesCollector ()
 
template<typename T , BranchType = InEvent>
ProductToken< T > consumes (InputTag const &)
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > consumesView (InputTag const &)
 
template<typename T , BranchType = InEvent>
void consumesMany ()
 
template<typename T , BranchType = InEvent>
ProductToken< T > mayConsume (InputTag const &)
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > mayConsumeView (InputTag const &)
 
template<typename T , BranchType = InEvent>
void mayConsumeMany ()
 

Detailed Description

Module to generate particles created by radiological decay, patterned off of SingleGen.

The module generates the products of radioactive decay of some known nuclides. Each nuclide decay producing a single particle (with exceptions, as for example argon(A=42)), whose spectrum is specified in a ROOT file to be found in the FW_SEARCH_PATH path, and it can be a alpha, beta, gamma or neutron. In case multiple decay channels are possible, each decay is stochastically chosen weighting the channels according to the integral of their spectrum. The normalization of the spectrum is otherwise ignored.

Nuclides can be added by making the proper distributions available in a file called after the name used for it in the Nuclide configuration parameter (e.g 14C.root if the nuclide key is 14C): check the existing nuclide files for examples.

A special treatment is encoded for argon(A=42) and radon(A=222) (and, "temporary", for nichel(A=59) ).

Decays happen only in volumes specified in the configuration, and with a rate also specified in the configuration. Volumes are always box-shaped, and can be specified by coordinates or by name. In addition, within each volume decays will be generated only in the subvolumes matching the specified materials.

Note
All beta decays emit positrons.

Configuration parameters

Definition at line 185 of file RadioGen_module.cc.

Member Typedef Documentation

typedef double evgen::RadioGen::td_Mass
private

Definition at line 195 of file RadioGen_module.cc.

typedef int evgen::RadioGen::ti_PDGID
private

Definition at line 194 of file RadioGen_module.cc.

Constructor & Destructor Documentation

evgen::RadioGen::RadioGen ( fhicl::ParameterSet const &  pset)
explicit

Definition at line 280 of file RadioGen_module.cc.

281  : EDProducer{pset}
282  , fX0{pset.get< std::vector<double> >("X0", {})}
283  , fY0{pset.get< std::vector<double> >("Y0", {})}
284  , fZ0{pset.get< std::vector<double> >("Z0", {})}
285  , fX1{pset.get< std::vector<double> >("X1", {})}
286  , fY1{pset.get< std::vector<double> >("Y1", {})}
287  , fZ1{pset.get< std::vector<double> >("Z1", {})}
288  , fIsFirstSignalSpecial{pset.get< bool >("IsFirstSignalSpecial", false)}
289  // create a default random engine; obtain the random seed from NuRandomService,
290  // unless overridden in configuration with key "Seed"
291  , fEngine(art::ServiceHandle<rndm::NuRandomService>{}->createEngine(*this, pset, "Seed"))
292  {
293  produces< std::vector<simb::MCTruth> >();
294  produces< sumdata::RunData, art::InRun >();
295 
296 
297  auto const nuclide = pset.get< std::vector<std::string>>("Nuclide");
298  auto const material = pset.get< std::vector<std::string>>("Material");
299  auto const Bq = pset.get< std::vector<double> >("BqPercc");
300  auto t0 = pset.get< std::vector<double> >("T0", {});
301  auto t1 = pset.get< std::vector<double> >("T1", {});
302 
303  if (fT0.empty() || fT1.empty()) { // better be both empty...
304  if (!fT0.empty() || !fT1.empty()) {
306  << "RadioGen T0 and T1 need to be both non-empty, or both empty"
307  " (now T0 has " << fT0.size() << " entries and T1 has " << fT0.size()
308  << ")\n";
309  }
310  auto const [ defaultT0, defaultT1 ] = defaulttimewindow();
311  t0.push_back(defaultT0);
312  t1.push_back(defaultT1);
313  }
314 
315  //
316  // First, the materials are assigned to the coordinates explicitly
317  // configured; then, each of the remaining materials is assigned to one
318  // of the named volumes.
319  // TODO: reaction to mismatches is "not so great".
320  //
321  mf::LogInfo("RadioGen") << "Configuring activity:";
322  for (std::size_t iCoord: util::counter(fX0.size())) {
323 
324  fNuclide.push_back(nuclide.at(iCoord));
325  fMaterial.push_back(material.at(iCoord));
326  fBq.push_back(Bq.at(iCoord));
327  // replicate the last timing if none is specified
328  fT0.push_back(t0[std::min(iCoord, t0.size() - 1U)]);
329  fT1.push_back(t1[std::min(iCoord, t1.size() - 1U)]);
330 
331  dumpNuclideSettings(mf::LogVerbatim("RadioGen"), iCoord);
332 
333  } // for
334 
335  std::size_t iNext = fX0.size();
336  auto const volumes = pset.get<std::vector<std::string>>("Volumes", {});
337  for (auto&& [ iVolume, volName ]: util::enumerate(volumes)) {
338  // this expands the coordinate vectors
339  auto const nVolumes = addvolume(volName);
340  if (nVolumes == 0) {
342  << "No volume named '" << volName << "' was found!\n";
343  }
344 
345  std::size_t const iVolFirst = fNuclide.size();
346  for (auto iVolInstance: util::counter(nVolumes)) {
347  fNuclide.push_back(nuclide.at(iNext));
348  fMaterial.push_back(material.at(iNext));
349  fBq.push_back(Bq.at(iNext));
350  // replicate the last timing if none is specified
351  fT0.push_back(t0[std::min(iNext, t0.size() - 1U)]);
352  fT1.push_back(t1[std::min(iNext, t1.size() - 1U)]);
353 
355  (mf::LogVerbatim("RadioGen"), iVolFirst + iVolInstance, volName);
356 
357  }
358  ++iNext;
359  } // for
360 
361  // check for consistency of vector sizes
362  unsigned int nsize = fNuclide.size();
363  if (nsize == 0) {
365  << "No nuclide configured!\n";
366  }
367 
368  if ( fMaterial.size() != nsize ) throw cet::exception("RadioGen") << "Different size Material vector and Nuclide vector\n";
369  if ( fBq.size() != nsize ) throw cet::exception("RadioGen") << "Different size Bq vector and Nuclide vector\n";
370  if ( fT0.size() != nsize ) throw cet::exception("RadioGen") << "Different size T0 vector and Nuclide vector\n";
371  if ( fT1.size() != nsize ) throw cet::exception("RadioGen") << "Different size T1 vector and Nuclide vector\n";
372  if ( fX0.size() != nsize ) throw cet::exception("RadioGen") << "Different size X0 vector and Nuclide vector\n";
373  if ( fY0.size() != nsize ) throw cet::exception("RadioGen") << "Different size Y0 vector and Nuclide vector\n";
374  if ( fZ0.size() != nsize ) throw cet::exception("RadioGen") << "Different size Z0 vector and Nuclide vector\n";
375  if ( fX1.size() != nsize ) throw cet::exception("RadioGen") << "Different size X1 vector and Nuclide vector\n";
376  if ( fY1.size() != nsize ) throw cet::exception("RadioGen") << "Different size Y1 vector and Nuclide vector\n";
377  if ( fZ1.size() != nsize ) throw cet::exception("RadioGen") << "Different size Z1 vector and Nuclide vector\n";
378 
379  for(std::string & nuclideName : fNuclide){
380  if(nuclideName=="39Ar" ){readfile("39Ar","Argon_39.root") ;}
381  else if(nuclideName=="60Co" ){readfile("60Co","Cobalt_60.root") ;}
382  else if(nuclideName=="85Kr" ){readfile("85Kr","Krypton_85.root") ;}
383  else if(nuclideName=="40K" ){readfile("40K","Potassium_40.root") ;}
384  else if(nuclideName=="232Th"){readfile("232Th","Thorium_232.root");}
385  else if(nuclideName=="238U" ){readfile("238U","Uranium_238.root") ;}
386  else if(nuclideName=="222Rn"){continue;} //Rn222 is handled separately later
387  else if(nuclideName=="59Ni"){continue;} //Rn222 is handled separately later
388  else if(nuclideName=="42Ar" ){
389  readfile("42Ar_1", "Argon_42_1.root"); //Each possible beta decay mode of Ar42 is given it's own .root file for now.
390  readfile("42Ar_2", "Argon_42_2.root"); //This allows us to know which decay chain to follow for the dexcitation gammas.
391  readfile("42Ar_3", "Argon_42_3.root"); //The dexcitation gammas are not included in the root files as we want to
392  readfile("42Ar_4", "Argon_42_4.root"); //probabilistically simulate the correct coincident gammas, which we cannot guarantee
393  readfile("42Ar_5", "Argon_42_5.root"); //by sampling a histogram.
394  continue;
395  } //Ar42 is handeled separately later
396  else{
397  std::string searchName = nuclideName;
398  searchName+=".root";
399  readfile(nuclideName,searchName);
400  }
401  }
402  }
code to link reconstructed objects back to the MC truth information
std::vector< double > fZ0
Bottom corner z position (cm) in world coordinates.
std::vector< std::string > fNuclide
List of nuclides to simulate. Example: "39Ar".
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::pair< double, double > defaulttimewindow() const
Returns the start and end of the readout window.
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
void dumpNuclideSettings(Stream &&out, std::size_t iNucl, std::string const &volumeName={}) const
Prints the settings for the specified nuclide and volume.
void readfile(std::string nuclide, std::string const &filename)
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
std::vector< double > fT1
End of time window to simulate in ns.
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:285
std::vector< double > fY1
Top corner y position (cm) in world coordinates.
std::vector< double > fZ1
Top corner z position (cm) in world coordinates.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
std::size_t addvolume(std::string const &volumeName)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
CLHEP::HepRandomEngine & fEngine
std::vector< double > fT0
Beginning of time window to simulate in ns.
std::vector< std::string > fMaterial
List of regexes of materials in which to generate the decays. Example: "LAr".
std::vector< double > fX0
Bottom corner x position (cm) in world coordinates.
std::vector< double > fBq
Radioactivity in Becquerels (decay per sec) per cubic cm.
std::vector< double > fX1
Top corner x position (cm) in world coordinates.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
std::vector< double > fY0
Bottom corner y position (cm) in world coordinates.

Member Function Documentation

std::size_t evgen::RadioGen::addvolume ( std::string const &  volumeName)
private

Adds all volumes with the specified name to the coordinates. Volumes must be boxes aligned to the world frame axes.

Definition at line 431 of file RadioGen_module.cc.

431  {
432 
433  auto const& geom = *(lar::providerFrom<geo::Geometry>());
434 
435  std::vector<geo::GeoNodePath> volumePaths;
436  auto findVolume = [&volumePaths, volumeName](auto& path)
437  {
438  if (path.current().GetVolume()->GetName() == volumeName)
439  volumePaths.push_back(path);
440  return true;
441  };
442 
443  geo::ROOTGeometryNavigator navigator { *(geom.ROOTGeoManager()) };
444 
445  navigator.apply(findVolume);
446 
447  for (geo::GeoNodePath const& path: volumePaths) {
448 
449  //
450  // find the coordinates of the volume in local coordinates
451  //
452  TGeoShape const* pShape = path.current().GetVolume()->GetShape();
453  auto pBox = dynamic_cast<TGeoBBox const*>(pShape);
454  if (!pBox) {
455  throw cet::exception("RadioGen") << "Volume '"
456  << path.current().GetName() << "' is a " << pShape->IsA()->GetName()
457  << ", not a TGeoBBox.\n";
458  }
459 
460  geo::Point_t const origin
461  = geo::vect::makeFromCoords<geo::Point_t>(pBox->GetOrigin());
462  geo::Vector_t const diag
463  = { pBox->GetDX(), pBox->GetDY(), pBox->GetDZ() };
464 
465  //
466  // convert to world coordinates
467  //
468 
469  auto const trans
470  = path.currentTransformation<geo::TransformationMatrix>();
471 
473  trans.Transform(origin - diag, min);
474  trans.Transform(origin + diag, max);
475 
476  //
477  // add to the coordinates
478  //
479  fX0.push_back(std::min(min.X(), max.X()));
480  fY0.push_back(std::min(min.Y(), max.Y()));
481  fZ0.push_back(std::min(min.Z(), max.Z()));
482  fX1.push_back(std::max(min.X(), max.X()));
483  fY1.push_back(std::max(min.Y(), max.Y()));
484  fZ1.push_back(std::max(min.Z(), max.Z()));
485 
486  } // for
487 
488  return volumePaths.size();
489  } // RadioGen::addvolume()
bool apply(geo::GeoNodePath &path, Op &&op) const
Applies the specified operation to all nodes under the path.
std::vector< double > fZ0
Bottom corner z position (cm) in world coordinates.
Executes an operation on all the nodes of the ROOT geometry.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:164
std::vector< double > fY1
Top corner y position (cm) in world coordinates.
std::vector< double > fZ1
Top corner z position (cm) in world coordinates.
static int max(int a, int b)
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
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
Representation of a node and its ancestry.
Definition: GeoNodePath.h:38
std::vector< double > fX0
Bottom corner x position (cm) in world coordinates.
std::vector< double > fX1
Top corner x position (cm) in world coordinates.
ROOT::Math::Transform3D TransformationMatrix
Type of transformation matrix used in geometry.
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:227
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
std::vector< double > fY0
Bottom corner y position (cm) in world coordinates.
void evgen::RadioGen::Ar42Gamma2 ( std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &  v_prods)
private

Definition at line 872 of file RadioGen_module.cc.

873  {
874  ti_PDGID pdgid = 22; td_Mass m = 0.0; //we are writing gammas
875  std::vector<double> vd_p = {.0015246};//Momentum in GeV
876  for(auto p : vd_p){
877  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
878  }
879  }
TLorentzVector dirCalc(double p, double m)
p
Definition: test.py:223
void evgen::RadioGen::Ar42Gamma3 ( std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &  v_prods)
private

Definition at line 881 of file RadioGen_module.cc.

882  {
883  ti_PDGID pdgid = 22; td_Mass m = 0.0; //we are writing gammas
884  std::vector<double> vd_p = {.0003126};
885  for(auto p : vd_p){
886  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
887  }
888  Ar42Gamma2(v_prods);
889  }
TLorentzVector dirCalc(double p, double m)
p
Definition: test.py:223
void Ar42Gamma2(std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
void evgen::RadioGen::Ar42Gamma4 ( std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &  v_prods)
private

Definition at line 891 of file RadioGen_module.cc.

892  {
893  CLHEP::RandFlat flat(fEngine);
894  ti_PDGID pdgid = 22; td_Mass m = 0.0; //we are writing gammas
895  double chan1 = (0.052 / (0.052+0.020) );
896  if(flat.fire()<chan1){
897  std::vector<double> vd_p = {.0008997};//Momentum in GeV
898  for(auto p : vd_p){
899  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
900  }
901  Ar42Gamma2(v_prods);
902  }else{
903  std::vector<double> vd_p = {.0024243};//Momentum in GeV
904  for(auto p : vd_p){
905  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
906  }
907  }
908  }
TLorentzVector dirCalc(double p, double m)
p
Definition: test.py:223
void Ar42Gamma2(std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
CLHEP::HepRandomEngine & fEngine
void evgen::RadioGen::Ar42Gamma5 ( std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &  v_prods)
private

Definition at line 910 of file RadioGen_module.cc.

911  {
912  CLHEP::RandFlat flat(fEngine);
913  ti_PDGID pdgid = 22; td_Mass m = 0.0; //we are writing gammas
914  double chan1 = ( 0.0033 / (0.0033 + 0.0201 + 0.041) ); double chan2 = ( 0.0201 / (0.0033 + 0.0201 + 0.041) );
915  double chanPick = flat.fire();
916  if(chanPick < chan1){
917  std::vector<double> vd_p = {0.000692, 0.001228};//Momentum in GeV
918  for(auto p : vd_p){
919  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
920  }
921  Ar42Gamma2(v_prods);
922  }else if (chanPick<(chan1+chan2)){
923  std::vector<double> vd_p = {0.0010212};//Momentum in GeV
924  for(auto p : vd_p){
925  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
926  }
927  Ar42Gamma4(v_prods);
928  }else{
929  std::vector<double> vd_p = {0.0019208};//Momentum in GeV
930  for(auto p : vd_p){
931  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
932  }
933  Ar42Gamma2(v_prods);
934  }
935  }
TLorentzVector dirCalc(double p, double m)
p
Definition: test.py:223
void Ar42Gamma2(std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
CLHEP::HepRandomEngine & fEngine
void Ar42Gamma4(std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
void evgen::RadioGen::beginRun ( art::Run run)
privatevirtual

Reimplemented from art::EDProducer.

Definition at line 405 of file RadioGen_module.cc.

406  {
408  run.put(std::make_unique<sumdata::RunData>(geo->DetectorName()));
409  }
std::string DetectorName() const
Returns a string with the name of the detector, as configured.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
LArSoft geometry interface.
Definition: ChannelGeo.h:16
std::pair< double, double > evgen::RadioGen::defaulttimewindow ( ) const
private

Returns the start and end of the readout window.

Definition at line 979 of file RadioGen_module.cc.

979  {
980  // values are in simulation time scale (and therefore in [ns])
981  using namespace detinfo::timescales;
982 
983  auto const& timings = detinfo::makeDetectorTimings
985  detinfo::DetectorPropertiesData const& detInfo
987 
988  //
989  // we take a number of (TPC electronics) ticks before the trigger time,
990  // and we go to a number of ticks after the trigger time;
991  // that shift is one readout window size
992  //
993 
994  auto const trigTimeTick
995  = timings.toTick<electronics_tick>(timings.TriggerTime());
996  electronics_time_ticks const beforeTicks
997  { -static_cast<int>(detInfo.ReadOutWindowSize()) };
998  electronics_time_ticks const afterTicks { detInfo.NumberTimeSamples() };
999 
1000  return {
1001  double(timings.toTimeScale<simulation_time>(trigTimeTick + beforeTicks)),
1002  double(timings.toTimeScale<simulation_time>(trigTimeTick + afterTicks))
1003  };
1004  } // RadioGen::defaulttimewindow()
timescale_traits< ElectronicsTimeCategory >::tick_t electronics_tick
A point on the electronics time scale expressed in its ticks.
timescale_traits< ElectronicsTimeCategory >::tick_interval_t electronics_time_ticks
An interval on the electronics time scale expressed in its ticks.
timescale_traits< SimulationTimeCategory >::time_point_t simulation_time
A point in time on the simulation time scale.
detinfo::DetectorTimings makeDetectorTimings(detinfo::DetectorClocksData const &detClocks)
Namespace including different time scales as defined in LArSoft.
TLorentzVector evgen::RadioGen::dirCalc ( double  p,
double  m 
)
private

Definition at line 606 of file RadioGen_module.cc.

607  {
608  CLHEP::RandFlat flat(fEngine);
609  // isotropic production angle for the decay product
610  double costheta = (2.0*flat.fire() - 1.0);
611  if (costheta < -1.0) costheta = -1.0;
612  if (costheta > 1.0) costheta = 1.0;
613  double const sintheta = sqrt(1.0-costheta*costheta);
614  double const phi = 2.0*M_PI*flat.fire();
615  return TLorentzVector{p*sintheta*std::cos(phi),
616  p*sintheta*std::sin(phi),
617  p*costheta,
618  std::sqrt(p*p+m*m)};
619  }
p
Definition: test.py:223
#define M_PI
Definition: includeROOT.h:54
CLHEP::HepRandomEngine & fEngine
template<typename Stream >
void evgen::RadioGen::dumpNuclideSettings ( Stream &&  out,
std::size_t  iNucl,
std::string const &  volumeName = {} 
) const
private

Prints the settings for the specified nuclide and volume.

Definition at line 962 of file RadioGen_module.cc.

964  {
965 
966  out << "[#" << iNucl << "] "
967  << fNuclide[iNucl]
968  << " (" << fBq[iNucl] << " Bq/cm^3)"
969  << " in " << fMaterial[iNucl]
970  << " from " << fT0[iNucl] << " to " << fT1[iNucl] << " ns in ( "
971  << fX0[iNucl] << ", " << fY0[iNucl] << ", " << fZ0[iNucl] << ") to ( "
972  << fX1[iNucl] << ", " << fY1[iNucl] << ", " << fZ1[iNucl] << ")";
973  if (!volumeName.empty()) out << " (\"" << volumeName << "\")";
974 
975  } // RadioGen::dumpNuclideSettings()
std::vector< double > fZ0
Bottom corner z position (cm) in world coordinates.
std::vector< std::string > fNuclide
List of nuclides to simulate. Example: "39Ar".
std::vector< double > fT1
End of time window to simulate in ns.
std::vector< double > fY1
Top corner y position (cm) in world coordinates.
std::vector< double > fZ1
Top corner z position (cm) in world coordinates.
std::vector< double > fT0
Beginning of time window to simulate in ns.
std::vector< std::string > fMaterial
List of regexes of materials in which to generate the decays. Example: "LAr".
std::vector< double > fX0
Bottom corner x position (cm) in world coordinates.
std::vector< double > fBq
Radioactivity in Becquerels (decay per sec) per cubic cm.
std::vector< double > fX1
Top corner x position (cm) in world coordinates.
std::vector< double > fY0
Bottom corner y position (cm) in world coordinates.
void evgen::RadioGen::produce ( art::Event evt)
privatevirtual

unique_ptr allows ownership to be transferred to the art::Event after the put statement

Implements art::EDProducer.

Definition at line 412 of file RadioGen_module.cc.

413  {
414  ///unique_ptr allows ownership to be transferred to the art::Event after the put statement
415  std::unique_ptr< std::vector<simb::MCTruth> > truthcol(new std::vector<simb::MCTruth>);
416 
417  simb::MCTruth truth;
419 
420  trackidcounter = -1;
421  for (unsigned int i=0; i<fNuclide.size(); ++i) {
422  SampleOne(i,truth);
423  }//end loop over nuclides
424 
425  MF_LOG_DEBUG("RadioGen") << truth;
426  truthcol->push_back(truth);
427  evt.put(std::move(truthcol));
428  }
void SetOrigin(simb::Origin_t origin)
Definition: MCTruth.h:82
std::vector< std::string > fNuclide
List of nuclides to simulate. Example: "39Ar".
single particles thrown at the detector
Definition: MCTruth.h:26
def move(depos, offset)
Definition: depos.py:107
int trackidcounter
Serial number for the MC track ID.
void SampleOne(unsigned int i, simb::MCTruth &mct)
Checks that the node represents a box well aligned to world frame axes.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
#define MF_LOG_DEBUG(id)
Event generator information.
Definition: MCTruth.h:32
void evgen::RadioGen::readfile ( std::string  nuclide,
std::string const &  filename 
)
private

Definition at line 623 of file RadioGen_module.cc.

624  {
625  bool found{false};
626  std::regex const re_argon{"42Ar.*"};
627  for (size_t i=0; i<fNuclide.size(); i++)
628  {
629  if (fNuclide[i] == nuclide){ //This check makes sure that the nuclide we are searching for is in fact in our fNuclide list. Ar42 handeled separately.
630  found = true;
631  break;
632  } //End If nuclide is in our list. Next is the special case of Ar42
633  else if (std::regex_match(nuclide, re_argon) && fNuclide[i]=="42Ar") {
634  found = true;
635  break;
636  }
637  }
638  if (!found) return;
639 
640  Bool_t addStatus = TH1::AddDirectoryStatus();
641  TH1::AddDirectory(kFALSE); // cloned histograms go in memory, and aren't deleted when files are closed.
642  // be sure to restore this state when we're out of the routine.
643 
644  spectrumname.push_back(nuclide);
645  cet::search_path sp("FW_SEARCH_PATH");
646  std::string fn2 = "Radionuclides/";
647  fn2 += filename;
648  std::string fullname;
649  sp.find_file(fn2, fullname);
650  struct stat sb;
651  if (fullname.empty() || stat(fullname.c_str(), &sb)!=0)
652  throw cet::exception("RadioGen") << "Input spectrum file "
653  << fn2
654  << " not found in FW_SEARCH_PATH!\n";
655 
656  TFile f(fullname.c_str(),"READ");
657  TGraph *alphagraph = (TGraph*) f.Get("Alphas");
658  TGraph *betagraph = (TGraph*) f.Get("Betas");
659  TGraph *gammagraph = (TGraph*) f.Get("Gammas");
660  TGraph *neutrongraph = (TGraph*) f.Get("Neutrons");
661 
662  if (alphagraph)
663  {
664  int np = alphagraph->GetN();
665  double *y = alphagraph->GetY();
667  name = "RadioGen_";
668  name += nuclide;
669  name += "_Alpha";
670  auto alphahist = std::make_unique<TH1D>(name.c_str(),"Alpha Spectrum",np,0,np);
671  for (int i=0; i<np; i++) {
672  alphahist->SetBinContent(i+1,y[i]);
673  alphahist->SetBinError(i+1,0);
674  }
675  alphaintegral.push_back(alphahist->Integral());
676  alphaspectrum.push_back(move(alphahist));
677  }
678  else
679  {
680  alphaintegral.push_back(0);
681  alphaspectrum.push_back(nullptr);
682  }
683 
684 
685  if (betagraph)
686  {
687  int np = betagraph->GetN();
688 
689  double *y = betagraph->GetY();
691  name = "RadioGen_";
692  name += nuclide;
693  name += "_Beta";
694  auto betahist = std::make_unique<TH1D>(name.c_str(),"Beta Spectrum",np,0,np);
695  for (int i=0; i<np; i++) {
696  betahist->SetBinContent(i+1,y[i]);
697  betahist->SetBinError(i+1,0);
698  }
699  betaintegral.push_back(betahist->Integral());
700  betaspectrum.push_back(move(betahist));
701  }
702  else
703  {
704  betaintegral.push_back(0);
705  betaspectrum.push_back(nullptr);
706  }
707 
708  if (gammagraph)
709  {
710  int np = gammagraph->GetN();
711  double *y = gammagraph->GetY();
713  name = "RadioGen_";
714  name += nuclide;
715  name += "_Gamma";
716  auto gammahist = std::make_unique<TH1D>(name.c_str(),"Gamma Spectrum",np,0,np);
717  for (int i=0; i<np; i++) {
718  gammahist->SetBinContent(i+1,y[i]);
719  gammahist->SetBinError(i+1,0);
720  }
721  gammaintegral.push_back(gammahist->Integral());
722  gammaspectrum.push_back(move(gammahist));
723  }
724  else
725  {
726  gammaintegral.push_back(0);
727  gammaspectrum.push_back(nullptr);
728  }
729 
730  if (neutrongraph)
731  {
732  int np = neutrongraph->GetN();
733  double *y = neutrongraph->GetY();
735  name = "RadioGen_";
736  name += nuclide;
737  name += "_Neutron";
738  auto neutronhist = std::make_unique<TH1D>(name.c_str(),"Neutron Spectrum",np,0,np);
739  for (int i=0; i<np; i++)
740  {
741  neutronhist->SetBinContent(i+1,y[i]);
742  neutronhist->SetBinError(i+1,0);
743  }
744  neutronintegral.push_back(neutronhist->Integral());
745  neutronspectrum.push_back(move(neutronhist));
746  }
747  else
748  {
749  neutronintegral.push_back(0);
750  neutronspectrum.push_back(nullptr);
751  }
752 
753  f.Close();
754  TH1::AddDirectory(addStatus);
755 
756  double total = alphaintegral.back() + betaintegral.back() + gammaintegral.back() + neutronintegral.back();
757  if (total>0)
758  {
759  alphaintegral.back() /= total;
760  betaintegral.back() /= total;
761  gammaintegral.back() /= total;
762  neutronintegral.back() /= total;
763  }
764  }
static QCString name
Definition: declinfo.cpp:673
std::vector< std::unique_ptr< TH1D > > gammaspectrum
std::vector< std::string > fNuclide
List of nuclides to simulate. Example: "39Ar".
std::string string
Definition: nybbler.cc:12
string filename
Definition: train.py:213
std::vector< double > neutronintegral
std::vector< std::string > spectrumname
std::vector< std::unique_ptr< TH1D > > alphaspectrum
def move(depos, offset)
Definition: depos.py:107
std::vector< double > alphaintegral
std::vector< double > betaintegral
std::vector< std::unique_ptr< TH1D > > neutronspectrum
std::vector< double > gammaintegral
std::vector< std::unique_ptr< TH1D > > betaspectrum
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
double evgen::RadioGen::samplefromth1d ( TH1D &  hist)
private

Definition at line 835 of file RadioGen_module.cc.

836  {
837  CLHEP::RandFlat flat(fEngine);
838 
839  int nbinsx = hist.GetNbinsX();
840  std::vector<double> partialsum;
841  partialsum.resize(nbinsx+1);
842  partialsum[0] = 0;
843 
844  for (int i=1;i<=nbinsx;i++)
845  {
846  double hc = hist.GetBinContent(i);
847  if ( hc < 0) throw cet::exception("RadioGen") << "Negative bin: " << i << " " << hist.GetName() << "\n";
848  partialsum[i] = partialsum[i-1] + hc;
849  }
850  double integral = partialsum[nbinsx];
851  if (integral == 0) return 0;
852  // normalize to unit sum
853  for (int i=1;i<=nbinsx;i++) partialsum[i] /= integral;
854 
855  double r1 = flat.fire();
856  int ibin = TMath::BinarySearch(nbinsx,&(partialsum[0]),r1);
857  Double_t x = hist.GetBinLowEdge(ibin+1);
858  if (r1 > partialsum[ibin]) {
859  x += hist.GetBinWidth(ibin+1)*(r1-partialsum[ibin])/(partialsum[ibin+1] - partialsum[ibin]);
860  }
861  return x;
862  }
CLHEP::HepRandomEngine & fEngine
list x
Definition: train.py:276
nbinsx
New: trying to make a variation.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void evgen::RadioGen::SampleOne ( unsigned int  i,
simb::MCTruth mct 
)
private

Checks that the node represents a box well aligned to world frame axes.

Definition at line 495 of file RadioGen_module.cc.

496  {
498  TGeoManager *geomanager = geo->ROOTGeoManager();
499 
500  CLHEP::RandFlat flat(fEngine);
501  CLHEP::RandPoisson poisson(fEngine);
502 
503  // figure out how many decays to generate, assuming that the entire prism consists of the radioactive material.
504  // we will skip over decays in other materials later.
505 
506  double rate = fabs( fBq[i] * (fT1[i] - fT0[i]) * (fX1[i] - fX0[i]) * (fY1[i] - fY0[i]) * (fZ1[i] - fZ0[i]) ) / 1.0E9;
507  long ndecays = poisson.shoot(rate);
508 
509  std::regex const re_material{fMaterial[i]};
510  for (unsigned int idecay=0; idecay<ndecays; idecay++)
511  {
512  // generate just one particle at a time. Need a little recoding if a radioactive
513  // decay generates multiple daughters that need simulation
514  // uniformly distributed in position and time
515  //
516  // JStock: Leaving this as a single position for the decay products. For now I will assume they all come from the same spot.
517  TLorentzVector pos( fX0[i] + flat.fire()*(fX1[i] - fX0[i]),
518  fY0[i] + flat.fire()*(fY1[i] - fY0[i]),
519  fZ0[i] + flat.fire()*(fZ1[i] - fZ0[i]),
520  (idecay==0 && fIsFirstSignalSpecial) ? 0 : ( fT0[i] + flat.fire()*(fT1[i] - fT0[i]) ) );
521 
522  // discard decays that are not in the proper material
523  std::string volmaterial = geomanager->FindNode(pos.X(),pos.Y(),pos.Z())->GetMedium()->GetMaterial()->GetName();
524  if (!std::regex_match(volmaterial, re_material)) continue;
525 
526  //Moved pdgid into the next statement, so that it is localized.
527  // electron=11, photon=22, alpha = 1000020040, neutron = 2112
528 
529  //JStock: Allow us to have different particles from the same decay. This requires multiple momenta.
530  std::vector<std::tuple<ti_PDGID, td_Mass, TLorentzVector>> v_prods; //(First is for PDGID, second is mass, third is Momentum)
531 
532  if (fNuclide[i] == "222Rn") // Treat 222Rn separately
533  {
534  double p=0; double t=0.00548952; td_Mass m=m_alpha; ti_PDGID pdgid=1000020040; //td_Mass = double. ti_PDGID = int;
535  double energy = t + m;
536  double p2 = energy*energy - m*m;
537  if (p2 > 0) p = TMath::Sqrt(p2);
538  else p = 0;
539  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
540  }//End special case RN222
541  else if(fNuclide[i] == "59Ni"){ //Treat 59Ni Calibration Source separately (as I haven't made a spectrum for it, and ultimately it should be handeled with multiple particle outputs.
542  double p=0.008997; td_Mass m=0; ti_PDGID pdgid=22; // td_Mas=double. ti_PDFID=int. Assigning p directly, as t=p for gammas.
543  v_prods.emplace_back(pdgid, m, dirCalc(p,m));
544  }//end special case Ni59 calibration source
545  else if(fNuclide[i] == "42Ar"){ // Spot for special treatment of Ar42.
546  double p=0; double t=0; td_Mass m = 0; ti_PDGID pdgid=0; //td_Mass = double. ti_PDGID = int;
547  double bSelect = flat.fire(); //Make this a random number from 0 to 1.
548  if(bSelect<0.819){ //beta channel 1. No Gamma. beta Q value 3525.22 keV
549  samplespectrum("42Ar_1", pdgid, t, m, p);
550  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
551  //No gamma here.
552  }else if(bSelect<0.9954){ //beta channel 2. 1 Gamma (1524.6 keV). beta Q value 2000.62
553  samplespectrum("42Ar_2", pdgid, t, m, p);
554  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
555  Ar42Gamma2(v_prods);
556  }else if(bSelect<0.9988){ //beta channel 3. 1 Gamma Channel. 312.6 keV + gamma 2. beta Q value 1688.02 keV
557  samplespectrum("42Ar_3", pdgid, t, m, p);
558  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
559  Ar42Gamma3(v_prods);
560  }else if(bSelect<0.9993){ //beta channel 4. 2 Gamma Channels. Either 899.7 keV (i 0.052) + gamma 2 or 2424.3 keV (i 0.020). beta Q value 1100.92 keV
561  samplespectrum("42Ar_4", pdgid, t, m, p);
562  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
563  Ar42Gamma4(v_prods);
564  }else{ //beta channel 5. 3 gamma channels. 692.0 keV + 1228.0 keV + Gamma 2 (i 0.0033) ||OR|| 1021.2 keV + gamma 4 (i 0.0201) ||OR|| 1920.8 keV + gamma 2 (i 0.041). beta Q value 79.82 keV
565  samplespectrum("42Ar_5", pdgid, t, m, p);
566  v_prods.emplace_back(pdgid, m, dirCalc(p, m));
567  Ar42Gamma5(v_prods);
568  }
569  //Add beta.
570  //Call gamma function for beta mode.
571  }
572  else{ //General Case.
573  double p=0; double t=0; td_Mass m = 0; ti_PDGID pdgid=0; //td_Mass = double. ti_PDGID = int;
574  samplespectrum(fNuclide[i],pdgid,t,m,p);
575  std::tuple<ti_PDGID, td_Mass, TLorentzVector> partMassMom = std::make_tuple(pdgid, m, dirCalc(p,m));
576  v_prods.push_back(partMassMom);
577  }//end else (not RN or other special case
578 
579  //JStock: Modify this to now loop over the v_prods.
580  for(auto prodEntry : v_prods){
581  // set track id to a negative serial number as these are all primary particles and have id <= 0
582  int trackid = trackidcounter;
583  ti_PDGID pdgid = std::get<0>(prodEntry);
584  td_Mass m = std::get<1>(prodEntry);
585  TLorentzVector pvec = std::get<2>(prodEntry);
586  trackidcounter--;
587  std::string primary("primary");
588 
589  // alpha particles need a little help since they're not in the TDatabasePDG table
590  // // so don't rely so heavily on default arguments to the MCParticle constructor
591  if (pdgid == 1000020040){
592  simb::MCParticle part(trackid, pdgid, primary,-1,m,1);
593  part.AddTrajectoryPoint(pos, pvec);
594  mct.Add(part);
595  }// end "If alpha"
596  else{
597  simb::MCParticle part(trackid, pdgid, primary);
598  part.AddTrajectoryPoint(pos, pvec);
599  mct.Add(part);
600  }// end All standard cases.
601  }//End Loop over all particles produces in this single decay.
602  }
603  }
TLorentzVector dirCalc(double p, double m)
std::vector< double > fZ0
Bottom corner z position (cm) in world coordinates.
std::vector< std::string > fNuclide
List of nuclides to simulate. Example: "39Ar".
std::string string
Definition: nybbler.cc:12
void Ar42Gamma5(std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
TGeoManager * ROOTGeoManager() const
Access to the ROOT geometry description manager.
std::vector< double > fT1
End of time window to simulate in ns.
std::vector< double > fY1
Top corner y position (cm) in world coordinates.
std::vector< double > fZ1
Top corner z position (cm) in world coordinates.
int trackidcounter
Serial number for the MC track ID.
void Ar42Gamma3(std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
p
Definition: test.py:223
void samplespectrum(std::string nuclide, int &itype, double &t, double &m, double &p)
void Add(simb::MCParticle const &part)
Definition: MCTruth.h:80
void Ar42Gamma2(std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
CLHEP::HepRandomEngine & fEngine
std::vector< double > fT0
Beginning of time window to simulate in ns.
void Ar42Gamma4(std::vector< std::tuple< ti_PDGID, td_Mass, TLorentzVector >> &v_prods)
std::vector< std::string > fMaterial
List of regexes of materials in which to generate the decays. Example: "LAr".
std::vector< double > fX0
Bottom corner x position (cm) in world coordinates.
std::vector< double > fBq
Radioactivity in Becquerels (decay per sec) per cubic cm.
LArSoft geometry interface.
Definition: ChannelGeo.h:16
std::vector< double > fX1
Top corner x position (cm) in world coordinates.
std::vector< double > fY0
Bottom corner y position (cm) in world coordinates.
void evgen::RadioGen::samplespectrum ( std::string  nuclide,
int &  itype,
double &  t,
double &  m,
double &  p 
)
private

Definition at line 767 of file RadioGen_module.cc.

768  {
769  CLHEP::RandFlat flat(fEngine);
770 
771  int inuc = -1;
772  for (size_t i=0; i<spectrumname.size(); i++)
773  {
774  if (nuclide == spectrumname[i])
775  {
776  inuc = i;
777  break;
778  }
779  }
780  if (inuc == -1)
781  {
782  t=0; // throw an exception in the future
783  itype = 0;
784  throw cet::exception("RadioGen") << "Ununderstood nuclide: " << nuclide << "\n";
785  }
786 
787  double rtype = flat.fire();
788 
789  itype = -1;
790  m = 0;
791  p = 0;
792  for (int itry=0;itry<10;itry++) // maybe a tiny normalization issue with a sum of 0.99999999999 or something, so try a few times.
793  {
794  if (rtype <= alphaintegral[inuc] && alphaspectrum[inuc] != nullptr)
795  {
796  itype = 1000020040; // alpha
797  m = m_alpha;
798  t = samplefromth1d(*alphaspectrum[inuc])/1000000.0;
799  }
800  else if (rtype <= alphaintegral[inuc]+betaintegral[inuc] && betaspectrum[inuc] != nullptr)
801  {
802  itype = 11; // beta
803  m = m_e;
804  t = samplefromth1d(*betaspectrum[inuc])/1000000.0;
805  }
806  else if ( rtype <= alphaintegral[inuc] + betaintegral[inuc] + gammaintegral[inuc] && gammaspectrum[inuc] != nullptr)
807  {
808  itype = 22; // gamma
809  m = 0;
810  t = samplefromth1d(*gammaspectrum[inuc])/1000000.0;
811  }
812  else if( neutronspectrum[inuc] != nullptr)
813  {
814  itype = 2112;
815  m = m_neutron;
816  t = samplefromth1d(*neutronspectrum[inuc])/1000000.0;
817  }
818  if (itype >= 0) break;
819  }
820  if (itype == -1)
821  {
822  throw cet::exception("RadioGen") << "Normalization problem with nuclide: " << nuclide << "\n";
823  }
824  double e = t + m;
825  p = e*e - m*m;
826  if (p>=0)
827  { p = TMath::Sqrt(p); }
828  else
829  { p=0; }
830  }
std::vector< std::unique_ptr< TH1D > > gammaspectrum
std::vector< std::string > spectrumname
std::vector< std::unique_ptr< TH1D > > alphaspectrum
const double e
p
Definition: test.py:223
double samplefromth1d(TH1D &hist)
std::vector< double > alphaintegral
std::vector< double > betaintegral
CLHEP::HepRandomEngine & fEngine
std::vector< std::unique_ptr< TH1D > > neutronspectrum
std::vector< double > gammaintegral
std::vector< std::unique_ptr< TH1D > > betaspectrum
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33

Member Data Documentation

std::vector<double> evgen::RadioGen::alphaintegral
private

Definition at line 259 of file RadioGen_module.cc.

std::vector<std::unique_ptr<TH1D> > evgen::RadioGen::alphaspectrum
private

Definition at line 258 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::betaintegral
private

Definition at line 261 of file RadioGen_module.cc.

std::vector<std::unique_ptr<TH1D> > evgen::RadioGen::betaspectrum
private

Definition at line 260 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::fBq
private

Radioactivity in Becquerels (decay per sec) per cubic cm.

Definition at line 240 of file RadioGen_module.cc.

CLHEP::HepRandomEngine& evgen::RadioGen::fEngine
private

Definition at line 266 of file RadioGen_module.cc.

bool evgen::RadioGen::fIsFirstSignalSpecial
private

Definition at line 249 of file RadioGen_module.cc.

std::vector<std::string> evgen::RadioGen::fMaterial
private

List of regexes of materials in which to generate the decays. Example: "LAr".

Definition at line 239 of file RadioGen_module.cc.

std::vector<std::string> evgen::RadioGen::fNuclide
private

List of nuclides to simulate. Example: "39Ar".

Definition at line 238 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::fT0
private

Beginning of time window to simulate in ns.

Definition at line 241 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::fT1
private

End of time window to simulate in ns.

Definition at line 242 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::fX0
private

Bottom corner x position (cm) in world coordinates.

Definition at line 243 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::fX1
private

Top corner x position (cm) in world coordinates.

Definition at line 246 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::fY0
private

Bottom corner y position (cm) in world coordinates.

Definition at line 244 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::fY1
private

Top corner y position (cm) in world coordinates.

Definition at line 247 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::fZ0
private

Bottom corner z position (cm) in world coordinates.

Definition at line 245 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::fZ1
private

Top corner z position (cm) in world coordinates.

Definition at line 248 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::gammaintegral
private

Definition at line 263 of file RadioGen_module.cc.

std::vector<std::unique_ptr<TH1D> > evgen::RadioGen::gammaspectrum
private

Definition at line 262 of file RadioGen_module.cc.

std::vector<double> evgen::RadioGen::neutronintegral
private

Definition at line 265 of file RadioGen_module.cc.

std::vector<std::unique_ptr<TH1D> > evgen::RadioGen::neutronspectrum
private

Definition at line 264 of file RadioGen_module.cc.

std::vector<std::string> evgen::RadioGen::spectrumname
private

Definition at line 257 of file RadioGen_module.cc.

int evgen::RadioGen::trackidcounter
private

Serial number for the MC track ID.

Definition at line 250 of file RadioGen_module.cc.


The documentation for this class was generated from the following file: