File indexing completed on 2026-04-10 07:50:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <iomanip>
0016 #include "ssys.h"
0017 #include "sstr.h"
0018 #include "U4Physics.hh"
0019 #include "U4OpBoundaryProcess.h"
0020 #include "G4ProcessManager.hh"
0021 #include "G4FastSimulationManagerProcess.hh"
0022
0023
0024 #if defined(WITH_CUSTOM4) && defined(WITH_PMTSIM)
0025 #include "G4OpBoundaryProcess.hh"
0026 #include "C4OpBoundaryProcess.hh"
0027 #include "PMTSimParamSvc/PMTAccessor.h"
0028 #elif defined(WITH_CUSTOM4) && !defined(WITH_PMTSIM)
0029 #include "G4OpBoundaryProcess.hh"
0030 #include "C4OpBoundaryProcess.hh"
0031 #include "SPMTAccessor.h"
0032 #elif defined(WITH_INSTRUMENTED_DEBUG)
0033 #include "InstrumentedG4OpBoundaryProcess.hh"
0034 #else
0035 #include "G4OpBoundaryProcess.hh"
0036 #endif
0037
0038
0039 #include "SLOG.hh"
0040 const plog::Severity U4Physics::LEVEL = SLOG::EnvLevel("U4Physics", "DEBUG") ;
0041
0042 U4Physics::U4Physics()
0043 :
0044 fCerenkov(nullptr),
0045 fScintillation(nullptr),
0046 fAbsorption(nullptr),
0047 fRayleigh(nullptr),
0048 fBoundary(nullptr),
0049 fFastSim(nullptr)
0050 {
0051 Cerenkov_DISABLE = EInt(_Cerenkov_DISABLE, "0") ;
0052 Scintillation_DISABLE = EInt(_Scintillation_DISABLE, "0" );
0053 OpAbsorption_DISABLE = EInt(_OpAbsorption_DISABLE, "0") ;
0054 OpRayleigh_DISABLE = EInt(_OpRayleigh_DISABLE, "0") ;
0055 OpBoundaryProcess_DISABLE = EInt(_OpBoundaryProcess_DISABLE, "0") ;
0056 OpBoundaryProcess_LASTPOST = EInt(_OpBoundaryProcess_LASTPOST, "0") ;
0057 FastSim_ENABLE = EInt(_FastSim_ENABLE, "0") ;
0058 }
0059
0060
0061
0062
0063 #include "G4BosonConstructor.hh"
0064 #include "G4LeptonConstructor.hh"
0065 #include "G4MesonConstructor.hh"
0066 #include "G4BaryonConstructor.hh"
0067 #include "G4IonConstructor.hh"
0068
0069
0070 void U4Physics::ConstructParticle()
0071 {
0072 G4BosonConstructor::ConstructParticle();
0073 G4LeptonConstructor::ConstructParticle();
0074 G4MesonConstructor::ConstructParticle();
0075 G4BaryonConstructor::ConstructParticle();
0076 G4IonConstructor::ConstructParticle();
0077 }
0078
0079 void U4Physics::ConstructProcess()
0080 {
0081 AddTransportation();
0082 ConstructEM();
0083 ConstructOp();
0084 }
0085
0086
0087
0088 #include "G4ComptonScattering.hh"
0089 #include "G4GammaConversion.hh"
0090 #include "G4PhotoElectricEffect.hh"
0091
0092 #include "G4eMultipleScattering.hh"
0093 #include "G4MuMultipleScattering.hh"
0094 #include "G4hMultipleScattering.hh"
0095
0096 #include "G4eIonisation.hh"
0097 #include "G4eBremsstrahlung.hh"
0098 #include "G4eplusAnnihilation.hh"
0099
0100 #include "G4MuIonisation.hh"
0101 #include "G4MuBremsstrahlung.hh"
0102 #include "G4MuPairProduction.hh"
0103
0104 #include "G4hIonisation.hh"
0105
0106 void U4Physics::ConstructEM()
0107 {
0108 G4int em_verbosity = 0 ;
0109 G4EmParameters* empar = G4EmParameters::Instance() ;
0110 empar->SetVerbose(em_verbosity);
0111 empar->SetWorkerVerbose(em_verbosity);
0112
0113 auto particleIterator=GetParticleIterator();
0114 particleIterator->reset();
0115 while( (*particleIterator)() )
0116 {
0117 G4ParticleDefinition* particle = particleIterator->value();
0118
0119 G4ProcessManager* pmanager = particle->GetProcessManager();
0120 G4String particleName = particle->GetParticleName();
0121
0122 if (particleName == "gamma") {
0123
0124
0125 pmanager->AddDiscreteProcess(new G4GammaConversion());
0126 pmanager->AddDiscreteProcess(new G4ComptonScattering());
0127 pmanager->AddDiscreteProcess(new G4PhotoElectricEffect());
0128
0129 } else if (particleName == "e-") {
0130
0131
0132 pmanager->AddProcess(new G4eMultipleScattering(),-1, 1, 1);
0133 pmanager->AddProcess(new G4eIonisation(), -1, 2, 2);
0134 pmanager->AddProcess(new G4eBremsstrahlung(), -1, 3, 3);
0135
0136 } else if (particleName == "e+") {
0137
0138
0139 pmanager->AddProcess(new G4eMultipleScattering(),-1, 1, 1);
0140 pmanager->AddProcess(new G4eIonisation(), -1, 2, 2);
0141 pmanager->AddProcess(new G4eBremsstrahlung(), -1, 3, 3);
0142 pmanager->AddProcess(new G4eplusAnnihilation(), 0,-1, 4);
0143
0144 } else if( particleName == "mu+" ||
0145 particleName == "mu-" ) {
0146
0147
0148 pmanager->AddProcess(new G4MuMultipleScattering(),-1, 1, 1);
0149 pmanager->AddProcess(new G4MuIonisation(), -1, 2, 2);
0150 pmanager->AddProcess(new G4MuBremsstrahlung(), -1, 3, 3);
0151 pmanager->AddProcess(new G4MuPairProduction(), -1, 4, 4);
0152
0153 } else {
0154 if ((particle->GetPDGCharge() != 0.0) &&
0155 (particle->GetParticleName() != "chargedgeantino") &&
0156 !particle->IsShortLived()) {
0157
0158 pmanager->AddProcess(new G4hMultipleScattering(),-1,1,1);
0159 pmanager->AddProcess(new G4hIonisation(), -1,2,2);
0160 }
0161 }
0162 }
0163 }
0164
0165 #include "Local_G4Cerenkov_modified.hh"
0166 #include "Local_DsG4Scintillation.hh"
0167
0168 #include "ShimG4OpAbsorption.hh"
0169 #include "ShimG4OpRayleigh.hh"
0170
0171
0172 std::string U4Physics::desc() const
0173 {
0174 std::stringstream ss ;
0175 ss
0176 << "U4Physics::desc" << "\n"
0177 << std::setw(60) << _Cerenkov_DISABLE << " : " << Cerenkov_DISABLE << "\n"
0178 << std::setw(60) << _Scintillation_DISABLE << " : " << Scintillation_DISABLE << "\n"
0179 << std::setw(60) << _OpAbsorption_DISABLE << " : " << OpAbsorption_DISABLE << "\n"
0180 << std::setw(60) << _OpRayleigh_DISABLE << " : " << OpRayleigh_DISABLE << "\n"
0181 << std::setw(60) << _OpBoundaryProcess_DISABLE << " : " << OpBoundaryProcess_DISABLE << "\n"
0182 << std::setw(60) << _OpBoundaryProcess_LASTPOST << " : " << OpBoundaryProcess_LASTPOST << "\n"
0183 << std::setw(60) << _FastSim_ENABLE << " : " << FastSim_ENABLE << "\n"
0184 ;
0185 std::string str = ss.str();
0186 return str ;
0187 }
0188
0189
0190 std::string U4Physics::Desc()
0191 {
0192 std::stringstream ss ;
0193 #ifdef DEBUG_TAG
0194 ss << ( ShimG4OpAbsorption::FLOAT ? "ShimG4OpAbsorption_FLOAT" : "ShimG4OpAbsorption_ORIGINAL" ) ;
0195 ss << "_" ;
0196 ss << ( ShimG4OpRayleigh::FLOAT ? "ShimG4OpRayleigh_FLOAT" : "ShimG4OpRayleigh_ORIGINAL" ) ;
0197 #endif
0198 std::string str = ss.str();
0199 return str ;
0200 }
0201
0202
0203
0204
0205 std::string U4Physics::Switches()
0206 {
0207 std::stringstream ss ;
0208 ss << "U4Physics::Switches" << std::endl ;
0209 #if defined(WITH_CUSTOM4)
0210 ss << "WITH_CUSTOM4" << std::endl ;
0211 #else
0212 ss << "NOT:WITH_CUSTOM4" << std::endl ;
0213 #endif
0214 #if defined(WITH_PMTSIM)
0215 ss << "WITH_PMTSIM" << std::endl ;
0216 #else
0217 ss << "NOT:WITH_PMTSIM" << std::endl ;
0218 #endif
0219 #if defined(WITH_CUSTOM4) && defined(WITH_PMTSIM)
0220 ss << "WITH_CUSTOM4_AND_WITH_PMTSIM" << std::endl ;
0221 #else
0222 ss << "NOT:WITH_CUSTOM4_AND_WITH_PMTSIM" << std::endl ;
0223 #endif
0224
0225 #if defined(WITH_CUSTOM4) && !defined(WITH_PMTSIM)
0226 ss << "WITH_CUSTOM4_AND_NOT_WITH_PMTSIM" << std::endl ;
0227 #else
0228 ss << "NOT:WITH_CUSTOM4_AND_NOT_WITH_PMTSIM" << std::endl ;
0229 #endif
0230
0231 #if defined(DEBUG_TAG)
0232 ss << "DEBUG_TAG" << std::endl ;
0233 #else
0234 ss << "NOT:DEBUG_TAG" << std::endl ;
0235 #endif
0236 std::string str = ss.str();
0237 return str ;
0238 }
0239
0240
0241
0242 int U4Physics::EInt(const char* key, const char* fallback)
0243 {
0244 const char* val_ = getenv(key) ;
0245 int val = std::atoi(val_ ? val_ : fallback) ;
0246 return val ;
0247 }
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266 void U4Physics::ConstructOp()
0267 {
0268 LOG(info) << desc() ;
0269
0270 if(Cerenkov_DISABLE == 0)
0271 {
0272 fCerenkov = new Local_G4Cerenkov_modified ;
0273 fCerenkov->SetMaxNumPhotonsPerStep(10000);
0274 fCerenkov->SetMaxBetaChangePerStep(10.0);
0275 fCerenkov->SetTrackSecondariesFirst(true);
0276 fCerenkov->SetVerboseLevel(EInt("Local_G4Cerenkov_modified_verboseLevel", "0"));
0277 }
0278
0279 if(Scintillation_DISABLE == 0)
0280 {
0281 fScintillation = new Local_DsG4Scintillation(EInt("Local_DsG4Scintillation_opticksMode","0")) ;
0282 fScintillation->SetTrackSecondariesFirst(true);
0283 }
0284
0285 if(FastSim_ENABLE == 1 )
0286 {
0287 fFastSim = new G4FastSimulationManagerProcess("fast_sim_man");
0288 }
0289
0290 if(OpAbsorption_DISABLE == 0)
0291 {
0292 #ifdef DEBUG_TAG
0293 fAbsorption = new ShimG4OpAbsorption();
0294 #else
0295 fAbsorption = new G4OpAbsorption();
0296 #endif
0297 }
0298
0299 if(OpRayleigh_DISABLE == 0)
0300 {
0301 #ifdef DEBUG_TAG
0302 fRayleigh = new ShimG4OpRayleigh();
0303 #else
0304 fRayleigh = new G4OpRayleigh();
0305 #endif
0306 }
0307
0308 if(OpBoundaryProcess_DISABLE == 0)
0309 {
0310 fBoundary = CreateBoundaryProcess();
0311 LOG(info) << " fBoundary " << fBoundary ;
0312 }
0313
0314
0315
0316 auto particleIterator=GetParticleIterator();
0317 particleIterator->reset();
0318 while( (*particleIterator)() )
0319 {
0320 G4ParticleDefinition* particle = particleIterator->value();
0321 G4ProcessManager* pmanager = particle->GetProcessManager();
0322 G4String particleName = particle->GetParticleName();
0323
0324 if ( fCerenkov && fCerenkov->IsApplicable(*particle))
0325 {
0326 pmanager->AddProcess(fCerenkov);
0327 pmanager->SetProcessOrdering(fCerenkov,idxPostStep);
0328 }
0329
0330 if ( fScintillation && fScintillation->IsApplicable(*particle) && particleName != "opticalphoton")
0331 {
0332 pmanager->AddProcess(fScintillation);
0333 pmanager->SetProcessOrderingToLast(fScintillation, idxAtRest);
0334 pmanager->SetProcessOrderingToLast(fScintillation, idxPostStep);
0335 }
0336
0337 if (particleName == "opticalphoton")
0338 {
0339 ConstructOp_opticalphoton(pmanager, particleName);
0340 }
0341 }
0342 }
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 void U4Physics::ConstructOp_opticalphoton(G4ProcessManager* pmanager, const G4String& particleName)
0358 {
0359 assert( particleName == "opticalphoton" );
0360
0361 if(fScintillation)
0362 {
0363 pmanager->AddProcess(fScintillation);
0364 pmanager->SetProcessOrderingToLast(fScintillation, idxAtRest);
0365 pmanager->SetProcessOrderingToLast(fScintillation, idxPostStep);
0366 }
0367 if(fAbsorption) pmanager->AddDiscreteProcess(fAbsorption);
0368 if(fRayleigh) pmanager->AddDiscreteProcess(fRayleigh);
0369 if(fBoundary) pmanager->AddDiscreteProcess(fBoundary);
0370 if(fFastSim) pmanager->AddDiscreteProcess(fFastSim);
0371 }
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392 G4VProcess* U4Physics::CreateBoundaryProcess()
0393 {
0394 G4VProcess* proc = nullptr ;
0395
0396 #if defined(WITH_PMTSIM) && defined(WITH_CUSTOM4)
0397 const char* path = "$PMTSimParamData_BASE" ;
0398 const PMTSimParamData* data = PMTAccessor::LoadData(path) ;
0399 LOG(LEVEL) << "load path " << path << " giving PMTSimParamData.data: " << ( data ? "YES" : "NO" ) ;
0400
0401
0402 const PMTAccessor* pmt = PMTAccessor::Create(data) ;
0403 const C4IPMTAccessor* ipmt = pmt ;
0404 proc = new C4OpBoundaryProcess(ipmt);
0405
0406 LOG(LEVEL) << "create C4OpBoundaryProcess : WITH_CUSTOM4 WITH_PMTSIM " ;
0407
0408 #elif defined(WITH_CUSTOM4)
0409 const char* jpmt = spath::Resolve("$CFBaseFromGEOM/CSGFoundry/SSim/extra/jpmt");
0410 const SPMTAccessor* pmt = SPMTAccessor::Load(jpmt) ;
0411 const char* geom = ssys::getenvvar("GEOM", "no-GEOM") ;
0412 LOG_IF(fatal, pmt == nullptr )
0413 << " FAILED TO SPMTAccessor::Load from [" << jpmt << "]"
0414 << " GEOM " << ( geom ? geom : "-" )
0415 ;
0416
0417 assert(pmt) ;
0418 const C4IPMTAccessor* ipmt = pmt ;
0419 proc = new C4OpBoundaryProcess(ipmt);
0420 LOG(LEVEL) << "create C4OpBoundaryProcess : WITH_CUSTOM4 NOT:WITH_PMTSIM " ;
0421
0422 #elif defined(WITH_INSTRUMENTED_DEBUG)
0423 proc = new InstrumentedG4OpBoundaryProcess();
0424 LOG(LEVEL) << "create InstrumentedG4OpBoundaryProcess : NOT (WITH_PMTSIM and WITH_CUSTOM4) " ;
0425 #else
0426 proc = new G4OpBoundaryProcess();
0427
0428 #endif
0429 return proc ;
0430 }
0431