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" 32 #include "Geant4/G4VModularPhysicsList.hh" 34 #include "Geant4/G4PhysListFactoryAlt.hh" 35 #include "Geant4/G4PhysicsConstructorRegistry.hh" 47 static G4VisExecutive*
vm_ = 0;
52 : fCheckOverlaps (false )
53 , fValidateGDMLSchema(false )
54 , fUseStepLimits (false )
55 , fUIManager (nullptr)
56 , fConvertMCTruth (nullptr)
65 std::string
const& g4physicslist,
66 std::string
const& gdmlFile)
115 fRunManager->SetUserAction( static_cast<G4UserRunAction*>(0) );
116 fRunManager->SetUserAction( static_cast<G4UserEventAction*>(0) );
117 fRunManager->SetUserAction( static_cast<G4UserTrackingAction*>(0) );
118 fRunManager->SetUserAction( static_cast<G4UserSteppingAction*>(0) );
120 fRunManager->SetUserAction( static_cast<G4UserStackingAction*>(0) );
127 <<
"G4Helper never initialized; probably because there were no input primary events";
159 G4VUserPhysicsList* physics = 0;
160 std::string bywhom =
"User";
161 std::string factoryname =
"g4alt::G4PhysListFactory";
162 bool list_known_ctors =
true;
167 std::vector< std::string > pstrings;
169 boost::algorithm::split( pstrings, physicsString, boost::is_any_of(
";"),
170 boost::token_compress_on );
172 for (
unsigned int j=0; j < pstrings.size(); ++j )
173 boost::algorithm::trim(pstrings[j]);
175 if ( pstrings.size() < 1 ) pstrings.push_back(
"");
176 std::string phListName = pstrings[0];
183 g4alt::G4PhysListFactory factory;
184 factoryname =
"g4alt::G4PhysListFactory";
186 if ( factory.IsReferencePhysList(phListName) ) {
187 bywhom = factoryname;
188 physics = factory.GetReferencePhysList(phListName);
192 if ( phListName !=
"" ) {
193 std::cerr << std::endl << factoryname
194 <<
" failed to find ReferencePhysList \"" 195 << phListName <<
"\"" << std::endl;
196 factory.PrintAvailablePhysLists();
211 << bywhom <<
" could not construct \"" 215 <<
"FAIL hard if we don't succeed";
218 phListName =
"<none>";
223 <<
" constructed G4VUserPhysicsList \"" 234 for (
unsigned int k=1; k < pstrings.size(); ++k ) {
235 std::string physProcAddition = pstrings[k];
238 std::vector< std::string > physProcParts;
239 boost::algorithm::split( physProcParts, physProcAddition,
240 boost::is_any_of(
"(,)"),
241 boost::token_compress_on );
243 for (
unsigned int j=0; j < physProcParts.size(); ++j )
244 boost::algorithm::trim(physProcParts[j]);
247 std::string physProcName = physProcParts[0];
248 if ( physProcName ==
"" )
continue;
250 G4PhysicsConstructorRegistry* pcRegistry =
251 G4PhysicsConstructorRegistry::Instance();
253 if ( ! pcRegistry->IsKnownPhysicsConstructor(physProcName) ) {
256 <<
"G4PhysicsProcessFactorySingleton could not " 261 if ( ! list_known_ctors )
continue;
263 list_known_ctors =
false;
264 std::vector<G4String> list = pcRegistry->AvailablePhysicsConstructors();
266 <<
"For reference: PhysicsProcesses in " 267 <<
"G4PhysicsProcessFactorySingleton are: ";
271 <<
" ... no registered processes";
273 for (
size_t indx=0; indx < list.size(); ++indx ) {
275 <<
" [" << std::setw(2) << indx <<
"] " 276 <<
"\"" << list[indx] <<
"\"";
285 <<
"\" physics process to \"" 290 G4VPhysicsConstructor* pctor =
291 pcRegistry->GetPhysicsConstructor(physProcName);
294 G4VModularPhysicsList* mpl =
dynamic_cast<G4VModularPhysicsList*
>(physics);
295 if ( ! pctor )
MF_LOG_VERBATIM(
"G4Helper") <<
" ... failed with null pointer";
296 else if ( ! mpl )
MF_LOG_VERBATIM(
"G4Helper") <<
" ... failed, physics list wasn't a G4VModularPhysicsList";
297 else mpl->RegisterPhysics(pctor);
303 for (
unsigned int i=1; i < physProcParts.size(); ++i ) {
304 if ( physProcParts[i] ==
"" )
continue;
316 auto mpl =
dynamic_cast<G4VModularPhysicsList*
>(physics);
317 if(mpl) mpl->RegisterPhysics(
new G4StepLimiterPhysics());
320 <<
"Step limits requested, but unable to register G4StepLimiterPhysics" 321 <<
"\n NO STEP LIMITS WILL BE APPLIED";
333 for(
auto const& pw : pworlds){
359 G4LogicalVolume* logVol = G4LogicalVolumeStore::GetInstance()->GetVolume(volumeName);
363 G4UserLimits *stepLimit =
new G4UserLimits(maxStepSize);
364 logVol->SetUserLimits(stepLimit);
370 <<
"Unable to find volume " 372 <<
" and set step size limit";
386 fDetector->RegisterParallelWorld(pWorld);
420 G4UserRunAction* runAction = (G4UserRunAction* ) uaManager;
421 G4UserEventAction* eventAction = (G4UserEventAction* ) uaManager;
422 G4UserTrackingAction* trackingAction = (G4UserTrackingAction*) uaManager;
423 G4UserSteppingAction* steppingAction = (G4UserSteppingAction*) uaManager;
430 G4UserStackingAction* stackingAction = (G4UserStackingAction*) uaManager;
438 if(!vm_) vm_ =
new G4VisExecutive();
455 return this->
G4Run( primary.
get() );
483 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)
#define MF_LOG_ERROR(category)
void SetParallelWorlds(std::vector< G4VUserParallelWorld * > pworlds)
std::vector< G4VUserParallelWorld * > fParallelWorlds
list of parallel worlds
Use Geant4 to run the LArSoft detector simulation.
void InitPhysics()
Initialization for the Geant4 Monte Carlo.
void SetPhysicsList(std::string physicsList)
static G4VisExecutive * vm_
std::string fGDMLFile
Name of the gdml file containing the detector Geometry.
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.
DetectorConstruction * fDetector
DetectorConstruction object.
G4Helper()
Standard constructor and destructor for an FMWK module.
static UserActionManager * Instance()
#define MF_LOG_VERBATIM(category)
G4RunManager * fRunManager
Geant4's run manager.
std::string fG4PhysListName
Name of physics list to use.
void Append(art::Ptr< simb::MCTruth > &mct)
Event generator information.
bool fUseStepLimits
Set in SetVolumeStepLimit.
#define MF_LOG_WARNING(category)
ConvertMCTruthToG4 * fConvertMCTruth
Geant4 event generator.
G4UImanager * fUIManager
Geant4's user-interface manager.