15 #include "Geant4/G4UImanager.hh" 16 #include "Geant4/G4VUserDetectorConstruction.hh" 17 #include "Geant4/G4VUserPrimaryGeneratorAction.hh" 18 #include "Geant4/G4VUserPhysicsList.hh" 19 #include "Geant4/G4UserLimits.hh" 20 #include "Geant4/G4UserRunAction.hh" 21 #include "Geant4/G4UserEventAction.hh" 22 #include "Geant4/G4UserTrackingAction.hh" 23 #include "Geant4/G4UserSteppingAction.hh" 24 #include "Geant4/G4VisExecutive.hh" 25 #include "Geant4/G4StepLimiterPhysics.hh" 26 #include "Geant4/G4LogicalVolumeStore.hh" 28 #include <boost/algorithm/string.hpp> 30 #include "Geant4/QGSP_BERT.hh" 31 #define TRY_NEW_PL_FACTORY 32 #ifdef TRY_NEW_PL_FACTORY 35 #include "Geant4/G4PhysListFactory.hh" 39 #include "Geant4/G4VModularPhysicsList.hh" 51 static G4VisExecutive*
vm_ = 0;
56 : fCheckOverlaps (false )
57 , fValidateGDMLSchema(false )
58 , fUseStepLimits (false )
59 , fUIManager (nullptr)
60 , fConvertMCTruth (nullptr)
69 std::string
const& g4physicslist,
70 std::string
const& gdmlFile)
119 fRunManager->SetUserAction( static_cast<G4UserRunAction*>(0) );
120 fRunManager->SetUserAction( static_cast<G4UserEventAction*>(0) );
121 fRunManager->SetUserAction( static_cast<G4UserTrackingAction*>(0) );
122 fRunManager->SetUserAction( static_cast<G4UserSteppingAction*>(0) );
124 fRunManager->SetUserAction( static_cast<G4UserStackingAction*>(0) );
131 <<
"G4Helper never initialized; probably because there were no input primary events";
163 G4VUserPhysicsList* physics = 0;
164 std::string bywhom =
"User";
165 std::string factoryname =
"G4PhysListFactory";
166 bool list_known_procs =
true;
171 std::vector< std::string > pstrings;
173 boost::algorithm::split( pstrings, physicsString, boost::is_any_of(
";"),
174 boost::token_compress_on );
176 for (
unsigned int j=0; j < pstrings.size(); ++j )
177 boost::algorithm::trim(pstrings[j]);
179 if ( pstrings.size() < 1 ) pstrings.push_back(
"");
180 std::string phListName = pstrings[0];
187 #ifdef TRY_NEW_PL_FACTORY 190 factoryname =
"alt::G4PhysListFactory";
209 G4PhysListFactory factory;
213 if ( factory.IsReferencePhysList(phListName) ) {
214 bywhom = factoryname;
219 if ( phListName !=
"" ) {
220 std::cerr << std::endl << factoryname
221 <<
" failed to find ReferencePhysList \"" 222 << phListName <<
"\"" << std::endl;
223 #ifdef TRY_NEW_PL_FACTORY 224 factory.PrintAvailablePhysLists();
226 std::vector<G4String> list = factory.AvailablePhysLists();
228 <<
"For reference: PhysicsLists in G4PhysListFactory are: ";
229 for (
size_t indx=0; indx < list.size(); ++indx ) {
231 <<
" [" << std::setw(2) << indx <<
"] " 232 <<
"\"" << list[indx] <<
"\"";
241 <<
"G4PhysListFactory could not construct \"" 245 <<
"fall back to using QGSP_BERT";
247 physics =
new QGSP_BERT;
248 phListName =
"QGSP_BERT";
253 <<
" constructed G4VUserPhysicsList \"" 264 for (
unsigned int k=1; k < pstrings.size(); ++k ) {
265 std::string physProcAddition = pstrings[k];
268 std::vector< std::string > physProcParts;
269 boost::algorithm::split( physProcParts, physProcAddition,
270 boost::is_any_of(
"(,)"),
271 boost::token_compress_on );
273 for (
unsigned int j=0; j < physProcParts.size(); ++j )
274 boost::algorithm::trim(physProcParts[j]);
277 std::string physProcName = physProcParts[0];
278 if ( physProcName ==
"" )
continue;
284 <<
"G4PhysicsProcessFactorySingleton could not " 289 if ( ! list_known_procs )
continue;
290 list_known_procs =
false;
293 <<
"For reference: PhysicsProcesses in " 294 <<
"G4PhysicsProcessFactorySingleton are: ";
298 <<
" ... no registered processes";
300 for (
size_t indx=0; indx < list.size(); ++indx ) {
302 <<
" [" << std::setw(2) << indx <<
"] " 303 <<
"\"" << list[indx] <<
"\"";
312 <<
"\" physics process to \"" 320 G4VModularPhysicsList* mpl =
dynamic_cast<G4VModularPhysicsList*
>(physics);
321 if ( ! pctor )
LOG_VERBATIM(
"G4Helper") <<
" ... failed with null pointer";
322 else if ( ! mpl )
LOG_VERBATIM(
"G4Helper") <<
" ... failed, physics list wasn't a G4VModularPhysicsList";
323 else mpl->RegisterPhysics(pctor);
329 for (
unsigned int i=1; i < physProcParts.size(); ++i ) {
330 if ( physProcParts[i] ==
"" )
continue;
342 auto mpl =
dynamic_cast<G4VModularPhysicsList*
>(physics);
343 if(mpl) mpl->RegisterPhysics(
new G4StepLimiterPhysics());
346 <<
"Step limits requested, but unable to register G4StepLimiterPhysics" 347 <<
"\n NO STEP LIMITS WILL BE APPLIED";
359 for(
auto const& pw : pworlds){
385 G4LogicalVolume* logVol = G4LogicalVolumeStore::GetInstance()->GetVolume(volumeName);
389 G4UserLimits *stepLimit =
new G4UserLimits(maxStepSize);
390 logVol->SetUserLimits(stepLimit);
396 <<
"Unable to find volume " 398 <<
" and set step size limit";
412 fDetector->RegisterParallelWorld(pWorld);
446 G4UserRunAction* runAction = (G4UserRunAction* ) uaManager;
447 G4UserEventAction* eventAction = (G4UserEventAction* ) uaManager;
448 G4UserTrackingAction* trackingAction = (G4UserTrackingAction*) uaManager;
449 G4UserSteppingAction* steppingAction = (G4UserSteppingAction*) uaManager;
456 G4UserStackingAction* stackingAction = (G4UserStackingAction*) uaManager;
464 if(!vm_) vm_ =
new G4VisExecutive();
481 return this->
G4Run( primary.
get() );
509 for(
auto primary : primaries)
Build Geant4 geometry from GDML.
virtual bool DoesAnyActionProvideStacking()
void Reset()
Get ready to convert a new set of MCTruth objects.
bool fValidateGDMLSchema
Have G4GDML validate geometry schema?
bool G4Run(std::vector< const simb::MCTruth * > &primaries)
void SetUserAction()
Initialization for the Geant4 Monte Carlo.
void ConstructDetector(std::string const &gdmlFile)
void SetParallelWorlds(std::vector< G4VUserParallelWorld * > pworlds)
std::vector< G4VUserParallelWorld * > fParallelWorlds
list of parallel worlds
Use Geant4 to run the LArSoft detector simulation.
const std::vector< G4String > & AvailablePhysicsProcesses() const
void InitPhysics()
Initialization for the Geant4 Monte Carlo.
#define LOG_ERROR(category)
void SetPhysicsList(std::string physicsList)
static G4VisExecutive * vm_
std::string fGDMLFile
Name of the gdml file containing the detector Geometry.
static G4PhysicsProcessFactorySingleton & Instance()
G4VModularPhysicsList * GetReferencePhysList(const G4String &)
bool fCheckOverlaps
Have G4GDML check for overlaps?
basic interface to Geant4 for ART-based software
void SetVolumeStepLimit(std::string const &volumeName, double maxStepSize)
std::string fG4MacroPath
to be executed before main MC processing.
#define LOG_WARNING(category)
DetectorConstruction * fDetector
DetectorConstruction object.
G4Helper()
Standard constructor and destructor for an FMWK module.
G4bool IsKnownPhysicsProcess(const G4String &)
static UserActionManager * Instance()
G4RunManager * fRunManager
Geant4's run manager.
std::string fG4PhysListName
Name of physics list to use.
#define LOG_VERBATIM(category)
void Append(art::Ptr< simb::MCTruth > &mct)
Event generator information.
bool fUseStepLimits
Set in SetVolumeStepLimit.
G4VPhysicsConstructor * GetPhysicsProcess(const G4String &)
ConvertMCTruthToG4 * fConvertMCTruth
Geant4 event generator.
G4UImanager * fUIManager
Geant4's user-interface manager.