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 #include "G4IAEAphspWriter.hh"
0038
0039 #include "globals.hh"
0040 #include "G4SystemOfUnits.hh"
0041 #include "G4Run.hh"
0042 #include "G4Step.hh"
0043 #include "G4Track.hh"
0044
0045 #include "iaea_phsp.h"
0046 #include "IAEASourceIdRegistry.hh"
0047 #include "G4IAEAphspWriterStack.hh"
0048
0049 #include <map>
0050 #include <sstream>
0051 #include <vector>
0052
0053
0054
0055 G4IAEAphspWriter::G4IAEAphspWriter(const G4String filename)
0056 {
0057 fFileName = filename;
0058 fZphspVec = new std::vector<G4double>;
0059 fConstVariables = new std::map<G4int, G4double>;
0060 fOrigHistories = new std::vector<G4int>;
0061 fIAEASourcesOpen = 0;
0062 G4cout << "G4IAEAphspWriter object constructed." << G4endl;
0063 }
0064
0065
0066 G4IAEAphspWriter::~G4IAEAphspWriter()
0067 {
0068 if (fZphspVec) delete fZphspVec;
0069 if (fConstVariables) delete fConstVariables;
0070 if (fOrigHistories) delete fOrigHistories;
0071 }
0072
0073
0074
0075
0076 void G4IAEAphspWriter::AddZphsp(const G4double zphsp)
0077 {
0078 fZphspVec->push_back(zphsp);
0079 G4cout << "G4IAEAphspWriter: Registered phase-space plane at z = "
0080 << zphsp/cm << " cm." << G4endl;
0081
0082
0083 fOrigHistories->push_back(0);
0084 }
0085
0086
0087
0088
0089 void G4IAEAphspWriter::SetDataFromIAEAStack(const G4IAEAphspWriterStack* stack)
0090 {
0091 if (!stack) {
0092 G4ExceptionDescription msg;
0093 msg << "No G4IAEAphspWriterStack has been constructed!" << G4endl;
0094 G4Exception("G4IAEAphspWriter::SetDataFromIAEAStack()",
0095 "IAEAphspWriter001", FatalException, msg );
0096 return;
0097 }
0098 else {
0099 fFileName = stack->GetFileName();
0100
0101 if (stack->GetZphspVec()->size() > 0) {
0102 (*fZphspVec) = *(stack->GetZphspVec());
0103
0104 G4cout << "G4IAEAphspWriter::fFileName = " << fFileName << G4endl;
0105 G4cout << "G4IAEAphspWriter::fZphspVec->size() = "
0106 << fZphspVec->size() << G4endl;
0107
0108
0109 fOrigHistories->assign(fZphspVec->size(), 0);
0110 }
0111 else {
0112 G4ExceptionDescription msg;
0113 msg << "No phsp plane z-coordinate has been defined!" << G4endl;
0114 G4Exception("G4IAEAphspWriter::SetDataFromIAEAStack()",
0115 "IAEAphspWriter002", FatalErrorInArgument, msg );
0116 return;
0117 }
0118 }
0119 }
0120
0121
0122
0123
0124 void G4IAEAphspWriter::SetConstVariable(const G4int idx, const G4double val)
0125 {
0126 if (idx < 0 || idx > 6) {
0127 G4cout << "No constant variable applies for index " << idx
0128 << ". Doing nothing." << G4endl;
0129 return;
0130 }
0131
0132 fConstVariables->insert( std::pair<G4int, G4double>(idx, val) );
0133 switch (idx) {
0134 case 0:
0135 G4cout << "Variable 'x' set to constant value " << val << " cm" << G4endl;
0136 break;
0137 case 1:
0138 G4cout << "Variable 'y' set to constant value " << val << " cm" << G4endl;
0139 break;
0140 case 2:
0141 G4cout << "Variable 'z' set to constant value " << val << " cm" << G4endl;
0142 break;
0143 case 3:
0144 G4cout << "Variable 'u' set to constant value " << val << G4endl;
0145 break;
0146 case 4:
0147 G4cout << "Variable 'v' set to constant value " << val << G4endl;
0148 break;
0149 case 5:
0150 G4cout << "Variable 'w' set to constant value " << val << G4endl;
0151 break;
0152 case 6:
0153 G4cout << "Variable 'wt' set to constant value " << val << G4endl;
0154 }
0155 }
0156
0157
0158
0159
0160 void G4IAEAphspWriter::WriteIAEAParticle(const size_t idx, const G4int incHist,
0161 const G4int pdg, const G4double kinE,
0162 const G4double wt,
0163 const G4ThreeVector pos,
0164 const G4ThreeVector momDir)
0165 {
0166 IAEA_I32 partType;
0167 switch(pdg) {
0168 case 22:
0169 partType = 1;
0170 break;
0171 case 11:
0172 partType = 2;
0173 break;
0174 case -11:
0175 partType = 3;
0176 break;
0177 case 2112:
0178 partType = 4;
0179 break;
0180 case 2212:
0181 partType = 5;
0182 break;
0183 default:
0184 G4ExceptionDescription msg;
0185 msg << "PDG " << pdg
0186 << " is not supported by IAEAphsp format and will not be recorded."
0187 << G4endl;
0188 G4Exception("G4IAEAphspWriter::WriteIAEAParticle()",
0189 "IAEAphspWriter003", JustWarning, msg);
0190 return;
0191 }
0192
0193 IAEA_I32 sourceID = static_cast<IAEA_I32>(idx+fIAEASourcesOpen);
0194
0195 IAEA_I32 nStat = static_cast<IAEA_I32>(incHist);
0196 IAEA_Float energy = static_cast<IAEA_Float>(kinE/MeV);
0197 IAEA_Float weight = static_cast<IAEA_Float>(wt);
0198 IAEA_Float x = static_cast<IAEA_Float>( pos.x()/cm );
0199 IAEA_Float y = static_cast<IAEA_Float>( pos.y()/cm );
0200 IAEA_Float z = static_cast<IAEA_Float>( pos.z()/cm );
0201 IAEA_Float u = static_cast<IAEA_Float>( momDir.x() );
0202 IAEA_Float v = static_cast<IAEA_Float>( momDir.y() );
0203 IAEA_Float w = static_cast<IAEA_Float>( momDir.z() );
0204
0205
0206 IAEA_Float extraFloat = -1;
0207 IAEA_I32 extraInt = nStat;
0208
0209
0210 iaea_write_particle(&sourceID, &nStat, &partType,
0211 &energy, &weight,
0212 &x, &y, &z, &u, &v, &w, &extraFloat, &extraInt);
0213 }
0214
0215
0216
0217
0218
0219 void G4IAEAphspWriter::WriteIAEAParticle(const G4Step* aStep,
0220 const G4int zStopIdx)
0221 {
0222 IAEA_I32 sourceID =
0223 static_cast<IAEA_I32>(zStopIdx+fIAEASourcesOpen);
0224 G4double zStop = (*fZphspVec)[zStopIdx];
0225
0226
0227
0228 const G4Track* aTrack = aStep->GetTrack();
0229 G4int PDGCode = aTrack->GetDefinition()->GetPDGEncoding();
0230 IAEA_I32 partType;
0231 G4double postE = aStep->GetPostStepPoint()->GetKineticEnergy();
0232 G4double preE = aStep->GetPreStepPoint()->GetKineticEnergy();
0233 IAEA_Float kinEnergyMeV;
0234 G4ThreeVector postR = aStep->GetPostStepPoint()->GetPosition();
0235 G4ThreeVector preR = aStep->GetPreStepPoint()->GetPosition();
0236 G4double postZ = postR.z();
0237 G4double preZ = preR.z();
0238
0239 switch(PDGCode) {
0240 case 22:
0241 partType = 1;
0242 kinEnergyMeV = static_cast<IAEA_Float>(preE/MeV);
0243 break;
0244 case 11:
0245 partType = 2;
0246 kinEnergyMeV =
0247 static_cast<IAEA_Float>( (preE+
0248 (postE-preE)*(zStop-preZ)/(postZ-preZ))/MeV );
0249 break;
0250 case -11:
0251 partType = 3;
0252 kinEnergyMeV =
0253 static_cast<IAEA_Float>( (preE+
0254 (postE-preE)*(zStop-preZ)/(postZ-preZ))/MeV );
0255 break;
0256 case 2112:
0257 partType = 4;
0258 kinEnergyMeV = static_cast<IAEA_Float>(preE/MeV);
0259 break;
0260 case 2212:
0261 partType = 5;
0262 kinEnergyMeV =
0263 static_cast<IAEA_Float>( (preE+
0264 (postE-preE)*(zStop-preZ)/(postZ-preZ))/MeV );
0265 break;
0266 default:
0267 G4String pname = aTrack->GetDefinition()->GetParticleName();
0268 G4String errmsg = "'" + pname + "' is not supported by IAEAphsp format"
0269 + " and will not be recorded.";
0270 G4Exception("G4IAEAphspWriter::WriteIAEAParticle()",
0271 "IAEAphspWriter004", JustWarning, errmsg.c_str() );
0272 return;
0273 }
0274
0275
0276 IAEA_Float wt = static_cast<IAEA_Float>(aTrack->GetWeight());
0277
0278
0279 G4double postX = postR.x();
0280 G4double preX = preR.x();
0281 G4double postY = postR.y();
0282 G4double preY = preR.y();
0283 IAEA_Float x =
0284 static_cast<IAEA_Float>( (preX+
0285 (postX-preX)*(zStop-preZ)/(postZ-preZ))/cm );
0286 IAEA_Float y =
0287 static_cast<IAEA_Float>( (preY+
0288 (postY-preY)*(zStop-preZ)/(postZ-preZ))/cm );
0289 IAEA_Float z =
0290 static_cast<IAEA_Float>( zStop/cm );
0291
0292
0293 G4ThreeVector momDir = aStep->GetPreStepPoint()->GetMomentumDirection();
0294 IAEA_Float u = static_cast<IAEA_Float>(momDir.x());
0295 IAEA_Float v = static_cast<IAEA_Float>(momDir.y());
0296 IAEA_Float w = static_cast<IAEA_Float>(momDir.z());
0297
0298
0299 IAEA_Float extraFloat = -1;
0300
0301
0302 IAEA_I32 extraInt = -1;
0303 IAEA_I32 nStat = 0;
0304
0305
0306 iaea_write_particle(&sourceID, &nStat, &partType,
0307 &kinEnergyMeV, &wt,
0308 &x, &y, &z, &u, &v, &w, &extraFloat, &extraInt);
0309 }
0310
0311
0312
0313
0314
0315 void G4IAEAphspWriter::OpenIAEAphspOutFiles(const G4Run* aRun)
0316 {
0317
0318
0319
0320 const IAEA_I32 accessWrite = 2;
0321
0322 size_t nZphsps = fZphspVec->size();
0323 for (size_t ii = 0; ii < nZphsps; ii++) {
0324
0325 std::stringstream sstr;
0326 sstr << ((*fZphspVec)[ii]/cm);
0327 G4String zphsp(sstr.str());
0328 G4String fullName = fFileName + "_" + zphsp + "cm";
0329
0330
0331
0332 G4int runID = aRun->GetRunID();
0333 if (runID > 0) {
0334 std::stringstream sstr2;
0335 sstr2 << runID;
0336 G4String runIDStr(sstr2.str());
0337 fullName += "_";
0338 fullName += runIDStr;
0339 }
0340
0341
0342
0343
0344
0345 G4int reserved = IAEASourceIdRegistry::Instance().ReserveNextLowest();
0346 if (reserved < 0) {
0347 G4ExceptionDescription ed;
0348 ed << "No free IAEA source IDs available for writer" << G4endl;
0349 G4Exception("G4IAEAphspWriter::OpenIAEAphspOutFiles",
0350 "IAEAphspWriter005",FatalException, ed);
0351 }
0352 IAEA_I32 sourceWrite = static_cast<IAEA_I32>(reserved);
0353 char* filename = const_cast<char*>(fullName.data());
0354 IAEA_I32 result = 0;
0355
0356 iaea_new_source( &sourceWrite, filename, &accessWrite,
0357 &result, fullName.size()+1 );
0358
0359 if (result < 0 || sourceWrite < 0) {
0360 IAEASourceIdRegistry::Instance().Release(reserved);
0361 G4ExceptionDescription ed;
0362 ed << "IAEAphsp output file opening operation failed!" << G4endl;
0363 G4Exception("G4IAEAphspWriter::OpenIAEAphspOutFiles()",
0364 "IAEAphspWriter006", FatalException, ed);
0365 }
0366
0367
0368 fIAEASourcesOpen = sourceWrite - ii;
0369 G4cout << "G4IAEAphspWriter::OpenOutputIAEAphspFiles() ==> "
0370 << "\"" << fullName << "\" IAEAphsp id = " << sourceWrite << "."
0371 << G4endl;
0372
0373
0374
0375
0376
0377 std::map<G4int, G4double>::iterator itmap;
0378 for (itmap = fConstVariables->begin();
0379 itmap != fConstVariables->end(); itmap++) {
0380 IAEA_I32 varIdx = static_cast<IAEA_I32>( (*itmap).first );
0381 IAEA_Float varValue = static_cast<IAEA_I32>( (*itmap).second );
0382 iaea_set_constant_variable(&sourceWrite, &varIdx, &varValue);
0383 }
0384
0385
0386
0387
0388
0389
0390
0391 IAEA_I32 extraFloats = 0;
0392 IAEA_I32 extraInts = 1;
0393 iaea_set_extra_numbers(&sourceWrite, &extraFloats, &extraInts);
0394
0395
0396 IAEA_I32 longIdx = 0;
0397 IAEA_I32 longType = 1;
0398 iaea_set_type_extralong_variable(&sourceWrite, &longIdx, &longType);
0399 }
0400 }
0401
0402
0403
0404
0405 void G4IAEAphspWriter::CloseIAEAphspOutFiles()
0406 {
0407
0408 G4int nZphsps = fZphspVec->size();
0409 for (G4int ii = 0; ii < nZphsps; ii++) {
0410 const IAEA_I32 sourceID = static_cast<IAEA_I32>(ii+fIAEASourcesOpen);
0411 IAEA_I64 nEvts = static_cast<IAEA_I64>( fOrigHistories->at(ii) );
0412 iaea_set_total_original_particles(&sourceID, &nEvts);
0413
0414 IAEA_I32 result = 0;
0415 iaea_print_header(&sourceID, &result);
0416 if (result < 0) {
0417 G4Exception("G4IAEAphspWriter::EndOfRunAction()",
0418 "IAEAphspWriter007", JustWarning,
0419 "IAEA phsp source not found");
0420 }
0421
0422 iaea_destroy_source(&sourceID, &result);
0423 if (result > 0) {
0424 IAEASourceIdRegistry::Instance().Release(static_cast<G4int>(sourceID));
0425 G4cout << "Phase-space file at z_phsp = " << (*fZphspVec)[ii]/cm
0426 << " cm (IAEA source id #" << sourceID << ") closed successfully!"
0427 << G4endl << G4endl;
0428 }
0429 else {
0430 G4Exception("G4IAEAphspWriter::EndOfRunAction()",
0431 "IAEAphspWriter008", JustWarning,
0432 "IAEA file not closed properly");
0433 }
0434 }
0435 }