File indexing completed on 2026-04-09 07:49:03
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
0032 #include "ssys.h"
0033 #include "sframe.h"
0034
0035 #include "OPTICKS_LOG.hh"
0036 #include "SEvt.hh"
0037 #include "SSim.hh"
0038 #include "SEventConfig.hh"
0039 #include "SRM.h"
0040 #include "SGenerate.h"
0041 #include "SEvent.hh"
0042
0043
0044 #include "U4Material.hh"
0045 #include "U4VolumeMaker.hh"
0046 #include "U4Recorder.hh"
0047 #include "U4Random.hh"
0048 #include "U4Physics.hh"
0049 #include "U4SensitiveDetector.hh"
0050 #include "U4VPrimaryGenerator.h"
0051
0052 #include "G4CXOpticks.hh"
0053
0054
0055 struct G4CXApp
0056 :
0057 public G4UserRunAction,
0058 public G4UserEventAction,
0059 public G4UserTrackingAction,
0060 public G4UserSteppingAction,
0061 public G4VUserPrimaryGeneratorAction,
0062 public G4VUserDetectorConstruction
0063 {
0064 static const plog::Severity LEVEL ;
0065 static std::string Desc();
0066 static G4ParticleGun* InitGun();
0067 static U4SensitiveDetector* InitSensDet();
0068
0069 G4RunManager* fRunMgr ;
0070 U4Recorder* fRecorder ;
0071 G4ParticleGun* fGun ;
0072 U4SensitiveDetector* fSensDet ;
0073 G4VPhysicalVolume* fPV ;
0074
0075
0076 G4VPhysicalVolume* Construct();
0077
0078 void BeginOfRunAction(const G4Run*);
0079 void EndOfRunAction(const G4Run*);
0080
0081 void GeneratePrimaries(G4Event* evt);
0082 void BeginOfEventAction(const G4Event*);
0083 void EndOfEventAction(const G4Event*);
0084
0085 void PreUserTrackingAction(const G4Track*);
0086 void PostUserTrackingAction(const G4Track*);
0087
0088 void UserSteppingAction(const G4Step*);
0089
0090
0091 G4CXApp(G4RunManager* runMgr);
0092 static void OpenGeometry() ;
0093 virtual ~G4CXApp();
0094
0095 static G4RunManager* InitRunManager();
0096 static G4CXApp* Create();
0097 void BeamOn() ;
0098 static int Main();
0099
0100 };
0101
0102 const plog::Severity G4CXApp::LEVEL = info ;
0103
0104 std::string G4CXApp::Desc()
0105 {
0106 std::string phy = U4Physics::Desc() ;
0107 std::string rec = U4Recorder::Desc() ;
0108 std::stringstream ss ;
0109 if(!phy.empty()) ss << phy ;
0110 if(!rec.empty()) ss << "/" << rec ;
0111 std::string s = ss.str();
0112 return s ;
0113 }
0114
0115 G4ParticleGun* G4CXApp::InitGun()
0116 {
0117 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
0118 G4ParticleDefinition* particle = particleTable->FindParticle("e+");
0119 LOG(LEVEL) << " particle " << particle ;
0120 G4ParticleGun* gun = new G4ParticleGun(1) ;
0121 gun->SetParticleDefinition(particle);
0122 gun->SetParticleTime(0.0*CLHEP::ns);
0123 gun->SetParticlePosition(G4ThreeVector(0.0*CLHEP::cm,0.0*CLHEP::cm,0.0*CLHEP::cm));
0124 gun->SetParticleMomentumDirection(G4ThreeVector(1.,0.,0.));
0125 gun->SetParticleEnergy(1.0*MeV);
0126 return gun ;
0127 }
0128
0129 U4SensitiveDetector* G4CXApp::InitSensDet()
0130 {
0131 const char* sdn = ssys::getenvvar("G4CXApp__SensDet", "PMTSDMgr" ) ;
0132 U4SensitiveDetector* sd = sdn ? new U4SensitiveDetector(sdn) : nullptr ;
0133 std::cout
0134 << "G4CXApp::InitSensDet"
0135 << " sdn " << ( sdn ? sdn : "-" )
0136 << " sd " << ( sd ? "YES" : "NO " )
0137 << std::endl
0138 << U4SensitiveDetector::Desc()
0139 << std::endl
0140 ;
0141 return sd ;
0142 }
0143
0144 G4CXApp::G4CXApp(G4RunManager* runMgr)
0145 :
0146 fRunMgr(runMgr),
0147 fRecorder(new U4Recorder),
0148 fGun(SEventConfig::IsRunningModeGun() ? InitGun() : nullptr),
0149 fSensDet(InitSensDet()),
0150 fPV(nullptr)
0151 {
0152 fRunMgr->SetUserInitialization((G4VUserDetectorConstruction*)this);
0153 fRunMgr->SetUserAction((G4VUserPrimaryGeneratorAction*)this);
0154 fRunMgr->SetUserAction((G4UserRunAction*)this);
0155 fRunMgr->SetUserAction((G4UserEventAction*)this);
0156 fRunMgr->SetUserAction((G4UserTrackingAction*)this);
0157 fRunMgr->SetUserAction((G4UserSteppingAction*)this);
0158 fRunMgr->Initialize();
0159
0160 LOG(info) << std::endl << U4Recorder::Desc() ;
0161 }
0162
0163 G4VPhysicalVolume* G4CXApp::Construct()
0164 {
0165 LOG(info) << "[" ;
0166 const G4VPhysicalVolume* pv_ = U4VolumeMaker::PV() ;
0167 LOG_IF(fatal, pv_ == nullptr)
0168 << " FAILED TO CREATE PV : CHECK GEOM envvar "
0169 << std::endl
0170 << U4VolumeMaker::Desc()
0171 ;
0172
0173 if(pv_ == nullptr) std::raise(SIGINT) ;
0174
0175 G4VPhysicalVolume* pv = const_cast<G4VPhysicalVolume*>(pv_);
0176 fPV = pv ;
0177 LOG(LEVEL) << " fPV " << ( fPV ? fPV->GetName() : "ERR-NO-PV" ) ;
0178
0179 LOG(info) << "]" ;
0180
0181
0182 SSim::AddExtraSubfold("jpmt", "$CFBaseFromGEOM/CSGFoundry/SSim/extra/jpmt" );
0183
0184
0185 if(SEventConfig::GPU_Simulation())
0186 {
0187 G4CXOpticks::SetGeometry(pv_) ;
0188 G4CXOpticks::SaveGeometry() ;
0189
0190 assert( fRecorder->getU4Tree() );
0191 }
0192 else
0193 {
0194 LOG(LEVEL) << " SEventConfig::GPU_Simulation() false : SKIP G4CXOpticks::SetGeometry " ;
0195 }
0196
0197 return pv ;
0198 }
0199
0200 void G4CXApp::BeginOfRunAction(const G4Run* run){ fRecorder->BeginOfRunAction(run); }
0201 void G4CXApp::EndOfRunAction(const G4Run* run){ fRecorder->EndOfRunAction(run); }
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226 void G4CXApp::GeneratePrimaries(G4Event* event)
0227 {
0228 G4int eventID = event->GetEventID();
0229
0230 LOG(LEVEL) << "[ SEventConfig::RunningModeLabel " << SEventConfig::RunningModeLabel() << " eventID " << eventID ;
0231 SEvt* sev = SEvt::Get_ECPU();
0232 assert(sev);
0233
0234 if(SEventConfig::IsRunningModeGun())
0235 {
0236 LOG(fatal) << " THIS MODE NEEDS WORK ON U4PHYSICS " ;
0237 std::raise(SIGINT);
0238 fGun->GeneratePrimaryVertex(event) ;
0239 }
0240 else if(SEventConfig::IsRunningModeTorch())
0241 {
0242 int idx_arg = eventID ;
0243 NP* gs = SEvent::MakeTorchGenstep(idx_arg) ;
0244 NP* ph = SGenerate::GeneratePhotons(gs);
0245 U4VPrimaryGenerator::GeneratePrimaries_From_Photons(event, ph);
0246 delete ph ;
0247
0248 SEvent::SetGENSTEP(gs);
0249 }
0250 else if(SEventConfig::IsRunningModeInputPhoton())
0251 {
0252 NP* ph = sev->getInputPhoton();
0253 U4VPrimaryGenerator::GeneratePrimaries_From_Photons(event, ph) ;
0254 }
0255 else if(SEventConfig::IsRunningModeInputGenstep())
0256 {
0257 LOG(fatal) << "General InputGensteps with Geant4 not implemented, use eg cxs_min.sh to do that with Opticks " ;
0258 std::raise(SIGINT);
0259 }
0260 LOG(LEVEL) << "] " << " eventID " << eventID ;
0261 }
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 void G4CXApp::BeginOfEventAction(const G4Event* event)
0272 {
0273 G4int eventID = event->GetEventID();
0274 fRecorder->BeginOfEventAction_(eventID);
0275 }
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 void G4CXApp::EndOfEventAction(const G4Event* event)
0302 {
0303 G4int eventID = event->GetEventID();
0304 fRecorder->EndOfEventAction_(eventID);
0305
0306 if(SEventConfig::GPU_Simulation())
0307 {
0308 G4CXOpticks* gx = G4CXOpticks::Get() ;
0309 bool end = true ;
0310 gx->simulate(eventID, end ) ;
0311 }
0312 }
0313
0314 void G4CXApp::PreUserTrackingAction(const G4Track* trk){ fRecorder->PreUserTrackingAction(trk); }
0315 void G4CXApp::PostUserTrackingAction(const G4Track* trk){ fRecorder->PostUserTrackingAction(trk); }
0316 void G4CXApp::UserSteppingAction(const G4Step* step){ fRecorder->UserSteppingAction(step) ; }
0317
0318 void G4CXApp::OpenGeometry(){ G4GeometryManager::GetInstance()->OpenGeometry(); }
0319 G4CXApp::~G4CXApp(){ OpenGeometry(); }
0320
0321
0322
0323 G4RunManager* G4CXApp::InitRunManager()
0324 {
0325 G4VUserPhysicsList* phy = (G4VUserPhysicsList*)new U4Physics ;
0326 G4RunManager* run = new G4RunManager ;
0327 run->SetUserInitialization(phy) ;
0328 return run ;
0329 }
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339 G4CXApp* G4CXApp::Create()
0340 {
0341 LOG(info) << U4Recorder::Switches() ;
0342
0343 G4RunManager* run = InitRunManager();
0344 G4CXApp* app = new G4CXApp(run);
0345 return app ;
0346 }
0347
0348 void G4CXApp::BeamOn()
0349 {
0350 LOG(info) << "[ " << SEventConfig::kNumEvent << "=" << SEventConfig::NumEvent() ;
0351 fRunMgr->BeamOn(SEventConfig::NumEvent()) ;
0352 LOG(info) << "]" ;
0353 }
0354
0355 int G4CXApp::Main()
0356 {
0357 G4CXApp* app = G4CXApp::Create() ;
0358 app->BeamOn();
0359 delete app ;
0360 return 0 ;
0361 }
0362