File indexing completed on 2025-02-23 09:22:19
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 #include "LET.hh"
0031
0032 #include "G4EmCalculator.hh"
0033 #include "G4RunManager.hh"
0034 #include "G4SystemOfUnits.hh"
0035
0036 #include "DetectorConstruction.hh"
0037 #include "Hit.hh"
0038 #include "LETAccumulable.hh"
0039 #include "LETMessenger.hh"
0040 #include "VoxelizedSensitiveDetector.hh"
0041
0042 #include <cmath>
0043
0044 namespace RadioBio
0045 {
0046
0047
0048 LET::LET() : VRadiobiologicalQuantity()
0049 {
0050 fPath = "RadioBio_LET.out";
0051
0052 fMessenger = new LETMessenger(this);
0053
0054 Initialize();
0055 }
0056
0057
0058
0059 LET::~LET()
0060 {
0061 delete fMessenger;
0062 }
0063
0064
0065
0066 void LET::Initialize()
0067 {
0068 G4int VoxelNumber = VoxelizedSensitiveDetector::GetInstance()->GetTotalVoxelNumber();
0069
0070
0071 fNTotalLETT.resize(VoxelNumber);
0072 fNTotalLETD.resize(VoxelNumber);
0073 fDTotalLETT.resize(VoxelNumber);
0074 fDTotalLETD.resize(VoxelNumber);
0075
0076 fTotalLETD.resize(VoxelNumber);
0077 fTotalLETT.resize(VoxelNumber);
0078
0079 fInitialized = true;
0080 }
0081
0082
0083
0084 void LET::Compute()
0085 {
0086
0087 if (!fCalculationEnabled) {
0088 if (fVerboseLevel > 0) {
0089 G4cout << "LET::Compute() called but skipped as calculation not enabled" << G4endl;
0090 }
0091 return;
0092 }
0093 if (fVerboseLevel > 0) G4cout << "LET::Compute()" << G4endl;
0094
0095 if (VoxelizedSensitiveDetector::GetInstance() == nullptr)
0096 G4Exception("LET::ComputeLET", "PointerNotAvailable", FatalException,
0097 "Computing LET without voxelized geometry pointer!");
0098
0099 G4int VoxelNumber = VoxelizedSensitiveDetector::GetInstance()->GetTotalVoxelNumber();
0100
0101 for (G4int v = 0; v < VoxelNumber; v++) {
0102 if (fVerboseLevel > 1) G4cout << "COMPUTING LET of voxel " << v << G4endl;
0103
0104
0105 if (fDTotalLETD[v] > 0.) fTotalLETD[v] = fNTotalLETD[v] / fDTotalLETD[v];
0106
0107
0108 if (fDTotalLETT[v] > 0.) fTotalLETT[v] = fNTotalLETT[v] / fDTotalLETT[v];
0109 }
0110
0111
0112 std::sort(fIonLetStore.begin(), fIonLetStore.end());
0113
0114
0115 for (size_t ion = 0; ion < fIonLetStore.size(); ion++) {
0116 fIonLetStore[ion].Calculate();
0117 }
0118
0119 fCalculated = true;
0120 }
0121
0122
0123
0124
0125 void LET::Store()
0126 {
0127
0128 if (!fCalculationEnabled) {
0129 if (fVerboseLevel > 0) {
0130 G4cout << "LET::Store() called but skipped as calculation not enabled" << G4endl;
0131 }
0132 return;
0133 }
0134
0135 if (fSaved == true)
0136 G4Exception("LET::StoreLET", "NtuplesAlreadySaved", FatalException,
0137 "Overwriting LET file. For multiple runs, change filename.");
0138
0139 Compute();
0140 #define width 15L
0141 if (fVerboseLevel > 0) G4cout << "LET::StoreLET" << G4endl;
0142
0143
0144 if (fIonLetStore.size()) {
0145 std::ofstream ofs(fPath);
0146
0147 if (ofs.is_open()) {
0148
0149 ofs << std::setprecision(6) << std::left << "i\tj\tk\t";
0150 ofs << std::setw(width) << "LDT";
0151 ofs << std::setw(width) << "LTT";
0152
0153 for (size_t l = 0; l < fIonLetStore.size(); l++)
0154 {
0155 G4String a = (fIonLetStore[l].IsPrimary()) ? "_1_D" : "_D";
0156 ofs << std::setw(width) << fIonLetStore[l].GetName() + a;
0157 G4String b = (fIonLetStore[l].IsPrimary()) ? "_1_T" : "_T";
0158 ofs << std::setw(width) << fIonLetStore[l].GetName() + b;
0159 }
0160 ofs << G4endl;
0161
0162
0163 G4AnalysisManager* LETFragmentTuple = G4AnalysisManager::Instance();
0164
0165 LETFragmentTuple->SetVerboseLevel(1);
0166 LETFragmentTuple->SetFirstHistoId(1);
0167 LETFragmentTuple->SetFirstNtupleId(1);
0168
0169 LETFragmentTuple->SetDefaultFileType("xml");
0170 LETFragmentTuple->OpenFile("LET");
0171
0172 LETFragmentTuple->CreateNtuple("coordinate", "LET");
0173
0174 LETFragmentTuple->CreateNtupleIColumn("i");
0175 LETFragmentTuple->CreateNtupleIColumn("j");
0176 LETFragmentTuple->CreateNtupleIColumn("k");
0177 LETFragmentTuple->CreateNtupleDColumn("TotalLETD");
0178 LETFragmentTuple->CreateNtupleDColumn("TotalLETT");
0179 LETFragmentTuple->CreateNtupleIColumn("A");
0180 LETFragmentTuple->CreateNtupleIColumn("Z");
0181 LETFragmentTuple->CreateNtupleDColumn("IonLetD");
0182 LETFragmentTuple->CreateNtupleDColumn("IonLetT");
0183 LETFragmentTuple->FinishNtuple();
0184
0185 auto voxSensDet = VoxelizedSensitiveDetector::GetInstance();
0186
0187 for (G4int i = 0; i < voxSensDet->GetVoxelNumberAlongX(); i++)
0188 for (G4int j = 0; j < voxSensDet->GetVoxelNumberAlongY(); j++)
0189 for (G4int k = 0; k < voxSensDet->GetVoxelNumberAlongZ(); k++) {
0190 LETFragmentTuple->FillNtupleIColumn(1, 0, i);
0191 LETFragmentTuple->FillNtupleIColumn(1, 1, j);
0192 LETFragmentTuple->FillNtupleIColumn(1, 2, k);
0193
0194 G4int v = voxSensDet->GetThisVoxelNumber(i, j, k);
0195
0196
0197 ofs << G4endl;
0198 ofs << i << '\t' << j << '\t' << k << '\t';
0199 ofs << std::setw(width) << fTotalLETD[v] / (keV / um);
0200 ofs << std::setw(width) << fTotalLETT[v] / (keV / um);
0201
0202
0203 for (size_t l = 0; l < fIonLetStore.size(); l++) {
0204
0205 ofs << std::setw(width) << fIonLetStore[l].GetLETD()[v] / (keV / um);
0206 ofs << std::setw(width) << fIonLetStore[l].GetLETT()[v] / (keV / um);
0207 }
0208
0209 LETFragmentTuple->FillNtupleDColumn(1, 3, fTotalLETD[v] / (keV / um));
0210 LETFragmentTuple->FillNtupleDColumn(1, 4, fTotalLETT[v] / (keV / um));
0211
0212 for (size_t ll = 0; ll < fIonLetStore.size(); ll++) {
0213 LETFragmentTuple->FillNtupleIColumn(1, 5, fIonLetStore[ll].GetA());
0214 LETFragmentTuple->FillNtupleIColumn(1, 6, fIonLetStore[ll].GetZ());
0215
0216 LETFragmentTuple->FillNtupleDColumn(1, 7, fIonLetStore[ll].GetLETD()[v] / (keV / um));
0217 LETFragmentTuple->FillNtupleDColumn(1, 8, fIonLetStore[ll].GetLETT()[v] / (keV / um));
0218 LETFragmentTuple->AddNtupleRow(1);
0219 }
0220 }
0221 ofs.close();
0222
0223
0224 LETFragmentTuple->CloseFile();
0225 }
0226 }
0227
0228 fSaved = true;
0229 }
0230
0231
0232
0233 void LET::Reset()
0234 {
0235 if (fVerboseLevel > 1) {
0236 G4cout << "LET::Reset(): ";
0237 }
0238 fNTotalLETT = 0.0;
0239 fNTotalLETD = 0.0;
0240 fDTotalLETT = 0.0;
0241 fDTotalLETD = 0.0;
0242
0243 fTotalLETD = 0.0;
0244 fTotalLETT = 0.0;
0245
0246 fIonLetStore.clear();
0247 fCalculated = false;
0248 }
0249
0250
0251
0252
0253 void LET::AddFromAccumulable(G4VAccumulable* GenAcc)
0254 {
0255 LETAccumulable* acc = (LETAccumulable*)GenAcc;
0256
0257 AddNTotalLETT(acc->GetTotalLETT());
0258 AddDTotalLETT(acc->GetDTotalLETT());
0259 AddNTotalLETD(acc->GetTotalLETD());
0260 AddDTotalLETD(acc->GetDTotalLETD());
0261
0262
0263
0264 for (unsigned int l = 0; l < acc->GetIonLetStore().size(); l++) {
0265 G4int PDGencoding = acc->GetIonLetStore()[l].GetPDGencoding();
0266 size_t q;
0267
0268 for (q = 0; q < fIonLetStore.size(); q++) {
0269
0270 if (fIonLetStore[q].GetPDGencoding() == PDGencoding) {
0271 if (acc->GetIonLetStore()[l].IsPrimary() == fIonLetStore[q].IsPrimary()) break;
0272 }
0273 }
0274
0275 if (q == fIonLetStore.size())
0276 fIonLetStore.push_back(acc->GetIonLetStore()[l]);
0277 else
0278 fIonLetStore[q].Merge(&(acc->GetIonLetStore()[l]));
0279 }
0280 fCalculated = false;
0281 }
0282
0283
0284
0285 void LET::PrintParameters()
0286 {
0287 G4cout << "*******************************************" << G4endl
0288 << "******* Parameters of the class LET *******" << G4endl
0289 << "*******************************************" << G4endl;
0290 PrintVirtualParameters();
0291 }
0292
0293
0294
0295 }