File indexing completed on 2025-01-18 09:16:53
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 #include <vector>
0033 #include <map>
0034 #include "ICRP110UserScoreWriter.hh"
0035 #include "ICRP110ScoreWriterMessenger.hh"
0036 #include "G4SystemOfUnits.hh"
0037 #include "G4SDParticleFilter.hh"
0038 #include "G4VPrimitiveScorer.hh"
0039 #include "G4VScoringMesh.hh"
0040
0041 ICRP110UserScoreWriter::ICRP110UserScoreWriter():
0042 G4VScoreWriter()
0043 {
0044 fMessenger = new ICRP110ScoreWriterMessenger(this);
0045 fSex = "female";
0046 fSection = "head";
0047 }
0048
0049 ICRP110UserScoreWriter::~ICRP110UserScoreWriter()
0050 {
0051 delete fMessenger;
0052 }
0053
0054 void ICRP110UserScoreWriter::DumpQuantityToFile(const G4String & psName, const G4String & fileName, const G4String & option)
0055 {
0056 using MeshScoreMap = G4VScoringMesh::MeshScoreMap;
0057
0058 if(verboseLevel > 0)
0059 {
0060 G4cout << "ICRP110UserScorer-defined DumpQuantityToFile() method is invoked." << G4endl;
0061 }
0062
0063
0064 G4String opt = option;
0065 std::transform(opt.begin(), opt.end(), opt.begin(), (int (*)(int))(tolower));
0066
0067
0068 if(opt.size() == 0) opt = "csv";
0069
0070
0071
0072
0073
0074
0075
0076
0077 std::ofstream ofile(fileName);
0078
0079 if(!ofile)
0080 {
0081 G4cerr << "ERROR : DumpToFile : File open error -> " << fileName << G4endl;
0082 return;
0083 }
0084 ofile << "# mesh name: " << fScoringMesh -> GetWorldName() << G4endl;
0085
0086
0087 MeshScoreMap fSMap = fScoringMesh -> GetScoreMap();
0088
0089 auto msMapItr = fSMap.find(psName);
0090
0091 if(msMapItr == fSMap.end())
0092 {
0093 G4cerr << "ERROR : DumpToFile : Unknown quantity, \""<< psName
0094 << "\"." << G4endl;
0095 return;
0096 }
0097
0098 std::map<G4int, G4StatDouble*> * score = msMapItr -> second-> GetMap();
0099
0100 ofile << "# primitive scorer name: " << msMapItr -> first << G4endl;
0101
0102
0103 std::vector<double> ScoringMeshEdep;
0104 for(G4int y = 0; y < fNMeshSegments[0]*fNMeshSegments[1]*fNMeshSegments[2]; y++) ScoringMeshEdep.push_back(0.);
0105
0106 ofile << std::setprecision(16);
0107
0108 for(G4int x = 0; x < fNMeshSegments[0]; x++) {
0109 for(G4int y = 0; y < fNMeshSegments[1]; y++) {
0110 for(G4int z = 0; z < fNMeshSegments[2]; z++){
0111
0112 G4int idx = GetIndex(x, y, z);
0113 std::map<G4int, G4StatDouble*>::iterator value = score -> find(idx);
0114 if (value != score -> end()) ScoringMeshEdep[idx] += (value->second->sum_wx())/(joule);
0115 }
0116 }
0117 }
0118
0119 ofile << std::setprecision(6);
0120
0121 ofile << std::setprecision(16);
0122
0123 for(G4int x = 0; x < fNMeshSegments[0]; x++) {
0124 for(G4int y = 0; y < fNMeshSegments[1]; y++) {
0125 for(G4int z = 0; z < fNMeshSegments[2]; z++){
0126
0127 G4int idx = GetIndex(x, y, z);
0128
0129 if (ScoringMeshEdep[idx] != 0){
0130 ofile << x << '\t' << y << '\t' << z << '\t' << ScoringMeshEdep[idx] << G4endl;
0131 }
0132
0133
0134 }
0135 }
0136 }
0137
0138
0139 ofile.close();
0140
0141
0142
0143
0144
0145
0146
0147
0148 G4int NSlices = 0;
0149 G4int NXVoxels = 0;
0150 G4int NYVoxels = 0;
0151 std::ifstream DataFile;
0152
0153 G4cout << "Phantom Sex: " << fSex << G4endl;
0154 G4cout << "Phantom Section: " << fSection << G4endl;
0155
0156 G4String male = "male";
0157 G4String female = "female";
0158
0159
0160
0161 if (fSex == "male")
0162 {
0163 if (fSection == "head")
0164 {
0165 DataFile.open("ICRPdata/MaleHead.dat");
0166 G4cout << "Selecting data file ICRPdata/MaleHead.dat..." << G4endl;
0167 }
0168 if (fSection == "trunk")
0169 {
0170 DataFile.open("ICRPdata/MaleTrunk.dat");
0171 G4cout << "Selecting data file ICRPdata/MaleTrunk.dat..." << G4endl;
0172 }
0173 if (fSection == "full")
0174 {
0175 DataFile.open("ICRPdata/MaleData.dat");
0176 G4cout << "Selecting data file ICRPdata/MaleData.dat..." << G4endl;
0177 }
0178 }
0179 else if(fSex == "female")
0180 {
0181 if (fSection == "head")
0182 {
0183 DataFile.open("ICRPdata/FemaleHead.dat");
0184 G4cout << "Selecting data file ICRPdata/FemaleHead.dat..." << G4endl;
0185 }
0186 if (fSection == "trunk")
0187 {
0188 DataFile.open("ICRPdata/FemaleTrunk.dat");
0189 G4cout << "Selecting data file ICRPdata/FemaleTrunk.dat..." << G4endl;
0190 }
0191 if (fSection == "full")
0192 {
0193 DataFile.open("ICRPdata/FemaleData.dat");
0194 G4cout << "Selecting data file ICRPdata/FemaleData.dat..." << G4endl;
0195 }
0196 }
0197 else
0198 {
0199 G4cout << "Phantom Sex or section not correctly specified to ICRP110UserScoreWriter" << G4endl;
0200 }
0201
0202
0203 if(DataFile.good() != 1 )
0204 {
0205 G4cout << "Problem Reading Data File" << G4endl;
0206 }
0207 else
0208 {
0209 G4cout << "Opening Data.dat File..." << G4endl;
0210 }
0211
0212 DataFile >> NSlices;
0213 G4cout << "Number of Phantom Slices Simulated = " << NSlices << G4endl;
0214
0215 DataFile >> NXVoxels >> NYVoxels;
0216 G4cout << "Number of X Voxels per slice = " << NXVoxels << G4endl;
0217 G4cout << "Number of Y Voxels per slice = " << NYVoxels << G4endl;
0218
0219
0220 G4int VoxelsPerSlice = 0;
0221 VoxelsPerSlice = NXVoxels * NYVoxels;
0222
0223
0224 for (G4int i = 0; i < 58; i++){
0225 DataFile.ignore(256, '\n');
0226 }
0227
0228
0229
0230 std::vector<G4String> SliceName;
0231
0232 for(G4int i = 0; i < NSlices; i++){
0233 SliceName.push_back("empty");
0234 }
0235
0236 for (G4int i = 0; i < NSlices; i++){
0237 DataFile >> SliceName[i];
0238 }
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 G4int ARRAY_SIZE = VoxelsPerSlice * NSlices;
0250
0251 std::vector<G4int> OrganIDs;
0252
0253 std::ifstream PhantomFile;
0254
0255 for (G4int ii = 0; ii < NSlices; ii++){
0256
0257 G4String sliceVar = SliceName[ii];
0258 G4String slice;
0259
0260 if (fSex == "male")
0261 {
0262 slice = "ICRPdata/ICRP110_g4dat/AM/"+sliceVar;
0263 }
0264 else if(fSex == "female")
0265 {
0266 slice = "ICRPdata/ICRP110_g4dat/AF/"+sliceVar;
0267 }
0268
0269 PhantomFile.open(slice.c_str());
0270
0271
0272 if(PhantomFile.good() != 1 )
0273 {
0274 G4cout << "Problem Reading Phantom Slice File:" << SliceName[ii] << G4endl;
0275 }
0276 else
0277 {
0278 G4cout << "Opening Phantom Slice File: " << SliceName[ii] << G4endl;
0279 }
0280
0281 G4int FNVoxelX;
0282 G4int FNVoxelY;
0283 G4int FNVoxelZ;
0284
0285
0286 PhantomFile >> FNVoxelX >> FNVoxelY >> FNVoxelZ;
0287
0288 G4int aa = 0;
0289
0290 for (G4int i = 0; i < VoxelsPerSlice; i++)
0291 {
0292 PhantomFile >> aa;
0293 OrganIDs.push_back(aa);
0294 }
0295
0296 PhantomFile.close();
0297 }
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307 std::ifstream MeshFile(fileName);
0308
0309
0310 if(MeshFile.good() != 1 )
0311 {
0312 G4cout << "Problem Reading Data File: " << fileName << G4endl;
0313 }
0314 else {
0315 G4cout << "Opening File: " << fileName << G4endl;
0316 }
0317
0318
0319
0320
0321 G4int col = 4;
0322 G4int lines = VoxelsPerSlice*NSlices;
0323
0324
0325 MeshFile.ignore(256, '\n');
0326 MeshFile.ignore(256, '\n');
0327
0328 std::vector<G4int> X_MeshID;
0329 std::vector<G4int> Y_MeshID;
0330 std::vector<G4int> Z_MeshID;
0331 std::vector<G4double> Edep;
0332
0333 G4int nX = 0;
0334 G4int nY = 0;
0335 G4int nZ = 0;
0336 G4double EDep = 0.0;
0337
0338 for (G4int i=0; i< lines; i++){
0339 for (G4int j=0; j < col;){
0340
0341 MeshFile >> nX;
0342 X_MeshID.push_back(nX);
0343 j++;
0344
0345 MeshFile >> nY;
0346 Y_MeshID.push_back(nY);
0347 j++;
0348
0349 MeshFile >> nZ;
0350 Z_MeshID.push_back(nZ);
0351 j++;
0352
0353 MeshFile >> EDep;
0354 Edep.push_back(EDep);
0355 j++;
0356
0357 }
0358 }
0359
0360 MeshFile.close();
0361
0362
0363
0364
0365
0366
0367 std::ifstream PhantomOrganNames;
0368
0369 if (strcmp(fSex.c_str(), male.c_str()) == 0)
0370 {
0371 PhantomOrganNames.open ("ICRPdata/ICRP110_g4dat/P110_data_V1.2/AM/AM_organs.dat");
0372
0373 if(PhantomOrganNames.good() != 1 )
0374 {
0375 G4cout << "Problem reading AM_organs.dat" << G4endl;
0376 }
0377 else
0378 {
0379 G4cout << "Reading AM_organs.dat" << G4endl;
0380 }
0381 }
0382 else if(strcmp(fSex.c_str(), female.c_str()) == 0)
0383 {
0384 PhantomOrganNames.open ("ICRPdata/ICRP110_g4dat/P110_data_V1.2/AF/AF_organs.dat");
0385
0386 if(PhantomOrganNames.good() != 1 )
0387 {
0388 G4cout << "Problem reading AF_organs.dat" << G4endl;
0389 }
0390 else
0391 {
0392 G4cout << "Reading AF_organs.dat" << G4endl;
0393 }
0394 }
0395
0396
0397 PhantomOrganNames.ignore(256, '\n');
0398 PhantomOrganNames.ignore(256, '\n');
0399 PhantomOrganNames.ignore(256, '\n');
0400 PhantomOrganNames.ignore(256, '\n');
0401
0402 G4String str;
0403 std::vector<G4String> OrganNames;
0404
0405 OrganNames.push_back("0 Air");
0406
0407 while(getline(PhantomOrganNames, str))
0408 {
0409 OrganNames.push_back(str);
0410 }
0411 OrganNames.push_back("141 Phantom Top/Bottom Skin Layer");
0412
0413
0414
0415
0416
0417
0418
0419
0420 G4int NOrganIDs = OrganNames.size();
0421
0422 std::ifstream OrganMasses;
0423
0424 OrganMasses.open ("ICRPdata/OrganMasses.dat");
0425
0426 if(OrganMasses.good() != 1 )
0427 {
0428 G4cout << "Problem reading OrganMasses.dat" << G4endl;
0429 }
0430 else
0431 {
0432 G4cout << "Reading OrganMasses.dat" << G4endl;
0433 }
0434
0435
0436 OrganMasses.ignore(256, '\n');
0437
0438 std::vector<G4int> iteratorID;
0439 std::vector<G4double> MaleOrganMasses;
0440 std::vector<G4double> FemaleOrganMasses;
0441
0442 G4int itID = 0;
0443 G4double massM = 0.0;
0444 G4double massF = 0.0;
0445
0446 for (G4int i = 0; i < NOrganIDs; i++)
0447 {
0448 OrganMasses >> itID;
0449 iteratorID.push_back(itID);
0450
0451 OrganMasses >> massM;
0452 MaleOrganMasses.push_back(massM);
0453
0454 OrganMasses >> massF;
0455 FemaleOrganMasses.push_back(massF);
0456 }
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468 std::ofstream OutputFile2;
0469
0470 G4int VoxelNumber = 0;
0471 G4int OrganIndex = 0;
0472 G4cout << "NOrganIDs: " << NOrganIDs << G4endl;
0473 std::vector <G4double> OrganDep;
0474 std::vector <G4double> OrganDose;
0475
0476 G4double a = 0.0;
0477 G4double b = 0.0;
0478
0479 for (G4int i = 0; i < NOrganIDs; i++)
0480 {
0481 OrganDep.push_back(a);
0482 OrganDose.push_back(b);
0483 }
0484
0485
0486 for (G4int i = 0; i < ARRAY_SIZE; i++){
0487 VoxelNumber = X_MeshID[i] + NXVoxels * Y_MeshID[i] + VoxelsPerSlice * Z_MeshID[i];
0488 OrganIndex = OrganIDs[VoxelNumber];
0489 OrganDep[OrganIndex] += Edep[i];
0490 }
0491
0492
0493 if (strcmp(fSex.c_str(), male.c_str()) == 0)
0494 {
0495 for (G4int i = 0; i < NOrganIDs; i++)
0496 {
0497 OrganDose[i] = (MaleOrganMasses[i] == 0 ) ? 0 : OrganDep[i]/(MaleOrganMasses[i] * 1e-3);
0498 }
0499 }
0500 else if(strcmp(fSex.c_str(), female.c_str()) == 0)
0501 {
0502 for (G4int i = 0; i < NOrganIDs; i++)
0503 {
0504 OrganDose[i] = (FemaleOrganMasses[i] == 0 ) ? 0 : OrganDep[i]/(FemaleOrganMasses[i] * 1e-3);
0505 }
0506 }
0507
0508 OutputFile2.open ("ICRP110.out");
0509
0510
0511 if(OutputFile2.good() != 1 )
0512 {
0513 G4cout << "Problem writing output to ICRP110.out" << G4endl;
0514 }
0515 else {
0516 G4cout << "Writing output to ICRP110.out" << G4endl;
0517 }
0518
0519
0520 G4double TotalDep = 0.0;
0521 G4double TotalDose = 0.0;
0522
0523 OutputFile2 << G4endl;
0524 OutputFile2 << '\t' << "-------------------------------- " << G4endl;
0525 OutputFile2 << '\t' << "OrganID" << '\t' << "Edep (J)" << '\t' << "Dose (Gy)" << G4endl;
0526 OutputFile2 << '\t' << "-------------------------------- " << G4endl;
0527
0528
0529 for (G4int i = 1; i < NOrganIDs; i++)
0530 {
0531 if (OrganDep[i] != 0)
0532 {
0533 if (i != 140)
0534 {
0535 OutputFile2 << '\t' << i << " |" << '\t' << '\t' << OrganDep[i] << '\t' << OrganDose[i] << G4endl;
0536 }
0537 }
0538 }
0539
0540 OutputFile2 << "----------------------------------------------------------------------------" << G4endl;
0541 OutputFile2 << "-------------------------------ORGAN INFO-----------------------------------" << G4endl;
0542 OutputFile2 << "-----------------(of organs where edep/dose was recorded)-------------------" << G4endl;
0543 OutputFile2 << "----------------------------------------------------------------------------" << G4endl;
0544 OutputFile2 << "ID" << '\t' << '\t' << "Organ Name" << '\t' << " " << '\t' << " " << '\t' << " " << '\t' << "Material ID" << '\t' << '\t' << "Density (g/cm^3) " << G4endl;
0545
0546 for(G4int i = 1; i < NOrganIDs; i++)
0547 {
0548 if (OrganDep[i] != 0)
0549 {
0550 if (i != 140)
0551 {
0552 OutputFile2 << OrganNames[i] << G4endl;
0553 }
0554 }
0555 }
0556
0557
0558 for (G4int i = 1; i < NOrganIDs; i++)
0559 {
0560 if (i != 140)
0561 {
0562 TotalDep += OrganDep[i];
0563 TotalDose += OrganDose[i];
0564 }
0565 }
0566
0567 OutputFile2 << G4endl;
0568 OutputFile2 << "Total Edep over all organs = " << TotalDep << " J" << G4endl;
0569 OutputFile2 << "Total dose absorbed over all organs = " << TotalDose << " Gy" << G4endl;
0570
0571
0572 OutputFile2 << G4endl;
0573 OutputFile2 << "----------------------------------------------------------------------------" << G4endl;
0574 OutputFile2 << "----------------ORGAN ENERGY DEPOSITIONS AND ABSORBED DOSE------------------" << G4endl;
0575 OutputFile2 << "-----------(for all organs [includes air - OrganIDs = 0, 140])--------------" << G4endl;
0576 OutputFile2 << "--------------([and top/bottom skin layer - OrganIDs = 141])----------------" << G4endl;
0577 OutputFile2 << "----------------------------------------------------------------------------" << G4endl;
0578 OutputFile2 << "OrganID" << '\t' << "Edep (J) " << '\t' << "Dose (Gy) " << G4endl;
0579 OutputFile2 << "-------------------------------" << G4endl;
0580
0581 for (G4int i = 0; i < NOrganIDs; i++)
0582 {
0583 OutputFile2 << i << " | " << '\t' << '\t' << OrganDep[i] << '\t' << OrganDose[i] << G4endl;
0584 }
0585
0586 OutputFile2 << "Total energy depositied over all organs = " << TotalDep << " J" << G4endl;
0587 OutputFile2 << "Total absorbed dose over all organs = " << TotalDose << " Gy " << G4endl;
0588 G4cout << "Total energy deposited over all Organs within the Phantom is " << TotalDep << " J" << G4endl;
0589 G4cout << "Total absorbed dose over all phantom organs is " << TotalDose << " Gy " << G4endl;
0590
0591 OutputFile2.close();
0592 }
0593
0594
0595
0596 void ICRP110UserScoreWriter::SetPhantomSex(G4String newSex)
0597 {
0598 fSex = newSex;
0599
0600 if (fSex == "male")
0601 {
0602 G4cout << ">> Male Phantom identified by UserScoreWriter." << G4endl;
0603 }
0604 if (fSex == "female")
0605 {
0606 G4cout << ">> Female Phantom identified by UserScoreWriter." << G4endl;
0607 }
0608 if ((fSex != "female") && (fSex != "male"))
0609 G4cout << fSex << " can not be defined!" << G4endl;
0610 }
0611
0612
0613 void ICRP110UserScoreWriter::SetPhantomSection(G4String newSection)
0614 {
0615 fSection = newSection;
0616
0617 if (fSection == "head")
0618 {
0619 G4cout << ">> Partial Head Phantom identified by UserScoreWriter." << G4endl;
0620 }
0621 if (fSection == "trunk")
0622 {
0623 G4cout << ">> Partial Trunk Phantom identified by UserScoreWriter." << G4endl;
0624 }
0625 if (fSection == "full")
0626 {
0627 G4cout << ">> Custom/Full Phantom identified by UserScoreWriter." << G4endl;
0628 }
0629 if ((fSection != "head") && (fSection != "trunk") && (fSection != "full"))
0630 G4cout << fSection << " can not be defined!" << G4endl;
0631 }