File indexing completed on 2026-04-17 07:51:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #include "G4IAEAphspReader.hh"
0043
0044 #include "iaea_phsp.h"
0045 #include "iaea_record.h"
0046 #include "IAEASourceIdRegistry.hh"
0047
0048 #include <vector>
0049
0050 #include "globals.hh"
0051 #include "G4SystemOfUnits.hh"
0052 #include "G4ThreeVector.hh"
0053 #include "G4Gamma.hh"
0054 #include "G4Electron.hh"
0055 #include "G4Positron.hh"
0056 #include "G4Neutron.hh"
0057 #include "G4Proton.hh"
0058 #include "G4Event.hh"
0059 #include "G4PrimaryParticle.hh"
0060 #include "G4PrimaryVertex.hh"
0061 #include "Randomize.hh"
0062 #include "G4Threading.hh"
0063
0064 #include "G4IAEAphspReaderMessenger.hh"
0065
0066
0067
0068
0069 G4IAEAphspReader::G4IAEAphspReader(const char* filename, const G4int threads)
0070 :fVerbose(0)
0071 {
0072 fTotalThreads = threads;
0073 fFileName = filename;
0074
0075 InitializeMembers();
0076 InitializeSource(fFileName);
0077
0078 }
0079
0080
0081
0082
0083 G4IAEAphspReader::G4IAEAphspReader(const G4String filename, const G4int threads)
0084 :fVerbose(0)
0085 {
0086 fTotalThreads = threads;
0087 fFileName = filename;
0088
0089 InitializeMembers();
0090 InitializeSource(fFileName);
0091
0092 }
0093
0094
0095
0096
0097 G4IAEAphspReader::~G4IAEAphspReader()
0098 {
0099 if (fVerbose > 0) G4cout << "Destroying G4IAEAphspReader" << G4endl;
0100 delete fMessenger;
0101
0102
0103 fParticleTypeVec->clear();
0104 fKinEVec->clear();
0105 fPosVec->clear();
0106 fMomDirVec->clear();
0107 fWeightVec->clear();
0108
0109 if (fNumberOfExtraFloats > 0) {
0110 fExtraFloatVec->clear();
0111 fExtraFloatTypes->clear();
0112 }
0113
0114 if (fNumberOfExtraInts > 0) {
0115 fExtraIntVec->clear();
0116 fExtraIntTypes->clear();
0117 }
0118
0119 delete fParticleTypeVec;
0120 delete fKinEVec;
0121 delete fPosVec;
0122 delete fMomDirVec;
0123 delete fWeightVec;
0124
0125 delete fExtraFloatVec;
0126 delete fExtraIntVec;
0127
0128 delete fExtraFloatTypes;
0129 delete fExtraIntTypes;
0130
0131
0132 const IAEA_I32 sourceRead = static_cast<IAEA_I32>( fSourceReadId );
0133 IAEA_I32 result = 0;
0134
0135 if (fVerbose > 0)
0136 G4cout << "Destroying IAEA source #" << sourceRead << G4endl;
0137
0138 iaea_destroy_source(&sourceRead, &result);
0139 if (result > 0) {
0140 IAEASourceIdRegistry::Instance().Release(fSourceReadId);
0141 G4cout << "File " << fFileName << ".IAEAphsp closed successfully!"
0142 << G4endl;
0143 }
0144 else {
0145 G4Exception("G4IAEAphspReader::~G4IAEAphspReader()",
0146 "IAEAphspReader001", JustWarning,
0147 "IAEA file not closed properly");
0148 }
0149
0150 if (fVerbose > 0) G4cout << "G4IAEAphspReader destroyed" << G4endl;
0151 }
0152
0153
0154
0155
0156 void G4IAEAphspReader::InitializeMembers()
0157 {
0158 G4ThreeVector zeroVec;
0159 G4ThreeVector yAxis(0.0, 1.0, 0.0);
0160 G4ThreeVector zAxis(0.0, 0.0, 1.0);
0161
0162 particle_time = 0.0;
0163 particle_position = zeroVec;
0164
0165 if ( G4Threading::IsMultithreadedApplication() )
0166 fSourceReadId = G4Threading::G4GetThreadId();
0167 else
0168 fSourceReadId = 0;
0169
0170 fOrigHistories = -1;
0171 fTotalParticles = -1;
0172 fExtraFloatTypes = new std::vector<G4int>;
0173 fExtraIntTypes = new std::vector<G4int>;
0174
0175 fParticleTypeVec = new std::vector<G4int>;
0176 fKinEVec = new std::vector<G4double>;
0177 fPosVec = new std::vector<G4ThreeVector>;
0178 fMomDirVec = new std::vector<G4ThreeVector>;
0179 fWeightVec = new std::vector<G4double>;
0180 fExtraFloatVec = new std::vector< std::vector<G4double> >;
0181 fExtraIntVec = new std::vector< std::vector<G4long> >;
0182
0183 fTotalParallelRuns = 1;
0184 fParallelRun = 1;
0185 fTimesRecycled = 0;
0186 fUsedOrigHistories = 0;
0187 fCurrentParticle = 0;
0188 fEndOfFile = false;
0189 fLastGenerated = true;
0190
0191 fGlobalPhspTranslation = zeroVec;
0192 fRotationOrder = 123;
0193 fAlpha = fBeta = fGamma = 0.;
0194 fIsocenterPosition = zeroVec;
0195 fCollimatorAngle = fGantryAngle = 0.;
0196 fCollimatorRotAxis = zAxis;
0197 fGantryRotAxis = yAxis;
0198
0199 fAxialSymmetryX = false;
0200 fAxialSymmetryY = false;
0201 fAxialSymmetryZ = false;
0202
0203
0204 fMessenger = new G4IAEAphspReaderMessenger(this);
0205 }
0206
0207
0208
0209
0210 void G4IAEAphspReader::InitializeSource(const G4String filename)
0211 {
0212
0213 G4int reserved = IAEASourceIdRegistry::Instance().ReserveNextLowest();
0214 if (reserved < 0) {
0215 G4ExceptionDescription ed;
0216 ed << "No free IAEA source_ID's available" << G4endl;
0217 G4Exception("G4IAEAphspReader::InitializeSource",
0218 "IAEAphspReader002",FatalException, ed);
0219 }
0220 IAEA_I32 sourceRead = static_cast<IAEA_I32>(reserved);
0221
0222
0223 const IAEA_I32 accessRead = 1;
0224 IAEA_I32 result = 0;
0225
0226 iaea_new_source(&sourceRead, const_cast<char*>(filename.data()),
0227 &accessRead, &result, filename.size()+1);
0228 if ( sourceRead < 0 || result < 0 ) {
0229 IAEASourceIdRegistry::Instance().Release(reserved);
0230 G4ExceptionDescription msg;
0231 msg << "Could not open IAEA source file to read" << G4endl;
0232 G4Exception("G4IAEAphspReader::InitializeSource()",
0233 "IAEAphspReader003", FatalException, msg);
0234 }
0235
0236
0237 fSourceReadId = static_cast<G4int>(sourceRead);
0238
0239
0240
0241 G4cout << "G4IAEAphspReader ==> This object has IAEA source ID = "
0242 << fSourceReadId << "." << G4endl;
0243
0244
0245 iaea_check_file_size_byte_order(&sourceRead, &result);
0246 if (result < 0 )
0247 G4Exception("G4IAEAphspReader::InitializeSource()",
0248 "IAEAphspReader004", FatalException,
0249 "Failure at iaea_check_size_byte_order()");
0250
0251
0252
0253
0254 IAEA_I32 particleType = -1;
0255 IAEA_I64 nParticles;
0256 iaea_get_max_particles(&sourceRead, &particleType, &nParticles);
0257
0258 if (nParticles < 0) {
0259 G4Exception("G4IAEAphspReader::InitializeSource()",
0260 "IAEAphspReader005", FatalException,
0261 "Failure at iaea_get_max_particles()");
0262 }
0263 else {
0264 fTotalParticles = static_cast<G4long>(nParticles);
0265 G4cout << "Total number of particles in file \"" << filename
0266 << ".IAEAphsp\"" << " = " << GetTotalParticles() << G4endl;
0267 }
0268
0269
0270
0271
0272 IAEA_I64 nHistories;
0273 iaea_get_total_original_particles(&sourceRead, &nHistories);
0274 fOrigHistories = static_cast<G4long>(nHistories);
0275
0276 G4cout << "Number of original histories in header file \""
0277 << filename << ".IAEAphsp\"" << " = " << nHistories << G4endl;
0278
0279
0280
0281
0282 IAEA_I32 nExtraFloat, nExtraInt;
0283 iaea_get_extra_numbers(&sourceRead, &nExtraFloat, &nExtraInt );
0284 fNumberOfExtraFloats = static_cast<G4int>( nExtraFloat );
0285 fNumberOfExtraInts = static_cast<G4int>( nExtraInt );
0286
0287 G4cout << "The number of Extra Floats is " << fNumberOfExtraFloats
0288 << " and the number of Extra Ints is " << fNumberOfExtraInts
0289 << G4endl;
0290
0291
0292
0293 IAEA_I32 extraFloatTypes[NUM_EXTRA_FLOAT], extraIntTypes[NUM_EXTRA_LONG];
0294 iaea_get_type_extra_variables(&sourceRead, &result,
0295 extraIntTypes, extraFloatTypes);
0296
0297 if (fNumberOfExtraFloats > 0) {
0298 fExtraFloatTypes->reserve( fNumberOfExtraFloats );
0299 for (G4int jj = 0; jj < fNumberOfExtraFloats; jj++)
0300 fExtraFloatTypes->push_back( static_cast<G4int>(extraFloatTypes[jj]) );
0301 }
0302
0303 if (fNumberOfExtraInts > 0) {
0304 fExtraIntTypes->reserve( fNumberOfExtraInts );
0305 for (G4int ii = 0; ii < fNumberOfExtraInts; ii++)
0306 fExtraIntTypes->push_back( static_cast<G4int>(extraIntTypes[ii]) );
0307 }
0308 }
0309
0310
0311
0312
0313
0314
0315 void G4IAEAphspReader::GeneratePrimaryVertex(G4Event* evt)
0316 {
0317 if (fLastGenerated) {
0318 RestartSourceFile();
0319 ReadAndStoreFirstParticle();
0320 }
0321
0322 PrepareThisEvent();
0323
0324 if (fNStat == 0) {
0325 ReadThisEvent();
0326 GeneratePrimaryParticles(evt);
0327 }
0328 }
0329
0330
0331
0332
0333 void G4IAEAphspReader::RestartSourceFile()
0334 {
0335
0336 fCurrentParticle = 0;
0337 fEndOfFile = false;
0338 fLastGenerated = false;
0339
0340
0341 fParticleTypeVec->clear();
0342 fKinEVec->clear();
0343 fPosVec->clear();
0344 fMomDirVec->clear();
0345 fWeightVec->clear();
0346 if (fNumberOfExtraFloats) fExtraFloatVec->clear();
0347 if (fNumberOfExtraInts) fExtraIntVec->clear();
0348
0349
0350 IAEA_I32 sourceRead = static_cast<IAEA_I32>(fSourceReadId);
0351 const IAEA_I32 accessRead = 1;
0352 IAEA_I32 result = 0;
0353
0354 G4cout << "G4IAEAphspReader ==> Closing IAEA source ID = " << fSourceReadId
0355 << " to re-open it and reset fOriginalHistoriesUsed"
0356 << G4endl;
0357 iaea_destroy_source(&sourceRead, &result);
0358
0359 iaea_new_source(&sourceRead, const_cast<char*>( fFileName.data() ),
0360 &accessRead, &result, fFileName.size()+1 );
0361 if ( sourceRead < 0 || result < 0 )
0362 G4Exception("G4IAEAphspReader::RestartSourceFile()",
0363 "IAEAphspReader006", FatalException,
0364 "Could not open IAEA source file to read");
0365
0366
0367 fSourceReadId = static_cast<G4int>(sourceRead);
0368 G4cout << "G4IAEAphspReader ==> IAEA source re-started with ID = "
0369 << fSourceReadId << "." << G4endl;
0370
0371 iaea_check_file_size_byte_order(&sourceRead, &result);
0372
0373 if (result < 0 )
0374 G4Exception("G4IAEAphspReader::RestartSourceFile()",
0375 "IAEAphspReader007", FatalException,
0376 "Failure at iaea_check_size_byte_order()");
0377 }
0378
0379
0380
0381
0382
0383 void G4IAEAphspReader::ReadAndStoreFirstParticle()
0384 {
0385
0386 IAEA_I32 type, nStat;
0387 IAEA_Float E, wt, x, y, z, u, v, w;
0388 IAEA_Float extraFloats[NUM_EXTRA_FLOAT];
0389 IAEA_I32 extraInts[NUM_EXTRA_LONG];
0390
0391 IAEA_I32 sourceRead = static_cast<IAEA_I32>(fSourceReadId);
0392
0393
0394
0395
0396
0397
0398 if (fParallelRun == 1)
0399 ComputeFirstLastParticle();
0400
0401
0402
0403
0404 IAEA_I32 chunk = static_cast<IAEA_I32>((fParallelRun-1)*fTotalThreads);
0405
0406 if ( G4Threading::IsMultithreadedApplication() )
0407 chunk += static_cast<IAEA_I32>(G4Threading::G4GetThreadId()+1);
0408 else
0409 chunk += 1;
0410
0411
0412
0413
0414
0415 IAEA_I32 totalChunks =
0416 static_cast<IAEA_I32>(fTotalParallelRuns*fTotalThreads);
0417
0418
0419 IAEA_I32 result;
0420 iaea_set_parallel(&sourceRead, 0, &chunk, &totalChunks, &result);
0421
0422
0423
0424 if (result < 0) {
0425 G4ExceptionDescription ed;
0426 ed << "ERROR placing the cursor within the phsp file [iaea_set_parallel()]"
0427 << G4endl;
0428 G4Exception("G4IAEAphspReader::ReadAndStoreFirstParticle()",
0429 "IAEAphspReader008", FatalException, ed);
0430 }
0431
0432 fCurrentParticle = fFirstParticle;
0433
0434
0435
0436
0437
0438
0439 fCurrentParticle++;
0440 iaea_get_particle(&sourceRead, &nStat, &type,
0441 &E, &wt, &x, &y, &z, &u, &v, &w, extraFloats, extraInts);
0442
0443
0444
0445 if (fVerbose > 1) {
0446 G4cout << std::setprecision(6) << G4endl
0447 << "G4IAEAphspReader: Reading particle # "
0448 << fCurrentParticle << " type= " << type
0449 << " n_stat= " << nStat
0450 << G4endl
0451 << "\t\t E= " << E << " wt= " << wt
0452 << G4endl
0453 << "\t\t x= " << x << " y= " << y << " z= " << z
0454 << " u= " << u << " v= " << v << " w= " << w
0455 << G4endl;
0456 }
0457
0458 if (nStat == -1)
0459 G4Exception("G4IAEAphspReader::ReadAndStoreFirstParticle()",
0460 "IAEAphspReader009", FatalException,
0461 "Cannot find source file");
0462 else if (nStat == 0)
0463 fNStat = 1;
0464 else
0465 fNStat = nStat;
0466
0467
0468
0469
0470
0471
0472 fParticleTypeVec->push_back(static_cast<G4int>(type) );
0473 fKinEVec->push_back(static_cast<G4double>(E));
0474
0475 G4ThreeVector pos, momDir;
0476 pos.set(static_cast<G4double>(x),
0477 static_cast<G4double>(y),
0478 static_cast<G4double>(z));
0479
0480 momDir.set(static_cast<G4double>(u),
0481 static_cast<G4double>(v),
0482 static_cast<G4double>(w));
0483
0484 fPosVec->push_back(pos);
0485 fMomDirVec->push_back(momDir);
0486
0487 fWeightVec->push_back(static_cast<G4double>(wt));
0488
0489 if (fNumberOfExtraFloats > 0) {
0490 std::vector<G4double> vExtraFloats;
0491 vExtraFloats.reserve(fNumberOfExtraFloats);
0492 for (G4int jj = 0; jj < fNumberOfExtraFloats; jj++)
0493 vExtraFloats.push_back( static_cast<G4double>(extraFloats[jj]) );
0494
0495 fExtraFloatVec->push_back(vExtraFloats);
0496 }
0497
0498 if (fNumberOfExtraInts > 0) {
0499 std::vector<G4long> vExtraInts;
0500 vExtraInts.reserve(fNumberOfExtraInts);
0501 for (G4int ii = 0; ii < fNumberOfExtraInts; ii++)
0502 vExtraInts.push_back( static_cast<G4long>(extraInts[ii]) );
0503
0504 fExtraIntVec->push_back(vExtraInts);
0505 }
0506
0507
0508
0509
0510 IAEA_I64 nUsedOriginal;
0511 iaea_get_used_original_particles(&sourceRead, &nUsedOriginal);
0512 fUsedOrigHistories = static_cast<G4long>(nUsedOriginal);
0513 if (fVerbose > 0)
0514 G4cout << "G4IAEAphspReader::fUsedOrigHistories = "
0515 << fUsedOrigHistories << " from IAEAphsp source #" << sourceRead
0516 << G4endl;
0517
0518
0519
0520
0521
0522 if (fCurrentParticle == fLastParticle)
0523 fEndOfFile = true;
0524 }
0525
0526
0527
0528
0529 void G4IAEAphspReader::PrepareThisEvent()
0530 {
0531 fNStat--;
0532
0533
0534
0535
0536
0537 G4int listSizes = fParticleTypeVec->size();
0538
0539 if (listSizes > 1) {
0540 fParticleTypeVec->erase(fParticleTypeVec->begin(),
0541 fParticleTypeVec->end()-1);
0542 fKinEVec->erase(fKinEVec->begin(), fKinEVec->end()-1);
0543 fPosVec->erase(fPosVec->begin(), fPosVec->end()-1);
0544 fMomDirVec->erase(fMomDirVec->begin(), fMomDirVec->end()-1);
0545 fWeightVec->erase(fWeightVec->begin(), fWeightVec->end()-1);
0546
0547 if (fNumberOfExtraFloats > 0)
0548 fExtraFloatVec->erase(fExtraFloatVec->begin(), fExtraFloatVec->end()-1);
0549
0550 if (fNumberOfExtraInts > 0)
0551 fExtraIntVec->erase(fExtraIntVec->begin(), fExtraIntVec->end()-1);
0552 }
0553 }
0554
0555
0556
0557
0558 void G4IAEAphspReader::ReadThisEvent()
0559 {
0560
0561 IAEA_I32 type, nStat;
0562 IAEA_Float E, wt, x, y, z, u, v, w;
0563 IAEA_I32 extraInts[NUM_EXTRA_LONG];
0564 IAEA_Float extraFloats[NUM_EXTRA_FLOAT];
0565
0566 IAEA_I32 sourceRead = static_cast<IAEA_I32>(fSourceReadId);
0567
0568
0569
0570
0571
0572 while (fNStat == 0 && !fEndOfFile) {
0573
0574
0575
0576 fCurrentParticle++;
0577 iaea_get_particle(&sourceRead, &nStat, &type, &E, &wt,
0578 &x, &y, &z, &u, &v, &w, extraFloats, extraInts);
0579 if (fVerbose > 1)
0580 G4cout << std::setprecision(6) << G4endl
0581 << "G4IAEAphspReader: Reading particle # "
0582 << fCurrentParticle << " type= " << type
0583 << " n_stat= " << nStat
0584 << G4endl
0585 << "\t\t E= " << E << " wt= " << wt
0586 << G4endl
0587 << "\t\t x= " << x << " y= " << y << " z= " << z
0588 << " u= " << u << " v= " << v << " w= " << w
0589 << G4endl;
0590
0591 if (nStat == -1)
0592 G4Exception("G4IAEAphspReader::ReadThisEvent()",
0593 "IAEAphspReader010", FatalException,
0594 "Cannot find source file");
0595 else
0596 fNStat += nStat;
0597
0598
0599
0600
0601
0602 fParticleTypeVec->push_back(static_cast<G4int>(type) );
0603 fKinEVec->push_back(static_cast<G4double>(E));
0604
0605 G4ThreeVector pos, momDir;
0606 pos.set(static_cast<G4double>(x),
0607 static_cast<G4double>(y),
0608 static_cast<G4double>(z));
0609
0610 momDir.set(static_cast<G4double>(u),
0611 static_cast<G4double>(v),
0612 static_cast<G4double>(w));
0613
0614 fPosVec->push_back(pos);
0615 fMomDirVec->push_back(momDir);
0616
0617 fWeightVec->push_back(static_cast<G4double>(wt));
0618
0619 if (fNumberOfExtraFloats > 0) {
0620 std::vector<G4double> vExtraFloats;
0621 vExtraFloats.reserve(fNumberOfExtraFloats);
0622 for (G4int jj = 0; jj < fNumberOfExtraFloats; jj++)
0623 vExtraFloats.push_back( static_cast<G4double>(extraFloats[jj]) );
0624
0625 fExtraFloatVec->push_back(vExtraFloats);
0626 }
0627
0628 if (fNumberOfExtraInts > 0) {
0629 std::vector<G4long> vExtraInts;
0630 vExtraInts.reserve(fNumberOfExtraInts);
0631 for (G4int ii = 0; ii < fNumberOfExtraInts; ii++)
0632 vExtraInts.push_back( static_cast<G4long>(extraInts[ii]) );
0633
0634 fExtraIntVec->push_back(vExtraInts);
0635 }
0636
0637
0638
0639
0640 IAEA_I64 nUsedOriginal;
0641 iaea_get_used_original_particles(&sourceRead, &nUsedOriginal);
0642 fUsedOrigHistories = static_cast<G4long>(nUsedOriginal);
0643 if (fVerbose > 0)
0644 G4cout << "G4IAEAphspReader::fUsedOrigHistories = "
0645 << fUsedOrigHistories << " from IAEAphsp source #" << sourceRead
0646 << G4endl;
0647
0648
0649
0650 if (fCurrentParticle == fLastParticle)
0651 fEndOfFile = true;
0652 }
0653 }
0654
0655
0656
0657
0658 void G4IAEAphspReader::GeneratePrimaryParticles(G4Event* evt)
0659 {
0660
0661
0662
0663
0664
0665
0666 G4int listSize = fParticleTypeVec->size();
0667
0668 if (fEndOfFile && fNStat == 0) {
0669
0670 fLastGenerated = true;
0671
0672
0673 G4cout << "WARNING: Last particle to read from IAEAphsp reached at event "
0674 << evt->GetEventID() << "."
0675 << G4endl;
0676 }
0677 else {
0678
0679 listSize--;
0680 }
0681
0682
0683
0684
0685
0686
0687
0688
0689 std::vector<G4double> randomRotations;
0690
0691 if (fAxialSymmetryZ || fAxialSymmetryX || fAxialSymmetryY) {
0692 randomRotations.reserve(fTimesRecycled+1);
0693 for (G4int ii = 0; ii <= fTimesRecycled; ii++) {
0694 G4double randomAngle = G4UniformRand();
0695 randomAngle *= (360.*deg);
0696 randomRotations.push_back(randomAngle);
0697 }
0698 }
0699
0700
0701
0702
0703 for (G4int ii = 0; ii < listSize; ii++) {
0704
0705
0706
0707
0708 G4ParticleDefinition * partDef = 0;
0709 switch((*fParticleTypeVec)[ii]) {
0710 case 1:
0711 partDef = G4Gamma::Definition();
0712 break;
0713 case 2:
0714 partDef = G4Electron::Definition();
0715 break;
0716 case 3:
0717 partDef = G4Positron::Definition();
0718 break;
0719 case 4:
0720 partDef = G4Neutron::Definition();
0721 break;
0722 case 5:
0723 partDef = G4Proton::Definition();
0724 break;
0725 default:
0726 G4ExceptionDescription ED;
0727 ED << "Particle code read at event #" << evt->GetEventID()
0728 << "is" << (*fParticleTypeVec)[ii]
0729 << " - this is not supported by the IAEAphsp format." << G4endl;
0730 G4Exception("G4IAEAphspReader::GeneratePrimaryParticles()",
0731 "IAEAphspReader011", EventMustBeAborted, ED);
0732 return;
0733 }
0734
0735
0736
0737
0738 particle_position = (*fPosVec)[ii];
0739 particle_position *= cm;
0740
0741 G4double partMass = partDef->GetPDGMass();
0742 G4double partTotE = static_cast<G4double>((*fKinEVec)[ii])*MeV + partMass;
0743 G4double partMom = std::sqrt( partTotE*partTotE - partMass*partMass );
0744
0745 G4ThreeVector partMomVec;
0746 partMomVec = (*fMomDirVec)[ii];
0747 partMomVec *= partMom;
0748
0749
0750
0751
0752
0753 particle_position += fGlobalPhspTranslation;
0754 PerformRotations(partMomVec);
0755
0756
0757
0758
0759
0760
0761 for (G4int jj = 0; jj <= fTimesRecycled; jj++) {
0762
0763 if (fAxialSymmetryZ) {
0764 particle_position.rotateZ(randomRotations[jj]);
0765 partMomVec.rotateZ(randomRotations[jj]);
0766 }
0767 else if (fAxialSymmetryX) {
0768 particle_position.rotateX(randomRotations[jj]);
0769 partMomVec.rotateX(randomRotations[jj]);
0770 }
0771 else if (fAxialSymmetryY) {
0772 particle_position.rotateY(randomRotations[jj]);
0773 partMomVec.rotateY(randomRotations[jj]);
0774 }
0775
0776
0777 G4PrimaryParticle * particle =
0778 new G4PrimaryParticle(partDef,
0779 partMomVec.x(),partMomVec.y(),partMomVec.z());
0780
0781 particle->SetWeight( ((*fWeightVec)[ii])/(fTimesRecycled+1) );
0782
0783
0784 G4PrimaryVertex * vertex =
0785 new G4PrimaryVertex(particle_position, particle_time);
0786 vertex->SetPrimary(particle);
0787
0788 if (fVerbose > 1)
0789 G4cout << std::setprecision(6) << G4endl
0790 << "G4IAEAphspReader ==> Vertex produced: "
0791 << " Event # " << evt->GetEventID()
0792 << " ParticleName: " << partDef->GetParticleName()
0793 << G4endl
0794 << "\t\t kinEnergy[MeV]= " << particle->GetKineticEnergy()/MeV
0795 << " weight= " << particle->GetWeight()
0796 << G4endl
0797 << "\t\t x[cm]= " << vertex->GetX0()/cm
0798 << " y[cm]= " << vertex->GetY0()/cm
0799 << " z[cm]= " << vertex->GetZ0()/cm
0800 << " u= " << particle->GetMomentumDirection().x()
0801 << " v= " << particle->GetMomentumDirection().y()
0802 << " w= " << particle->GetMomentumDirection().z()
0803 << G4endl;
0804
0805
0806 evt->AddPrimaryVertex(vertex);
0807 }
0808 }
0809 }
0810
0811
0812
0813
0814 void G4IAEAphspReader::PerformRotations(G4ThreeVector & mom)
0815 {
0816 PerformGlobalRotations(mom);
0817 PerformHeadRotations(mom);
0818 }
0819
0820
0821
0822
0823 void G4IAEAphspReader::PerformGlobalRotations(G4ThreeVector & momentum)
0824 {
0825 switch (fRotationOrder) {
0826 case 123:
0827 particle_position.rotateX(fAlpha);
0828 particle_position.rotateY(fBeta);
0829 particle_position.rotateZ(fGamma);
0830 momentum.rotateX(fAlpha);
0831 momentum.rotateY(fBeta);
0832 momentum.rotateZ(fGamma);
0833 break;
0834
0835 case 132:
0836 particle_position.rotateX(fAlpha);
0837 particle_position.rotateZ(fGamma);
0838 particle_position.rotateY(fBeta);
0839 momentum.rotateX(fAlpha);
0840 momentum.rotateZ(fGamma);
0841 momentum.rotateY(fBeta);
0842 break;
0843
0844 case 213:
0845 particle_position.rotateY(fBeta);
0846 particle_position.rotateX(fAlpha);
0847 particle_position.rotateZ(fGamma);
0848 momentum.rotateY(fBeta);
0849 momentum.rotateX(fAlpha);
0850 momentum.rotateZ(fGamma);
0851 break;
0852
0853 case 231:
0854 particle_position.rotateY(fBeta);
0855 particle_position.rotateZ(fGamma);
0856 particle_position.rotateX(fAlpha);
0857 momentum.rotateY(fBeta);
0858 momentum.rotateZ(fGamma);
0859 momentum.rotateX(fAlpha);
0860 break;
0861
0862 case 312:
0863 particle_position.rotateZ(fGamma);
0864 particle_position.rotateX(fAlpha);
0865 particle_position.rotateY(fBeta);
0866 momentum.rotateZ(fGamma);
0867 momentum.rotateX(fAlpha);
0868 momentum.rotateY(fBeta);
0869 break;
0870
0871 case 321:
0872 particle_position.rotateZ(fGamma);
0873 particle_position.rotateY(fBeta);
0874 particle_position.rotateX(fAlpha);
0875 momentum.rotateZ(fGamma);
0876 momentum.rotateY(fBeta);
0877 momentum.rotateX(fAlpha);
0878 break;
0879
0880 default:
0881 G4ExceptionDescription ED;
0882 ED << "Invalid combination in G4IAEAphspReader::fRotationOrder -> "
0883 << "NO global rotations are done." << G4endl;
0884 G4Exception("G4IAEAphspReader::PerformGlobalRotations()",
0885 "IAEAphspReader012", FatalErrorInArgument, ED);
0886 }
0887 }
0888
0889
0890
0891
0892 void G4IAEAphspReader::PerformHeadRotations(G4ThreeVector & momentum)
0893 {
0894
0895 particle_position -= fIsocenterPosition;
0896
0897
0898
0899
0900 particle_position.rotate(fCollimatorRotAxis, fCollimatorAngle);
0901 momentum.rotate(fCollimatorRotAxis, fCollimatorAngle);
0902
0903
0904 particle_position.rotate(fGantryRotAxis, fGantryAngle);
0905 momentum.rotate(fGantryRotAxis, fGantryAngle);
0906
0907
0908 particle_position += fIsocenterPosition;
0909 }
0910
0911
0912
0913
0914
0915 void G4IAEAphspReader::SetParallelRun(const G4int parallelRun)
0916 {
0917 if (parallelRun > fTotalParallelRuns || parallelRun < 1) {
0918 G4ExceptionDescription ED;
0919 ED << "SetParallelRun argument must be an integer between 1 "
0920 << "and fTotalParallelRuns" << G4endl;
0921 G4Exception("G4IAEAphspReader::SetParallelRun()",
0922 "IAEAphspReader013", FatalErrorInArgument, ED);
0923 }
0924 fParallelRun = parallelRun;
0925
0926 if (fVerbose > 0)
0927 G4cout << "G4IAEAphspReader::fParallelRun = " << fParallelRun
0928 << G4endl;
0929
0930 ComputeFirstLastParticle();
0931 }
0932
0933
0934
0935
0936 void G4IAEAphspReader::ComputeFirstLastParticle()
0937 {
0938
0939
0940
0941
0942
0943 G4cout << "G4IAEAphspReader: Defined " << fTotalParallelRuns
0944 << " chunks in the file"
0945 << " (i.e. number of independent simulations in parallel)" << G4endl;
0946
0947 G4cout << "G4IAEAphspReader ==> This run is using the chunk #"
0948 << fParallelRun << " of the " << fTotalParallelRuns
0949 << " defined in the phsp file." << G4endl;
0950
0951
0952
0953
0954
0955
0956
0957 IAEA_I64 particlesChunk = fTotalParticles/(fTotalParallelRuns*fTotalThreads);
0958 IAEA_I64 firstParticle = particlesChunk*(fParallelRun-1)*fTotalThreads;
0959
0960 if ( G4Threading::IsMultithreadedApplication() ) {
0961 IAEA_I32 threadID = static_cast<IAEA_I32>(G4Threading::G4GetThreadId());
0962 firstParticle += particlesChunk*threadID;
0963 }
0964
0965 IAEA_I64 lastParticle = firstParticle + particlesChunk;
0966
0967 fFirstParticle = static_cast<G4long>(firstParticle);
0968 fLastParticle = static_cast<G4long>(lastParticle);
0969
0970
0971 if (fLastParticle > fTotalParticles)
0972 fLastParticle = fTotalParticles;
0973
0974
0975 G4cout << "G4IAEAphspReader: "
0976 << "This thread is reading the particles from place #"
0977 << fFirstParticle+1 << " to #" << fLastParticle
0978 << " within the phsp file" << G4endl;
0979 }
0980
0981
0982
0983
0984 void G4IAEAphspReader::SetCollimatorRotationAxis(const G4ThreeVector & axis)
0985 {
0986 G4double mod = axis.mag();
0987 if (mod > 0) {
0988
0989 G4double scale = 1.0/mod;
0990 G4double ux = scale*axis.getX();
0991 G4double uy = scale*axis.getY();
0992 G4double uz = scale*axis.getZ();
0993 fCollimatorRotAxis.setX(ux);
0994 fCollimatorRotAxis.setY(uy);
0995 fCollimatorRotAxis.setZ(uz);
0996 }
0997 else {
0998 G4ExceptionDescription ED;
0999 ED << "Trying to set as CollimatorRotationAxis a null vector, "
1000 << "thus the previous value will remain." << G4endl;
1001 G4Exception("G4IAEAphspReader::SetCollimatorRotationAxis()",
1002 "IAEAphspReader014", JustWarning, ED);
1003 }
1004 }
1005
1006
1007
1008
1009 void G4IAEAphspReader::SetGantryRotationAxis(const G4ThreeVector & axis)
1010 {
1011 G4double mod = axis.mag();
1012 if ( mod > 0 ) {
1013
1014 G4double scale = 1.0/mod;
1015 G4double ux = scale*axis.getX();
1016 G4double uy = scale*axis.getY();
1017 G4double uz = scale*axis.getZ();
1018 fGantryRotAxis.setX(ux);
1019 fGantryRotAxis.setY(uy);
1020 fGantryRotAxis.setZ(uz);
1021 }
1022 else {
1023 G4ExceptionDescription ED;
1024 ED << "Trying to set as GantryRotationAxis a null vector, "
1025 << "thus the previous value will remain." << G4endl;
1026 G4Exception("G4IAEAphspReader::SetGantryRotationAxis()",
1027 "IAEAphspReader015", JustWarning, ED);
1028 }
1029 }
1030
1031
1032
1033
1034 G4long G4IAEAphspReader::GetTotalParticlesOfType(const G4String type) const
1035 {
1036 IAEA_I32 particleType;
1037
1038 if (type == "ALL") particleType = -1;
1039 else if (type == "PHOTON") particleType = 1;
1040 else if (type == "ELECTRON") particleType = 2;
1041 else if (type == "POSITRON") particleType = 3;
1042 else if (type == "NEUTRON") particleType = 4;
1043 else if (type == "PROTON") particleType = 5;
1044 else particleType = 0;
1045
1046 if (particleType == 0) {
1047 G4ExceptionDescription ED;
1048 ED << "Particle type \"" << type << "\" is not valid."
1049 << " (Please do ensure that all characters are uppercase)"
1050 << G4endl;
1051 G4Exception("G4IAEAphspReader::GetTotalParticlesOfType()",
1052 "IAEAphspReader016", JustWarning, ED);
1053 return -1;
1054 }
1055
1056 IAEA_I64 nParticles;
1057 const IAEA_I32 sourceRead = static_cast<IAEA_I32>( fSourceReadId );
1058 iaea_get_max_particles(&sourceRead, &particleType, &nParticles);
1059
1060 if (nParticles < 0)
1061 G4Exception("G4IAEAphspReader::GetTotalParticlesOfType()",
1062 "IAEAphspReader017", JustWarning,
1063 "IAEA header file not found");
1064 else
1065 G4cout << "G4IAEAphspReader: "
1066 << "Total number of " << type << " in filename "
1067 << fFileName << ".IAEAphsp" << " = " << nParticles << G4endl;
1068
1069 return ( static_cast<G4long>(nParticles) );
1070 }
1071
1072
1073
1074
1075 G4double G4IAEAphspReader::GetConstantVariable(const G4int index) const
1076 {
1077 const IAEA_I32 sourceRead = static_cast<IAEA_I32>( fSourceReadId );
1078 const IAEA_I32 idx = static_cast<IAEA_I32>( index );
1079 IAEA_Float constVariable;
1080 IAEA_I32 result;
1081
1082 iaea_get_constant_variable(&sourceRead, &idx, &constVariable, &result);
1083
1084 if (result == -1)
1085 G4Exception("G4IAEAphspReader::GetConstantVariable()",
1086 "IAEAphspReader018", JustWarning,
1087 "IAEA header file source not found");
1088 else if (result == -2)
1089 G4Exception("G4IAEAphspReader::GetConstantVariable()",
1090 "IAEAphspReader019", JustWarning,
1091 "index out of range");
1092 else if (result == -3)
1093 G4Exception("G4IAEAphspReader::GetConstantVariable()",
1094 "IAEAphspReader020", JustWarning,
1095 "parameter indicated by 'index' is not a constant");
1096
1097 return ( static_cast<G4double>(constVariable) );
1098 }