File indexing completed on 2026-04-10 07:50:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <csignal>
0017
0018 #include "G4RunManager.hh"
0019 #include "G4VUserDetectorConstruction.hh"
0020 #include "G4VUserPrimaryGeneratorAction.hh"
0021 #include "G4UserRunAction.hh"
0022 #include "G4UserEventAction.hh"
0023 #include "G4UserTrackingAction.hh"
0024 #include "G4UserSteppingAction.hh"
0025
0026 #include "G4SystemOfUnits.hh"
0027 #include "G4ParticleTable.hh"
0028 #include "G4ParticleGun.hh"
0029 #include "G4GeometryManager.hh"
0030
0031 #include "OPTICKS_LOG.hh"
0032 #include "SEvt.hh"
0033 #include "ssys.h"
0034 #include "SPath.hh"
0035 #include "SEventConfig.hh"
0036 #include "NP.hh"
0037 #include "sframe.h"
0038
0039 #include "U4Material.hh"
0040 #include "U4VolumeMaker.hh"
0041 #include "U4Recorder.hh"
0042 #include "U4Random.hh"
0043 #include "U4Physics.hh"
0044 #include "U4VPrimaryGenerator.h"
0045
0046 #ifdef WITH_PMTSIM
0047 #include "PMTSim.hh"
0048 #endif
0049
0050
0051 struct U4App
0052 :
0053 public G4UserRunAction,
0054 public G4UserEventAction,
0055 public G4UserTrackingAction,
0056 public G4UserSteppingAction,
0057 public G4VUserPrimaryGeneratorAction,
0058 public G4VUserDetectorConstruction
0059 {
0060 static const plog::Severity LEVEL ;
0061 static std::string Desc();
0062 static char PrimaryMode();
0063 static G4ParticleGun* InitGun();
0064
0065 G4RunManager* fRunMgr ;
0066 char fPrimaryMode ;
0067 U4Recorder* fRecorder ;
0068 G4ParticleGun* fGun ;
0069 G4VPhysicalVolume* fPV ;
0070
0071 G4VPhysicalVolume* Construct();
0072
0073 void BeginOfRunAction(const G4Run*);
0074 void EndOfRunAction(const G4Run*);
0075
0076 void GeneratePrimaries(G4Event* evt);
0077 void BeginOfEventAction(const G4Event*);
0078 void EndOfEventAction(const G4Event*);
0079
0080 void PreUserTrackingAction(const G4Track*);
0081 void PostUserTrackingAction(const G4Track*);
0082
0083 void UserSteppingAction(const G4Step*);
0084
0085
0086 U4App(G4RunManager* runMgr);
0087 virtual ~U4App();
0088
0089 static void SaveMeta(const char* savedir);
0090 static G4RunManager* InitRunManager();
0091 static U4App* Create();
0092 void BeamOn() ;
0093 static void Main();
0094
0095 };
0096
0097 const plog::Severity U4App::LEVEL = info ;
0098
0099 std::string U4App::Desc()
0100 {
0101 std::string phy = U4Physics::Desc() ;
0102 std::string rec = U4Recorder::Desc() ;
0103 std::stringstream ss ;
0104 if(!phy.empty()) ss << phy ;
0105 if(!rec.empty()) ss << "/" << rec ;
0106 std::string s = ss.str();
0107 return s ;
0108 }
0109
0110 char U4App::PrimaryMode()
0111 {
0112 char mode = '?' ;
0113 const char* mode_ = ssys::getenvvar("U4App__PRIMARY_MODE", "gun" );
0114 if(strcmp(mode_, "gun") == 0) mode = 'G' ;
0115 if(strcmp(mode_, "torch") == 0) mode = 'T' ;
0116 if(strcmp(mode_, "iphoton") == 0) mode = 'I' ;
0117 return mode ;
0118 }
0119
0120 G4ParticleGun* U4App::InitGun()
0121 {
0122 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
0123 G4ParticleDefinition* particle = particleTable->FindParticle("e+");
0124 LOG(LEVEL) << " particle " << particle ;
0125 G4ParticleGun* gun = new G4ParticleGun(1) ;
0126 gun->SetParticleDefinition(particle);
0127 gun->SetParticleTime(0.0*CLHEP::ns);
0128 gun->SetParticlePosition(G4ThreeVector(0.0*CLHEP::cm,0.0*CLHEP::cm,0.0*CLHEP::cm));
0129 gun->SetParticleMomentumDirection(G4ThreeVector(1.,0.,0.));
0130 gun->SetParticleEnergy(1.0*MeV);
0131 return gun ;
0132 }
0133
0134 U4App::U4App(G4RunManager* runMgr)
0135 :
0136 fRunMgr(runMgr),
0137 fPrimaryMode(PrimaryMode()),
0138 fRecorder(new U4Recorder),
0139 fGun(fPrimaryMode == 'G' ? InitGun() : nullptr),
0140 fPV(nullptr)
0141 {
0142 fRunMgr->SetUserInitialization((G4VUserDetectorConstruction*)this);
0143 fRunMgr->SetUserAction((G4VUserPrimaryGeneratorAction*)this);
0144 fRunMgr->SetUserAction((G4UserRunAction*)this);
0145 fRunMgr->SetUserAction((G4UserEventAction*)this);
0146 fRunMgr->SetUserAction((G4UserTrackingAction*)this);
0147 fRunMgr->SetUserAction((G4UserSteppingAction*)this);
0148 fRunMgr->Initialize();
0149
0150 }
0151
0152 G4VPhysicalVolume* U4App::Construct()
0153 {
0154 LOG(info) << "[" ;
0155 const G4VPhysicalVolume* pv_ = U4VolumeMaker::PV() ;
0156 LOG_IF(fatal, pv_ == nullptr) << " FAILED TO CREATE PV : CHECK GEOM envvar " ;
0157 if(pv_ == nullptr) std::raise(SIGINT) ;
0158
0159 G4VPhysicalVolume* pv = const_cast<G4VPhysicalVolume*>(pv_);
0160 fPV = pv ;
0161 LOG(LEVEL) << " fPV " << ( fPV ? fPV->GetName() : "ERR-NO-PV" ) ;
0162
0163 LOG(info) << "]" ;
0164 return pv ;
0165 }
0166
0167
0168 void U4App::BeginOfRunAction(const G4Run* run)
0169 {
0170 LOG(info) ;
0171 fRecorder->BeginOfRunAction(run);
0172 }
0173 void U4App::EndOfRunAction(const G4Run* run)
0174 {
0175 LOG(info);
0176 fRecorder->EndOfRunAction(run);
0177 }
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 void U4App::GeneratePrimaries(G4Event* )
0190 {
0191 std::raise(SIGINT) ;
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 }
0211
0212 void U4App::BeginOfEventAction(const G4Event* event)
0213 {
0214
0215 fRecorder->BeginOfEventAction(event);
0216 }
0217 void U4App::EndOfEventAction(const G4Event* event)
0218 {
0219 fRecorder->EndOfEventAction(event);
0220
0221 const char* savedir = SEvt::GetSaveDir(1);
0222 SaveMeta(savedir);
0223
0224 #if defined(WITH_PMTSIM) && defined(POM_DEBUG)
0225 PMTSim::ModelTrigger_Debug_Save(savedir) ;
0226 #else
0227 LOG(info) << "not-(WITH_PMTSIM and POM_DEBUG)" ;
0228 #endif
0229 }
0230
0231 void U4App::PreUserTrackingAction(const G4Track* trk){ fRecorder->PreUserTrackingAction(trk); }
0232 void U4App::PostUserTrackingAction(const G4Track* trk){ fRecorder->PostUserTrackingAction(trk); }
0233 void U4App::UserSteppingAction(const G4Step* step){ fRecorder->UserSteppingAction(step) ; }
0234
0235
0236 U4App::~U4App(){ G4GeometryManager::GetInstance()->OpenGeometry(); }
0237
0238
0239
0240 void U4App::SaveMeta(const char* savedir)
0241 {
0242 if(savedir == nullptr)
0243 {
0244 LOG(error) << " NULL savedir " ;
0245 return ;
0246 }
0247
0248 U4VolumeMaker::SaveTransforms(savedir) ;
0249 }
0250
0251 G4RunManager* U4App::InitRunManager()
0252 {
0253 G4VUserPhysicsList* phy = (G4VUserPhysicsList*)new U4Physics ;
0254 G4RunManager* run = new G4RunManager ;
0255 run->SetUserInitialization(phy) ;
0256 return run ;
0257 }
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267 U4App* U4App::Create()
0268 {
0269 LOG(info) << U4Recorder::Switches() ;
0270
0271 G4RunManager* run = InitRunManager();
0272 U4App* app = new U4App(run);
0273 return app ;
0274 }
0275
0276 void U4App::BeamOn()
0277 {
0278 fRunMgr->BeamOn(ssys::getenvint("BeamOn",1));
0279 }
0280
0281
0282
0283 void U4App::Main()
0284 {
0285 LOG(info) << SLOG::Banner() ;
0286
0287 U4App* app = U4App::Create() ;
0288 app->BeamOn();
0289 delete app ;
0290
0291 LOG(info) << SLOG::Banner() << " " << " savedir " << SEvt::GetSaveDir(1) ;
0292 }
0293
0294
0295