LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
larg4::LArG4 Class Reference

Runs Geant4 simulation and propagation of electrons and photons to readout. More...

Inheritance diagram for larg4::LArG4:
art::EDProducer art::ProducerBase art::Consumer art::EngineCreator art::ProductRegistryHelper

Public Types

using ModuleType = EDProducer
 
using WorkerType = WorkerT< EDProducer >
 
template<typename UserConfig , typename KeysToIgnore = void>
using Table = ProducerBase::Table< UserConfig, KeysToIgnore >
 

Public Member Functions

 LArG4 (fhicl::ParameterSet const &pset)
 Standard constructor and destructor for an FMWK module. More...
 
virtual ~LArG4 ()
 
void produce (art::Event &evt)
 
void beginJob ()
 
void beginRun (art::Run &run)
 
template<typename PROD , BranchType B = InEvent>
ProductID getProductID (std::string const &instanceName={}) const
 
template<typename PROD , BranchType B>
ProductID getProductID (ModuleDescription const &moduleDescription, std::string const &instanceName) const
 
bool modifiesEvent () const
 
template<typename T , BranchType = InEvent>
ProductToken< T > consumes (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ProductToken< T > consumes (InputTag const &it)
 
template<typename T , BranchType = InEvent>
void consumesMany ()
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > consumesView (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ViewToken< T > consumesView (InputTag const &it)
 
template<typename T , BranchType = InEvent>
ProductToken< T > mayConsume (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ProductToken< T > mayConsume (InputTag const &it)
 
template<typename T , BranchType = InEvent>
void mayConsumeMany ()
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > mayConsumeView (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ViewToken< T > mayConsumeView (InputTag const &it)
 
base_engine_tcreateEngine (seed_t seed)
 
base_engine_tcreateEngine (seed_t seed, std::string const &kind_of_engine_to_make)
 
base_engine_tcreateEngine (seed_t seed, std::string const &kind_of_engine_to_make, label_t const &engine_label)
 
seed_t get_seed_value (fhicl::ParameterSet const &pset, char const key[]="seed", seed_t const implicit_seed=-1)
 

Static Public Member Functions

static cet::exempt_ptr< Consumernon_module_context ()
 

Protected Member Functions

CurrentProcessingContext const * currentContext () const
 
void validateConsumedProduct (BranchType const bt, ProductInfo const &pi)
 
void prepareForJob (fhicl::ParameterSet const &pset)
 
void showMissingConsumes () const
 

Private Member Functions

std::unique_ptr< util::PositionInVolumeFilterCreateParticleVolumeFilter (std::set< std::string > const &vol_names) const
 Configures and returns a particle filter. More...
 

Private Attributes

g4b::G4HelperfG4Help
 G4 interface object. More...
 
larg4::LArVoxelListAction * flarVoxelListAction
 Geant4 user action to accumulate LAr voxel information. More...
 
larg4::ParticleListActionfparticleListAction
 Geant4 user action to particle information. More...
 
std::string fG4PhysListName
 predefined physics list to use if not making a custom one More...
 
std::string fG4MacroPath
 
bool fCheckOverlaps
 Whether to use the G4 overlap checker. More...
 
bool fdumpParticleList
 Whether each event's sim::ParticleList will be displayed. More...
 
bool fdumpSimChannels
 Whether each event's sim::Channel will be displayed. More...
 
bool fUseLitePhotons
 
bool fStoreReflected
 
int fSmartStacking
 Whether to instantiate and use class to. More...
 
double fOffPlaneMargin = 0.
 dictate how tracks are put on stack. More...
 
std::vector< std::string > fInputLabels
 
std::vector< std::string > fKeepParticlesInVolumes
 Only write particles that have trajectories through these volumes. More...
 
bool fSparsifyTrajectories
 Sparsify MCParticle Trajectories. More...
 

Detailed Description

Runs Geant4 simulation and propagation of electrons and photons to readout.

This module collects generated particles from one or more generators and processes them through Geant4.

Input

The module reads the particles to process from simb::MCTruth records. Each particle generator is required to produce a vector of such records: std::vector<simb::MCTruth>.

The module allows two operation modes:

  1. process specific generators: the label of the generator modules to be processed is specified explicitly in LArG4 configuration
  2. process all truth information generated so far: no generator is specified in the LArG4 module configuration, and the module will process all data products of type std::vector<simb::MCTruth>, in a non-specified order

For each simb::MCTruth, a Geant4 run is started. The interface with Geant4 is via a helper class provided by nutools. Only the particles in the truth record which have status code (simb::MCParticle::StatusCode()) equal to 1 are processed. These particles are called, in LArG4 jargon, primaries.

Output

The LArG4 module produces:

  • a collection of sim::SimChannel: each sim::SimChannel represents the set of energy depositions in liquid argon which drifted and were observed on a certain channel; it includes physics effects like attenuation, diffusion, electric field distortion, etc. Information of the generating Geant4 "track" is retained;
  • a collection of sim::SimPhotons or sim::SimPhotonsLite: each sim::SimPhotons represents the set of individual photons reaching a channel of the optical detector; it includes physics effects as well as quantum efficiency of the detector (to reduce data size early in the process); sim::SimPhotonsLite drops the information of the single photons and stores only collective information (e.g. their number).
  • a collection of sim::OpDetBacktrackerRecord (to be documented)
  • a collection of sim::AuxDetSimChannel (to be documented)
  • a collection of simb::MCParticle: the particles generated in the interaction of the primary particles with the material in the world are stored, but minor filtering by geometry and by physics is possible. An association of them with the originating simb::MCTruth object is also produced.

Notes on the conventions

  • all and the particles in the truth record (simb::MCTruth) which have status code (simb::MCParticle::StatusCode()) equal to 1 are passed to Geant4. These particles are called, in LArG4 jargon, primaries. The interface with Geant4 is via a helper class provided by nutools.
  • normally, information about each particle that Geant4 propagates (which Geant4 calls tracks), primary or not, is saved as an individual simb::MCParticle object into the output particle list. Each simb::MCParticle includes a Geant4-like track ID which is also recorded into each sim::IDE deposited by that particle. This information can be used to track all the deposition from a particle, or to backtrack the particle responsible of a deposition (but see below...). Note that the stored track ID may be different than the one Geant4 used (and, in particular, it's guaranteed to be unique within a sim::LArG4 instance output).
  • there are options (some set in sim::LArG4Parameters service) which allow for Geant4 tracks not to be saved as simb::MCParticle (e.g. ParticleKineticEnergyCut, KeepEMShowerDaughters). When these particles have deposited energy, their sim::IDE will report the ID of the first parent Geant4 track which is saved in the simb::MCParticle list, but with its sign flipped. Therefore, when tracking or backtracking (see above), comparisons should be performed using the absolute value of the sim::IDE (e.g. std::abs(ide.trackID)).

Timing

The LArG4 module produces sim::SimChannel objects from generated simb::MCParticle. Each particle ("primary") is assigned the time taken from its vertex (a 4-vector), which is expected to be represented in nanoseconds. The sim::SimChannel object is a collection of sim::IDE in time. The position in the sim::IDE is the location where some ionization occurred. The time associated to a sim::IDE is stored in tick units. The time it represents is the time when the ionization happened, which is the time of the primary particle plus the propagation time to the ionization location, plus the drift time, which the ionized electrons take to reach the anode wire. This time is then shifted to the frame of the electronics time via detinfo::DetectorClocks::G4ToElecTime(), which adds a configurable time offset. The time is converted into ticks via detinfo::DetectorClocks::TPCClock(), and this is the final value associated to the sim::IDE. For a more complete overview, see https://cdcvs.fnal.gov/redmine/projects/larsoft/wiki/Simulation#Simulation-Timing

Randomness

The random number generators used by this process are:

  • 'GEANT' instance: used by Geant4
  • 'propagation' instance: used in electron propagation

Configuration parameters

  • G4PhysListName (string, default: "larg4::PhysicsList"): whether to use the G4 overlap checker, which catches different issues than ROOT
  • CheckOverlaps (bool, default: false): whether to use the G4 overlap checker
  • DumpParticleList (bool, default: false): whether to print all MCParticles tracked
  • DumpSimChannels (bool, default: false): whether to print all depositions on each SimChannel
  • SmartStacking (int, default: 0): whether to use class to dictate how tracks are put on stack (nonzero is on)
  • KeepParticlesInVolumes (list of strings, default: empty): list of volumes in which to keep simb::MCParticle objects (empty keeps all)
  • GeantCommandFile (string, required): G4 macro file to pass to G4Helper for setting G4 command
  • Seed (integer, not defined by default): if defined, override the seed for random number generator used in Geant4 simulation (which is obtained from NuRandomService by default)
  • PropagationSeed (integer, not defined by default): if defined, override the seed for the random generator used for electrons propagation to the wire planes (obtained from the NuRandomService by default)
  • InputLabels (list of strings, default: process all truth): optional list of generator labels whose produced simb::MCTruth will be simulated; if not specified, all simb::MCTruth vector data products are simulated
  • ChargeRecoveryMargin (double, default: 0): sets the maximum distance from a plane for the wire charge recovery to occur, in centimeters; for details on how it works, see larg4::LArVoxelReadout::SetOffPlaneChargeRecoveryMargin(). A value of 0 effectively disables this feature. All TPCs will have the same margin applied.

Simulation details

Reflectivity to optical photons

Two models are supported for the simulation of (scintillation) light crossing detector surfaces:

  1. the standard one from GEANT4, implemented in G4OpBoundaryProcess
  2. a simplified one, implemented in larg4::OpBoundaryProcessSimple

The model is chosen according to the value of detinfo::DetectorProperties::SimpleBoundary(), and the choice is currently exerted by larg4::OpticalPhysics.

The simplified model is faster and simpler: it only deals with absorption and reflection (both specular and diffues). This is the "default" model used in most contexts.

GEANT4 model is more complete and slower. It may take some art to fully configure all the properties of the materials at the sides of the surfaces. The price is a detailed simulation that includes among others refraction and wavelength shifting.

Definition at line 297 of file LArG4_module.cc.

Member Typedef Documentation

using art::EDProducer::ModuleType = EDProducer
inherited

Definition at line 34 of file EDProducer.h.

template<typename UserConfig , typename KeysToIgnore = void>
using art::EDProducer::Table = ProducerBase::Table<UserConfig, KeysToIgnore>
inherited

Definition at line 43 of file EDProducer.h.

using art::EDProducer::WorkerType = WorkerT<EDProducer>
inherited

Definition at line 35 of file EDProducer.h.

Constructor & Destructor Documentation

larg4::LArG4::LArG4 ( fhicl::ParameterSet const &  pset)
explicit

Standard constructor and destructor for an FMWK module.

Definition at line 344 of file LArG4_module.cc.

References art::errors::Configuration, art::EngineCreator::createEngine(), e, fG4MacroPath, sim::LArG4Parameters::FillSimEnergyDeposits(), fInputLabels, fSparsifyTrajectories, fStoreReflected, fUseLitePhotons, LOG_DEBUG, sim::LArG4Parameters::NoElectronPropagation(), sim::LArG4Parameters::NoPhotonPropagation(), art::ProductRegistryHelper::produces(), art::EngineCreator::rng(), art::errors::ServiceNotFound, phot::PhotonVisibilityService::StoreReflected(), and sim::LArG4Parameters::UseLitePhotons().

345  : fG4Help (0)
346  , flarVoxelListAction (0)
347  , fparticleListAction (0)
348  , fG4PhysListName (pset.get< std::string >("G4PhysListName","larg4::PhysicsList"))
349  , fCheckOverlaps (pset.get< bool >("CheckOverlaps",false) )
350  , fdumpParticleList (pset.get< bool >("DumpParticleList",false) )
351  , fdumpSimChannels (pset.get< bool >("DumpSimChannels", false) )
352  , fStoreReflected (false)
353  , fSmartStacking (pset.get< int >("SmartStacking",0) )
354  , fOffPlaneMargin (pset.get< double >("ChargeRecoveryMargin",0.0) )
355  , fKeepParticlesInVolumes (pset.get< std::vector< std::string > >("KeepParticlesInVolumes",{}))
356  , fSparsifyTrajectories (pset.get< bool >("SparsifyTrajectories",false) )
357  {
358  LOG_DEBUG("LArG4") << "Debug: LArG4()";
360 
361  if (pset.has_key("Seed")) {
363  << "The configuration of LArG4 module has the discontinued 'Seed' parameter.\n"
364  "Seeds are now controlled by two parameters: 'GEANTSeed' and 'PropagationSeed'.";
365  }
366  // setup the random number service for Geant4, the "G4Engine" label is a
367  // special tag setting up a global engine for use by Geant4/CLHEP;
368  // obtain the random seed from NuRandomService,
369  // unless overridden in configuration with key "Seed" or "GEANTSeed"
371  ->createEngine(*this, "G4Engine", "GEANT", pset, "GEANTSeed");
372  // same thing for the propagation engine:
374  ->createEngine(*this, "HepJamesRandom", "propagation", pset, "PropagationSeed");
375 
376  //get a list of generators to use, otherwise, we'll end up looking for anything that's
377  //made an MCTruth object
378  bool useInputLabels = pset.get_if_present< std::vector<std::string> >("InputLabels",fInputLabels);
379  if(!useInputLabels) fInputLabels.resize(0);
380 
383 
384  if(!lgp->NoPhotonPropagation()){
385  try {
388  }
389  catch (art::Exception const& e) {
390  // If the service is not configured, then just keep the default
391  // false for reflected light. If reflected photons are simulated
392  // without PVS they will show up in the regular SimPhotons collection
393  if (e.categoryCode() != art::errors::ServiceNotFound) throw;
394  }
395 
396  if(!fUseLitePhotons) {
397  produces< std::vector<sim::SimPhotons> >();
398  if(fStoreReflected) {
399  produces< std::vector<sim::SimPhotons> >("Reflected");
400  }
401  }
402  else{
403  produces< std::vector<sim::SimPhotonsLite> >();
404  produces< std::vector<sim::OpDetBacktrackerRecord> >();
405  if(fStoreReflected) {
406  produces< std::vector<sim::SimPhotonsLite> >("Reflected");
407  produces< std::vector<sim::OpDetBacktrackerRecord> >("Reflected");
408  }
409  }
410  }
411 
412  if(lgp->FillSimEnergyDeposits()){
413  produces < std::vector<sim::SimEnergyDeposit> >("TPCActive");
414  produces < std::vector<sim::SimEnergyDeposit> >("Other");
415  }
416 
417  produces< std::vector<simb::MCParticle> >();
418  if(!lgp->NoElectronPropagation()) produces< std::vector<sim::SimChannel> >();
419  produces< std::vector<sim::AuxDetSimChannel> >();
420  produces< art::Assns<simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo> >();
421 
422  // constructor decides if initialized value is a path or an environment variable
423  cet::search_path sp("FW_SEARCH_PATH");
424 
425  sp.find_file(pset.get< std::string >("GeantCommandFile"), fG4MacroPath);
426  struct stat sb;
427  if (fG4MacroPath.empty() || stat(fG4MacroPath.c_str(), &sb)!=0)
428  // failed to resolve the file name
429  throw cet::exception("NoG4Macro") << "G4 macro file "
430  << fG4MacroPath
431  << " not found!\n";
432 
433  }
std::vector< std::string > fInputLabels
std::string fG4MacroPath
void produces(std::string const &instanceName={}, Persistable const persistable=Persistable::Yes)
larg4::LArVoxelListAction * flarVoxelListAction
Geant4 user action to accumulate LAr voxel information.
bool NoPhotonPropagation() const
std::vector< std::string > fKeepParticlesInVolumes
Only write particles that have trajectories through these volumes.
bool fSparsifyTrajectories
Sparsify MCParticle Trajectories.
int fSmartStacking
Whether to instantiate and use class to.
bool fdumpSimChannels
Whether each event&#39;s sim::Channel will be displayed.
larg4::ParticleListAction * fparticleListAction
Geant4 user action to particle information.
base_engine_t & createEngine(seed_t seed)
bool NoElectronPropagation() const
g4b::G4Helper * fG4Help
G4 interface object.
bool FillSimEnergyDeposits() const
bool fdumpParticleList
Whether each event&#39;s sim::ParticleList will be displayed.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
static art::ServiceHandle< art::RandomNumberGenerator > & rng()
bool fUseLitePhotons
std::string fG4PhysListName
predefined physics list to use if not making a custom one
#define LOG_DEBUG(id)
bool fCheckOverlaps
Whether to use the G4 overlap checker.
bool fStoreReflected
Float_t e
Definition: plot.C:34
double fOffPlaneMargin
dictate how tracks are put on stack.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
bool UseLitePhotons() const
larg4::LArG4::~LArG4 ( )
virtual

Definition at line 437 of file LArG4_module.cc.

References fG4Help.

438  {
439  if(fG4Help) delete fG4Help;
440  }
g4b::G4Helper * fG4Help
G4 interface object.

Member Function Documentation

void larg4::LArG4::beginJob ( )
virtual

Reimplemented from art::EDProducer.

Definition at line 443 of file LArG4_module.cc.

References g4b::UserActionManager::AddAndAdoptAction(), g4b::G4Helper::ConstructDetector(), larg4::IonizationAndScintillation::CreateInstance(), fCheckOverlaps, fG4Help, fG4MacroPath, fG4PhysListName, fOffPlaneMargin, fparticleListAction, fSmartStacking, geo::GeometryCore::GDMLFile(), larg4::MaterialPropertyLoader::GetPropertiesFromServices(), g4b::G4Helper::GetRunManager(), g4b::G4Helper::InitPhysics(), g4b::UserActionManager::Instance(), sim::LArG4Parameters::KeepEMShowerDaughters(), larg4::LArVoxelReadout::Setup_t::offPlaneMargin, geo::GeometryCore::OpDetGeoName(), sim::LArG4Parameters::ParticleKineticEnergyCut(), larg4::LArVoxelReadoutGeometry::Setup_t::readoutSetup, art::EngineCreator::rng(), g4b::G4Helper::SetOverlapCheck(), g4b::G4Helper::SetParallelWorlds(), g4b::G4Helper::SetUserAction(), sim::LArG4Parameters::StoreTrajectories(), and larg4::MaterialPropertyLoader::UpdateGeometry().

444  {
447 
451 
452  // Get the logical volume store and assign material properties
455  MPL->UpdateGeometry(G4LogicalVolumeStore::GetInstance());
456 
457  // Tell the detector about the parallel LAr voxel geometry.
458  std::vector<G4VUserParallelWorld*> pworlds;
459  // Intialize G4 physics and primary generator action
460  fG4Help->InitPhysics();
461 
462  // create the ionization and scintillation calculator;
463  // this is a singleton (!) so it does not make sense
464  // to create it in LArVoxelReadoutGeometry
465  IonizationAndScintillation::CreateInstance(rng->getEngine("propagation"));
466 
467  // make a parallel world for each TPC in the detector
468  LArVoxelReadoutGeometry::Setup_t readoutGeomSetupData;
469  readoutGeomSetupData.readoutSetup.offPlaneMargin = fOffPlaneMargin;
470  readoutGeomSetupData.readoutSetup.propGen
471  = &(rng->getEngine("propagation"));
472  pworlds.push_back(new LArVoxelReadoutGeometry
473  ("LArVoxelReadoutGeometry", readoutGeomSetupData)
474  );
475  pworlds.push_back( new OpDetReadoutGeometry( geom->OpDetGeoName() ));
476  pworlds.push_back( new AuxDetReadoutGeometry("AuxDetReadoutGeometry") );
477 
478  fG4Help->SetParallelWorlds(pworlds);
479 
480  // moved up
481  // Intialize G4 physics and primary generator action
482  fG4Help->InitPhysics();
483 
484  // Use the UserActionManager to handle all the Geant4 user hooks.
486 
487  // User-action class for accumulating LAr voxels.
489 
490  // UserAction for getting past a bug in v4.9.4.p02 of Geant4.
491  // This action will not be used once the bug has been fixed
492  // The techniques used in this UserAction are not to be repeated
493  // as in general they are a very bad idea, ie they take a const
494  // pointer and jump through hoops to change it
495  // 08-Apr-2014 WGS: It appears that with the shift to Geant 4.9.6 or
496  // above, there's no longer any need for the "Bad Idea Action" fix.
497  // larg4::G4BadIdeaAction *bia = new larg4::G4BadIdeaAction(fSmartStacking);
498  // uaManager->AddAndAdoptAction(bia);
499 
500  // remove IonizationAndScintillationAction for now as we are ensuring
501  // the Reset for each G4Step within the G4SensitiveVolumes
502  //larg4::IonizationAndScintillationAction *iasa = new larg4::IonizationAndScintillationAction();
503  //uaManager->AddAndAdoptAction(iasa);
504 
505  // User-action class for accumulating particles and trajectories
506  // produced in the detector.
508  lgp->StoreTrajectories(),
509  lgp->KeepEMShowerDaughters());
511 
512  // UserActionManager is now configured so continue G4 initialization
514 
515  // With an enormous detector with lots of rock ala LAr34 (nee LAr20)
516  // we need to be smarter about stacking.
517  if (fSmartStacking>0){
518  G4UserStackingAction* stacking_action = new LArStackingAction(fSmartStacking);
519  fG4Help->GetRunManager()->SetUserAction(stacking_action);
520  }
521 
522 
523 
524  }
bool KeepEMShowerDaughters() const
std::string fG4MacroPath
Stores material properties and sends them to GEANT4 geometry.
std::string OpDetGeoName(unsigned int c=0) const
Returns gdml string which gives sensitive opdet name.
void SetUserAction()
Initialization for the Geant4 Monte Carlo.
Definition: G4Helper.cxx:432
void ConstructDetector(std::string const &gdmlFile)
Definition: G4Helper.cxx:368
void SetParallelWorlds(std::vector< G4VUserParallelWorld * > pworlds)
Definition: G4Helper.cxx:357
G4RunManager * GetRunManager()
Definition: G4Helper.h:100
bool StoreTrajectories() const
void InitPhysics()
Initialization for the Geant4 Monte Carlo.
Definition: G4Helper.cxx:407
int fSmartStacking
Whether to instantiate and use class to.
std::string GDMLFile() const
Returns the full directory path to the GDML file source.
larg4::ParticleListAction * fparticleListAction
Geant4 user action to particle information.
void SetOverlapCheck(bool check)
Definition: G4Helper.h:128
g4b::G4Helper * fG4Help
G4 interface object.
static void AddAndAdoptAction(UserAction *a)
static IonizationAndScintillation * CreateInstance(CLHEP::HepRandomEngine &engine)
void UpdateGeometry(G4LogicalVolumeStore *lvs)
Updates the material properties with the collected values.
double ParticleKineticEnergyCut() const
static art::ServiceHandle< art::RandomNumberGenerator > & rng()
static UserActionManager * Instance()
std::string fG4PhysListName
predefined physics list to use if not making a custom one
bool fCheckOverlaps
Whether to use the G4 overlap checker.
void GetPropertiesFromServices()
Imports properties from LArSoft services.
double fOffPlaneMargin
dictate how tracks are put on stack.
void larg4::LArG4::beginRun ( art::Run run)
virtual

Reimplemented from art::EDProducer.

Definition at line 526 of file LArG4_module.cc.

References CreateParticleVolumeFilter(), fKeepParticlesInVolumes, fparticleListAction, and larg4::ParticleListAction::ParticleFilter().

526  {
527  // prepare the filter object (null if no filtering)
528 
529  std::set<std::string> volnameset(fKeepParticlesInVolumes.begin(), fKeepParticlesInVolumes.end());
531 
532  }
std::vector< std::string > fKeepParticlesInVolumes
Only write particles that have trajectories through these volumes.
larg4::ParticleListAction * fparticleListAction
Geant4 user action to particle information.
void ParticleFilter(std::unique_ptr< util::PositionInVolumeFilter > &&filter)
Grabs a particle filter.
std::unique_ptr< util::PositionInVolumeFilter > CreateParticleVolumeFilter(std::set< std::string > const &vol_names) const
Configures and returns a particle filter.
template<typename T , BranchType = InEvent>
ProductToken<T> art::Consumer::consumes ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ProductToken<T> art::Consumer::consumes ( InputTag const &  it)
inherited

Definition at line 147 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

148 {
149  if (!moduleContext_)
150  return ProductToken<T>::invalid();
151 
152  consumables_[BT].emplace_back(ConsumableType::Product,
153  TypeID{typeid(T)},
154  it.label(),
155  it.instance(),
156  it.process());
157  return ProductToken<T>{it};
158 }
static ProductToken< T > invalid()
Definition: ProductToken.h:47
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename T , art::BranchType BT>
void art::Consumer::consumesMany ( )
inherited

Definition at line 162 of file Consumer.h.

163 {
164  if (!moduleContext_)
165  return;
166 
167  consumables_[BT].emplace_back(ConsumableType::Many, TypeID{typeid(T)});
168 }
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename Element , BranchType = InEvent>
ViewToken<Element> art::Consumer::consumesView ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ViewToken<T> art::Consumer::consumesView ( InputTag const &  it)
inherited

Definition at line 172 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

173 {
174  if (!moduleContext_)
175  return ViewToken<T>::invalid();
176 
177  consumables_[BT].emplace_back(ConsumableType::ViewElement,
178  TypeID{typeid(T)},
179  it.label(),
180  it.instance(),
181  it.process());
182  return ViewToken<T>{it};
183 }
static ViewToken< Element > invalid()
Definition: ProductToken.h:75
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
EngineCreator::base_engine_t & EngineCreator::createEngine ( seed_t  seed,
std::string const &  kind_of_engine_to_make 
)
inherited

Definition at line 32 of file EngineCreator.cc.

References art::EngineCreator::rng().

34 {
35  return rng()->createEngine(
36  placeholder_schedule_id(), seed, kind_of_engine_to_make);
37 }
long seed
Definition: chem4.cc:68
static art::ServiceHandle< art::RandomNumberGenerator > & rng()
EngineCreator::base_engine_t & EngineCreator::createEngine ( seed_t  seed,
std::string const &  kind_of_engine_to_make,
label_t const &  engine_label 
)
inherited

Definition at line 40 of file EngineCreator.cc.

References art::EngineCreator::rng().

43 {
44  return rng()->createEngine(
45  placeholder_schedule_id(), seed, kind_of_engine_to_make, engine_label);
46 }
long seed
Definition: chem4.cc:68
static art::ServiceHandle< art::RandomNumberGenerator > & rng()
std::unique_ptr< util::PositionInVolumeFilter > larg4::LArG4::CreateParticleVolumeFilter ( std::set< std::string > const &  vol_names) const
private

Configures and returns a particle filter.

Definition at line 535 of file LArG4_module.cc.

Referenced by beginRun().

536  {
537 
538  // if we don't have favourite volumes, don't even bother creating a filter
539  if (vol_names.empty()) return {};
540 
541  auto const& geom = *art::ServiceHandle<geo::Geometry>();
542 
543  std::vector<std::vector<TGeoNode const*>> node_paths
544  = geom.FindAllVolumePaths(vol_names);
545 
546  // collection of interesting volumes
548  GeoVolumePairs.reserve(node_paths.size()); // because we are obsessed
549 
550  //for each interesting volume, follow the node path and collect
551  //total rotations and translations
552  for (size_t iVolume = 0; iVolume < node_paths.size(); ++iVolume) {
553  std::vector<TGeoNode const*> path = node_paths[iVolume];
554 
555  TGeoTranslation* pTransl = new TGeoTranslation(0.,0.,0.);
556  TGeoRotation* pRot = new TGeoRotation();
557  for (TGeoNode const* node: path) {
558  TGeoTranslation thistranslate(*node->GetMatrix());
559  TGeoRotation thisrotate(*node->GetMatrix());
560  pTransl->Add(&thistranslate);
561  *pRot=*pRot * thisrotate;
562  }
563 
564  //for some reason, pRot and pTransl don't have tr and rot bits set correctly
565  //make new translations and rotations so bits are set correctly
566  TGeoTranslation* pTransl2 = new TGeoTranslation(pTransl->GetTranslation()[0],
567  pTransl->GetTranslation()[1],
568  pTransl->GetTranslation()[2]);
569  double phi=0.,theta=0.,psi=0.;
570  pRot->GetAngles(phi,theta,psi);
571  TGeoRotation* pRot2 = new TGeoRotation();
572  pRot2->SetAngles(phi,theta,psi);
573 
574  TGeoCombiTrans* pTransf = new TGeoCombiTrans(*pTransl2,*pRot2);
575 
576  GeoVolumePairs.emplace_back(node_paths[iVolume].back()->GetVolume(), pTransf);
577 
578  }
579 
580  return std::make_unique<util::PositionInVolumeFilter>(std::move(GeoVolumePairs));
581 
582  } // CreateParticleVolumeFilter()
std::vector< VolumeInfo_t > AllVolumeInfo_t
CurrentProcessingContext const * art::EDProducer::currentContext ( ) const
protectedinherited

Definition at line 120 of file EDProducer.cc.

References art::EDProducer::current_context_.

121  {
122  return current_context_.get();
123  }
CPC_exempt_ptr current_context_
Definition: EDProducer.h:116
EngineCreator::seed_t EngineCreator::get_seed_value ( fhicl::ParameterSet const &  pset,
char const  key[] = "seed",
seed_t const  implicit_seed = -1 
)
inherited

Definition at line 49 of file EngineCreator.cc.

References fhicl::ParameterSet::get().

Referenced by art::MixFilter< T >::initEngine_().

52 {
53  auto const& explicit_seeds = pset.get<std::vector<int>>(key, {});
54  return explicit_seeds.empty() ? implicit_seed : explicit_seeds.front();
55 }
template<typename PROD , BranchType B>
ProductID art::EDProducer::getProductID ( std::string const &  instanceName = {}) const
inlineinherited

Definition at line 123 of file EDProducer.h.

References art::EDProducer::moduleDescription_.

124  {
125  return ProducerBase::getProductID<PROD, B>(moduleDescription_,
126  instanceName);
127  }
ModuleDescription moduleDescription_
Definition: EDProducer.h:115
template<typename PROD , BranchType B>
ProductID art::ProducerBase::getProductID ( ModuleDescription const &  moduleDescription,
std::string const &  instanceName 
) const
inherited

Definition at line 56 of file ProducerBase.h.

References B, and art::ModuleDescription::moduleLabel().

Referenced by art::ProducerBase::modifiesEvent().

58  {
59  auto const& pd =
60  get_ProductDescription<PROD>(B, md.moduleLabel(), instanceName);
61  return pd.productID();
62  }
Int_t B
Definition: plot.C:25
template<typename T , BranchType = InEvent>
ProductToken<T> art::Consumer::mayConsume ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ProductToken<T> art::Consumer::mayConsume ( InputTag const &  it)
inherited

Definition at line 190 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

191 {
192  if (!moduleContext_)
193  return ProductToken<T>::invalid();
194 
195  consumables_[BT].emplace_back(ConsumableType::Product,
196  TypeID{typeid(T)},
197  it.label(),
198  it.instance(),
199  it.process());
200  return ProductToken<T>{it};
201 }
static ProductToken< T > invalid()
Definition: ProductToken.h:47
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename T , art::BranchType BT>
void art::Consumer::mayConsumeMany ( )
inherited

Definition at line 205 of file Consumer.h.

206 {
207  if (!moduleContext_)
208  return;
209 
210  consumables_[BT].emplace_back(ConsumableType::Many, TypeID{typeid(T)});
211 }
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename Element , BranchType = InEvent>
ViewToken<Element> art::Consumer::mayConsumeView ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ViewToken<T> art::Consumer::mayConsumeView ( InputTag const &  it)
inherited

Definition at line 215 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

216 {
217  if (!moduleContext_)
218  return ViewToken<T>::invalid();
219 
220  consumables_[BT].emplace_back(ConsumableType::ViewElement,
221  TypeID{typeid(T)},
222  it.label(),
223  it.instance(),
224  it.process());
225  return ViewToken<T>{it};
226 }
static ViewToken< Element > invalid()
Definition: ProductToken.h:75
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
bool art::ProducerBase::modifiesEvent ( ) const
inlineinherited

Definition at line 40 of file ProducerBase.h.

References art::ProducerBase::getProductID().

41  {
42  return true;
43  }
void art::Consumer::prepareForJob ( fhicl::ParameterSet const &  pset)
protectedinherited

Definition at line 89 of file Consumer.cc.

References fhicl::ParameterSet::get_if_present().

Referenced by art::EDProducer::doBeginJob(), art::EDFilter::doBeginJob(), and art::EDAnalyzer::doBeginJob().

90 {
91  if (!moduleContext_)
92  return;
93 
94  pset.get_if_present("errorOnMissingConsumes", requireConsumes_);
95  for (auto& consumablesPerBranch : consumables_) {
96  cet::sort_all(consumablesPerBranch);
97  }
98 }
bool requireConsumes_
Definition: Consumer.h:137
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
void larg4::LArG4::produce ( art::Event evt)
virtual

The main routine of this module: Fetch the primary particles from the event, simulate their evolution in the detctor, and produce the detector response.

Implements art::EDProducer.

Definition at line 585 of file LArG4_module.cc.

References geo::GeometryCore::AuxDet(), sim::SimChannel::Channel(), larg4::AuxDetReadout::clear(), larg4::OpDetPhotonTable::ClearEnergyDeposits(), larg4::OpDetPhotonTable::ClearTable(), geo::GeometryCore::Cryostat(), DEFINE_ART_MODULE, sim::SimPhotonsLite::DetectedPhotons, sim::dump::DumpMCParticle(), sim::dump::DumpMCTruth(), fdumpParticleList, fdumpSimChannels, fG4Help, sim::LArG4Parameters::FillSimEnergyDeposits(), fInputLabels, fparticleListAction, fSparsifyTrajectories, fStoreReflected, fUseLitePhotons, g4b::G4Helper::G4Run(), art::Ptr< T >::get(), larg4::AuxDetReadout::GetAuxDetSimChannel(), art::DataViewImpl::getByLabel(), larg4::OpDetPhotonTable::GetLitePhotons(), art::DataViewImpl::getManyByType(), larg4::OpDetPhotonTable::GetPhotons(), larg4::ParticleListAction::GetPrimaryTruthIndex(), larg4::LArVoxelReadout::GetSimChannelMap(), larg4::OpDetPhotonTable::GetSimEnergyDeposits(), art::Event::id(), larg4::OpDetPhotonTable::Instance(), larg4::ParticleListAction::isDropped(), LOG_DEBUG, art::errors::LogicError, simb::MCParticle::Mother(), geo::GeometryCore::NAuxDets(), geo::GeometryCore::Ncryostats(), sim::LArG4Parameters::NoElectronPropagation(), geo::GeometryCore::NOpDets(), sim::LArG4Parameters::NoPhotonPropagation(), geo::AuxDetGeo::NSensitiveVolume(), geo::CryostatGeo::NTPC(), sim::SimPhotonsLite::OpChannel, art::Handle< T >::provenance(), art::Event::put(), larg4::ParticleListAction::ResetTrackIDOffset(), simb::MCParticle::SparsifyTrajectory(), sim::SimChannel::TDCIDEMap(), simb::MCParticle::TrackId(), larg4::ParticleListAction::YieldList(), larg4::OpDetPhotonTable::YieldOpDetBacktrackerRecords(), and larg4::OpDetPhotonTable::YieldReflectedOpDetBacktrackerRecords().

586  {
587  LOG_DEBUG("LArG4") << "produce()";
588 
589  // loop over the lists and put the particles and voxels into the event as collections
590  std::unique_ptr< std::vector<sim::SimChannel> > scCol (new std::vector<sim::SimChannel>);
591  std::unique_ptr< std::vector< sim::AuxDetSimChannel > > adCol (new std::vector<sim::AuxDetSimChannel> );
592  auto tpassn = std::make_unique<art::Assns<simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo>>();
593  std::unique_ptr< std::vector<simb::MCParticle> > partCol (new std::vector<simb::MCParticle >);
594  std::unique_ptr< std::vector<sim::SimPhotons> > PhotonCol (new std::vector<sim::SimPhotons>);
595  std::unique_ptr< std::vector<sim::SimPhotons> > PhotonColRefl (new std::vector<sim::SimPhotons>);
596  std::unique_ptr< std::vector<sim::SimPhotonsLite> > LitePhotonCol (new std::vector<sim::SimPhotonsLite>);
597  std::unique_ptr< std::vector<sim::SimPhotonsLite> > LitePhotonColRefl (new std::vector<sim::SimPhotonsLite>);
598  std::unique_ptr< std::vector< sim::OpDetBacktrackerRecord > > cOpDetBacktrackerRecordCol (new std::vector<sim::OpDetBacktrackerRecord>);
599  std::unique_ptr< std::vector< sim::OpDetBacktrackerRecord > > cOpDetBacktrackerRecordColRefl (new std::vector<sim::OpDetBacktrackerRecord>);
600 
601 
602  art::PtrMaker<simb::MCParticle> makeMCPartPtr(evt, *this);
603 
604  //for energy deposits
605  std::unique_ptr< std::vector<sim::SimEnergyDeposit> > edepCol_TPCActive (new std::vector<sim::SimEnergyDeposit>);
606  std::unique_ptr< std::vector<sim::SimEnergyDeposit> > edepCol_Other (new std::vector<sim::SimEnergyDeposit>);
607 
608  // Fetch the lists of LAr voxels and particles.
611 
612  // Clear the detected photon table
614  if(lgp->FillSimEnergyDeposits())
616 
617  // reset the track ID offset as we have a new collection of interactions
619 
620  //look to see if there is any MCTruth information for this
621  //event
622  std::vector< art::Handle< std::vector<simb::MCTruth> > > mclists;
623  if(fInputLabels.size()==0)
624  evt.getManyByType(mclists);
625  else{
626  mclists.resize(fInputLabels.size());
627  for(size_t i=0; i<fInputLabels.size(); i++)
628  evt.getByLabel(fInputLabels[i],mclists[i]);
629  }
630 
631  unsigned int nGeneratedParticles = 0;
632 
633  // Need to process Geant4 simulation for each interaction separately.
634  for(size_t mcl = 0; mcl < mclists.size(); ++mcl){
635 
636  art::Handle< std::vector<simb::MCTruth> > mclistHandle = mclists[mcl];
637 
638  for(size_t m = 0; m < mclistHandle->size(); ++m){
639  art::Ptr<simb::MCTruth> mct(mclistHandle, m);
640 
641  LOG_DEBUG("LArG4") << *(mct.get());
642 
643  // The following tells Geant4 to track the particles in this interaction.
644  fG4Help->G4Run(mct);
645 
646  // receive the particle list
648 
649  for(auto const& partPair: particleList) {
650  simb::MCParticle& p = *(partPair.second);
651  ++nGeneratedParticles;
652 
653  // if the particle has been marked as dropped, we don't save it
654  // (as of LArSoft ~v5.6 this does not ever happen because
655  // ParticleListAction has already taken care of deleting them)
656  if (ParticleListAction::isDropped(&p)) continue;
657 
658  sim::GeneratedParticleInfo const truthInfo{
660  };
661  if (!truthInfo.hasGeneratedParticleIndex() && (p.Mother() == 0)) {
662  // this means it's primary but with no information; logic error!!
664  error << "Failed to match primary particle:\n";
666  error << "\nwith particles from the truth record '"
667  << mclistHandle.provenance()->inputTag() << "':\n";
668  sim::dump::DumpMCTruth(error, *mct, 2U, " "); // 2 points per line
669  error << "\n";
670  throw error;
671  }
672 
674 
675  partCol->push_back(std::move(p));
676 
677  tpassn->addSingle(mct, makeMCPartPtr(partCol->size() - 1), truthInfo);
678 
679  } // for(particleList)
680 
681 
682  // Has the user request a detailed dump of the output objects?
683  if (fdumpParticleList){
684  mf::LogInfo("LArG4") << "Dump sim::ParticleList; size()="
685  << particleList.size() << "\n"
686  << particleList;
687  }
688 
689  }
690 
691  }// end loop over interactions
692 
693  // get the electrons from the LArVoxelReadout sensitive detector
694  // Get the sensitive-detector manager.
695  G4SDManager* sdManager = G4SDManager::GetSDMpointer();
696 
697  // Find the sensitive detector with the name "LArVoxelSD".
698  OpDetSensitiveDetector *theOpDetDet = dynamic_cast<OpDetSensitiveDetector*>(sdManager->FindSensitiveDetector("OpDetSensitiveDetector"));
699 
700  // Store the contents of the detected photon table
701  //
702  if(theOpDetDet){
703 
704  if(!lgp->NoPhotonPropagation()){
705 
706  for (int Reflected = 0; Reflected <= 1; Reflected++) {
707  if (Reflected && ! fStoreReflected)
708  continue;
709 
710  if(!fUseLitePhotons){
711  LOG_DEBUG("Optical") << "Storing OpDet Hit Collection in Event";
712  std::vector<sim::SimPhotons>& ThePhotons = OpDetPhotonTable::Instance()->GetPhotons(Reflected);
713  if (Reflected) PhotonColRefl->reserve(ThePhotons.size());
714  else PhotonCol->reserve(ThePhotons.size());
715  for(auto& it : ThePhotons) {
716  if (Reflected) PhotonColRefl->push_back(std::move(it));
717  else PhotonCol->push_back(std::move(it));
718  }
719  }
720  else{
721  LOG_DEBUG("Optical") << "Storing OpDet Hit Collection in Event";
722 
723  std::map<int, std::map<int, int> > ThePhotons = OpDetPhotonTable::Instance()->GetLitePhotons(Reflected);
724 
725  if(ThePhotons.size() > 0){
726  LitePhotonCol->reserve(ThePhotons.size());
727  for(auto const& it : ThePhotons){
729  ph.OpChannel = it.first;
730  ph.DetectedPhotons = it.second;
731  if (Reflected) LitePhotonColRefl->push_back(ph);
732  else LitePhotonCol->push_back(ph);
733  }
734  }
735  }
736  if (Reflected)
737  *cOpDetBacktrackerRecordColRefl = OpDetPhotonTable::Instance()->YieldReflectedOpDetBacktrackerRecords();
738  else
739  *cOpDetBacktrackerRecordCol = OpDetPhotonTable::Instance()->YieldOpDetBacktrackerRecords();
740  }
741  } //end if no photon propagation
742 
743  if(lgp->FillSimEnergyDeposits())
744  {
745  auto const& edepMap = OpDetPhotonTable::Instance()->GetSimEnergyDeposits();
746  for(auto const& edepCol : edepMap){
747  if(boost::contains(edepCol.first,"TPCActive"))
748  edepCol_TPCActive->insert(edepCol_TPCActive->end(),
749  edepCol.second.begin(),edepCol.second.end());
750  else
751  edepCol_Other->insert(edepCol_Other->end(),
752  edepCol.second.begin(),edepCol.second.end());
753  }
754  }
755  }//end if theOpDetDet
756 
757 
758  if(!lgp->NoElectronPropagation())
759  {
760 
761  // only put the sim::SimChannels into the event once, not once for every
762  // MCTruth in the event
763 
764  std::set<LArVoxelReadout*> ReadoutList; // to be cleared later on
765 
766  for(unsigned int c = 0; c < geom->Ncryostats(); ++c){
767 
768  // map to keep track of which channels we already have SimChannels for in scCol
769  // remake this map on each cryostat as channels ought not to be shared between
770  // cryostats, just between TPC's
771 
772  std::map<unsigned int, unsigned int> channelToscCol;
773 
774  unsigned int ntpcs = geom->Cryostat(c).NTPC();
775  for(unsigned int t = 0; t < ntpcs; ++t){
776  std::string name("LArVoxelSD");
777  std::ostringstream sstr;
778  sstr << name << "_Cryostat" << c << "_TPC" << t;
779 
780  // try first to find the sensitive detector specific for this TPC;
781  // do not bother writing on screen if there is none (yet)
782  G4VSensitiveDetector* sd
783  = sdManager->FindSensitiveDetector(sstr.str(), false);
784  // if there is none, catch the general one (called just "LArVoxelSD")
785  if (!sd) sd = sdManager->FindSensitiveDetector(name, false);
786  // If this didn't work, then a sensitive detector with
787  // the name "LArVoxelSD" does not exist.
788  if ( !sd ){
789  throw cet::exception("LArG4") << "Sensitive detector for cryostat "
790  << c << " TPC " << t << " not found (neither '"
791  << sstr.str() << "' nor '" << name << "' exist)\n";
792  }
793 
794  // Convert the G4VSensitiveDetector* to a LArVoxelReadout*.
795  LArVoxelReadout* larVoxelReadout = dynamic_cast<LArVoxelReadout*>(sd);
796 
797  // If this didn't work, there is a "LArVoxelSD" detector, but
798  // it's not a LArVoxelReadout object.
799  if ( !larVoxelReadout ){
800  throw cet::exception("LArG4") << "Sensitive detector '"
801  << sd->GetName()
802  << "' is not a LArVoxelReadout object\n";
803  }
804 
805  LArVoxelReadout::ChannelMap_t& channels = larVoxelReadout->GetSimChannelMap(c, t);
806  if (!channels.empty()) {
807  LOG_DEBUG("LArG4") << "now put " << channels.size() << " SimChannels"
808  " from C=" << c << " T=" << t << " into the event";
809  }
810 
811  for(auto ch_pair: channels){
812  sim::SimChannel& sc = ch_pair.second;
813 
814  // push sc onto scCol but only if we haven't already put something in scCol for this channel.
815  // if we have, then merge the ionization deposits. Skip the check if we only have one TPC
816 
817  if (ntpcs > 1) {
818  unsigned int ichan = sc.Channel();
819  std::map<unsigned int, unsigned int>::iterator itertest = channelToscCol.find(ichan);
820  if (itertest == channelToscCol.end()) {
821  channelToscCol[ichan] = scCol->size();
822  scCol->emplace_back(std::move(sc));
823  }
824  else {
825  unsigned int idtest = itertest->second;
826  auto const& tdcideMap = sc.TDCIDEMap();
827  for(auto const& tdcide : tdcideMap){
828  for(auto const& ide : tdcide.second){
829  double xyz[3] = {ide.x, ide.y, ide.z};
830  scCol->at(idtest).AddIonizationElectrons(ide.trackID,
831  tdcide.first,
832  ide.numElectrons,
833  xyz,
834  ide.energy);
835  } // end loop to add ionization electrons to scCol->at(idtest)
836  }// end loop over tdc to vector<sim::IDE> map
837  } // end if check to see if we've put SimChannels in for ichan yet or not
838  }
839  else {
840  scCol->emplace_back(std::move(sc));
841  } // end of check if we only have one TPC (skips check for multiple simchannels if we have just one TPC)
842  } // end loop over simchannels for this TPC
843 
844 
845  // mark it for clearing
846  ReadoutList.insert(const_cast<LArVoxelReadout*>(larVoxelReadout));
847 
848  } // end loop over tpcs
849  }// end loop over cryostats
850 
851  for (LArVoxelReadout* larVoxelReadout: ReadoutList){
852  larVoxelReadout->ClearSimChannels();
853  }
854  }//endif electron prop
855 
856  // only put the sim::AuxDetSimChannels into the event once, not once for every
857  // MCTruth in the event
858 
859  adCol->reserve(geom->NAuxDets());
860  for(unsigned int a = 0; a < geom->NAuxDets(); ++a){
861 
862  // there should always be at least one senstive volume because
863  // we make one for the full aux det if none are specified in the
864  // gdml file - see AuxDetGeo.cxx
865  for(size_t sv = 0; sv < geom->AuxDet(a).NSensitiveVolume(); ++sv){
866 
867  // N.B. this name convention is used when creating the
868  // AuxDetReadout SD in AuxDetReadoutGeometry
869  std::stringstream name;
870  name << "AuxDetSD_AuxDet" << a << "_" << sv;
871  G4VSensitiveDetector* sd = sdManager->FindSensitiveDetector(name.str().c_str());
872  if ( !sd ){
873  throw cet::exception("LArG4") << "Sensitive detector '"
874  << name.str()
875  << "' does not exist\n";
876  }
877 
878  // Convert the G4VSensitiveDetector* to a AuxDetReadout*.
879  larg4::AuxDetReadout *auxDetReadout = dynamic_cast<larg4::AuxDetReadout*>(sd);
880 
881  LOG_DEBUG("LArG4") << "now put the AuxDetSimTracks in the event";
882 
883  const sim::AuxDetSimChannel adsc = auxDetReadout->GetAuxDetSimChannel();
884  adCol->push_back(adsc);
885  auxDetReadout->clear();
886  }
887 
888  } // Loop over AuxDets
889 
890  mf::LogInfo("LArG4")
891  << "Geant4 simulated " << nGeneratedParticles << " MC particles, we keep "
892  << partCol->size() << " .";
893 
894  if (fdumpSimChannels) {
895  mf::LogVerbatim("DumpSimChannels")
896  << "Event " << evt.id()
897  << ": " << scCol->size() << " channels with signal";
898  unsigned int nChannels = 0;
899  for (const sim::SimChannel& sc: *scCol) {
900  mf::LogVerbatim out("DumpSimChannels");
901  out << " #" << nChannels << ": ";
902  // dump indenting with " ", but not on the first line
903  sc.Dump(out, " ");
904  ++nChannels;
905  } // for
906  } // if dump SimChannels
907 
908  if(!lgp->NoElectronPropagation()) evt.put(std::move(scCol));
909 
910  evt.put(std::move(adCol));
911  evt.put(std::move(partCol));
912  if(!lgp->NoPhotonPropagation()){
913  if(!fUseLitePhotons){
914  evt.put(std::move(PhotonCol));
915  if (fStoreReflected)
916  evt.put(std::move(PhotonColRefl),"Reflected");
917  }
918  else{
919  evt.put(std::move(LitePhotonCol));
920  evt.put(std::move(cOpDetBacktrackerRecordCol));
921  if (fStoreReflected) {
922  evt.put(std::move(LitePhotonColRefl),"Reflected");
923  evt.put(std::move(cOpDetBacktrackerRecordColRefl),"Reflected");
924  }
925  }
926  }
927  evt.put(std::move(tpassn));
928 
929  if(lgp->FillSimEnergyDeposits()){
930  evt.put(std::move(edepCol_TPCActive),"TPCActive");
931  evt.put(std::move(edepCol_Other),"Other");
932  }
933  return;
934  } // LArG4::produce()
std::vector< std::string > fInputLabels
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< sim::OpDetBacktrackerRecord > YieldReflectedOpDetBacktrackerRecords()
void SparsifyTrajectory()
Definition: MCParticle.h:268
Energy deposited on a readout channel by simulated tracks.
Definition: SimChannel.h:143
intermediate_table::iterator iterator
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
bool G4Run(std::vector< const simb::MCTruth * > &primaries)
Definition: G4Helper.cxx:503
int Mother() const
Definition: MCParticle.h:217
void Dump(Stream &&out, std::string indent, std::string first_indent) const
Dumps the full content of the SimChannel into a stream.
Definition: SimChannel.h:340
bool NoPhotonPropagation() const
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
int TrackId() const
Definition: MCParticle.h:214
std::map< int, int > DetectedPhotons
Definition: SimPhotons.h:65
bool fSparsifyTrajectories
Sparsify MCParticle Trajectories.
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
Collection of particles crossing one auxiliary detector cell.
bool fdumpSimChannels
Whether each event&#39;s sim::Channel will be displayed.
larg4::ParticleListAction * fparticleListAction
Geant4 user action to particle information.
sim::ParticleList && YieldList()
std::map< unsigned int, sim::SimChannel > ChannelMap_t
Type of map channel -> sim::SimChannel.
std::vector< sim::SimPhotons > & GetPhotons(bool Reflected=false)
std::unordered_map< std::string, std::vector< sim::SimEnergyDeposit > > const & GetSimEnergyDeposits() const
bool NoElectronPropagation() const
g4b::G4Helper * fG4Help
G4 interface object.
static bool isDropped(simb::MCParticle const *p)
returns whether the specified particle has been marked as dropped
Provenance const * provenance() const
Definition: Handle.h:204
virtual void clear()
void DumpMCTruth(Stream &&out, simb::MCTruth const &truth, unsigned int pointsPerLine, std::string indent, std::string firstIndent)
Dumps the content of the specified MC truth in the output stream.
Definition: MCDumpers.h:346
bool FillSimEnergyDeposits() const
void getManyByType(std::vector< Handle< PROD >> &results) const
Definition: DataViewImpl.h:446
unsigned int NTPC() const
Number of TPCs in this cryostat.
Definition: CryostatGeo.h:155
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
size_t NSensitiveVolume() const
Definition: AuxDetGeo.h:160
GeneratedParticleIndex_t GetPrimaryTruthIndex(int trackId) const
Returns the index of primary truth (sim::NoGeneratorIndex if none).
bool fdumpParticleList
Whether each event&#39;s sim::ParticleList will be displayed.
AuxDetGeo const & AuxDet(unsigned int const ad=0) const
Returns the specified auxiliary detector.
unsigned int NOpDets() const
Number of OpDets in the whole detector.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
raw::ChannelID_t Channel() const
Returns the readout channel this object describes.
Definition: SimChannel.h:332
static OpDetPhotonTable * Instance(bool LitePhotons=false)
bool fUseLitePhotons
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
std::vector< sim::OpDetBacktrackerRecord > YieldOpDetBacktrackerRecords()
Contains information about a generated particle.
#define LOG_DEBUG(id)
TDCIDEs_t const & TDCIDEMap() const
Returns all the deposited energy information as stored.
Definition: SimChannel.h:331
bool fStoreReflected
std::map< int, std::map< int, int > > GetLitePhotons(bool Reflected=false)
void ClearTable(size_t nch=0)
EventID id() const
Definition: Event.h:56
sim::AuxDetSimChannel const GetAuxDetSimChannel() const
Definition: AuxDetReadout.h:73
void DumpMCParticle(Stream &&out, simb::MCParticle const &particle, std::string indent, std::string firstIndent)
Dumps the content of the specified particle in the output stream.
Definition: MCDumpers.h:228
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
unsigned int NAuxDets() const
Returns the number of auxiliary detectors.
void art::Consumer::showMissingConsumes ( ) const
protectedinherited

Definition at line 125 of file Consumer.cc.

Referenced by art::EDProducer::doEndJob(), art::EDFilter::doEndJob(), art::EDAnalyzer::doEndJob(), and art::RootOutput::endJob().

126 {
127  if (!moduleContext_)
128  return;
129 
130  // If none of the branches have missing consumes statements, exit early.
131  if (std::all_of(cbegin(missingConsumes_),
132  cend(missingConsumes_),
133  [](auto const& perBranch) { return perBranch.empty(); }))
134  return;
135 
136  constexpr cet::HorizontalRule rule{60};
137  mf::LogPrint log{"MTdiagnostics"};
138  log << '\n'
139  << rule('=') << '\n'
140  << "The following consumes (or mayConsume) statements are missing from\n"
141  << module_context(moduleDescription_) << '\n'
142  << rule('-') << '\n';
143 
144  cet::for_all_with_index(
145  missingConsumes_, [&log](std::size_t const i, auto const& perBranch) {
146  for (auto const& pi : perBranch) {
147  log << " "
148  << assemble_consumes_statement(static_cast<BranchType>(i), pi)
149  << '\n';
150  }
151  });
152  log << rule('=');
153 }
cet::exempt_ptr< ModuleDescription const > moduleDescription_
Definition: Consumer.h:140
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
bool moduleContext_
Definition: Consumer.h:136
ConsumableProductSets missingConsumes_
Definition: Consumer.h:139
void art::Consumer::validateConsumedProduct ( BranchType const  bt,
ProductInfo const &  pi 
)
protectedinherited

Definition at line 101 of file Consumer.cc.

References art::errors::ProductRegistrationFailure.

103 {
104  // Early exits if consumes tracking has been disabled or if the
105  // consumed product is an allowed consumable.
106  if (!moduleContext_)
107  return;
108 
109  if (cet::binary_search_all(consumables_[bt], pi))
110  return;
111 
112  if (requireConsumes_) {
114  "Consumer: an error occurred during validation of a "
115  "retrieved product\n\n")
116  << "The following consumes (or mayConsume) statement is missing from\n"
117  << module_context(moduleDescription_) << ":\n\n"
118  << " " << assemble_consumes_statement(bt, pi) << "\n\n";
119  }
120 
121  missingConsumes_[bt].insert(pi);
122 }
cet::exempt_ptr< ModuleDescription const > moduleDescription_
Definition: Consumer.h:140
bool requireConsumes_
Definition: Consumer.h:137
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
ConsumableProductSets missingConsumes_
Definition: Consumer.h:139

Member Data Documentation

bool larg4::LArG4::fCheckOverlaps
private

Whether to use the G4 overlap checker.

Definition at line 319 of file LArG4_module.cc.

Referenced by beginJob().

bool larg4::LArG4::fdumpParticleList
private

Whether each event's sim::ParticleList will be displayed.

Definition at line 320 of file LArG4_module.cc.

Referenced by produce().

bool larg4::LArG4::fdumpSimChannels
private

Whether each event's sim::Channel will be displayed.

Definition at line 321 of file LArG4_module.cc.

Referenced by produce().

g4b::G4Helper* larg4::LArG4::fG4Help
private

G4 interface object.

Definition at line 312 of file LArG4_module.cc.

Referenced by beginJob(), produce(), and ~LArG4().

std::string larg4::LArG4::fG4MacroPath
private

directory path for Geant4 macro file to be executed before main MC processing.

Definition at line 317 of file LArG4_module.cc.

Referenced by beginJob(), and LArG4().

std::string larg4::LArG4::fG4PhysListName
private

predefined physics list to use if not making a custom one

Definition at line 316 of file LArG4_module.cc.

Referenced by beginJob().

std::vector<std::string> larg4::LArG4::fInputLabels
private

Definition at line 327 of file LArG4_module.cc.

Referenced by LArG4(), and produce().

std::vector<std::string> larg4::LArG4::fKeepParticlesInVolumes
private

Only write particles that have trajectories through these volumes.

Definition at line 328 of file LArG4_module.cc.

Referenced by beginRun().

larg4::LArVoxelListAction* larg4::LArG4::flarVoxelListAction
private

Geant4 user action to accumulate LAr voxel information.

Definition at line 313 of file LArG4_module.cc.

double larg4::LArG4::fOffPlaneMargin = 0.
private

dictate how tracks are put on stack.

Off-plane charge recovery margin

Definition at line 325 of file LArG4_module.cc.

Referenced by beginJob().

larg4::ParticleListAction* larg4::LArG4::fparticleListAction
private

Geant4 user action to particle information.

Definition at line 314 of file LArG4_module.cc.

Referenced by beginJob(), beginRun(), and produce().

int larg4::LArG4::fSmartStacking
private

Whether to instantiate and use class to.

Definition at line 324 of file LArG4_module.cc.

Referenced by beginJob().

bool larg4::LArG4::fSparsifyTrajectories
private

Sparsify MCParticle Trajectories.

Definition at line 330 of file LArG4_module.cc.

Referenced by LArG4(), and produce().

bool larg4::LArG4::fStoreReflected
private

Definition at line 323 of file LArG4_module.cc.

Referenced by LArG4(), and produce().

bool larg4::LArG4::fUseLitePhotons
private

Definition at line 322 of file LArG4_module.cc.

Referenced by LArG4(), and produce().


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