File indexing completed on 2025-01-31 09:22:18
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 #include "HadrontherapyDetectorConstruction.hh"
0030 #include "HadrontherapyLet.hh"
0031
0032 #include "HadrontherapyMatrix.hh"
0033 #include "HadrontherapyInteractionParameters.hh"
0034 #include "HadrontherapyPrimaryGeneratorAction.hh"
0035 #include "HadrontherapyMatrix.hh"
0036 #include "G4AnalysisManager.hh"
0037 #include "G4RunManager.hh"
0038 #include "G4SystemOfUnits.hh"
0039 #include <cmath>
0040
0041 HadrontherapyLet* HadrontherapyLet::instance = NULL;
0042 G4bool HadrontherapyLet::doCalculation = false;
0043
0044 HadrontherapyLet* HadrontherapyLet::GetInstance(HadrontherapyDetectorConstruction *pDet)
0045 {
0046 if (instance) delete instance;
0047 instance = new HadrontherapyLet(pDet);
0048 return instance;
0049 }
0050
0051 HadrontherapyLet* HadrontherapyLet::GetInstance()
0052 {
0053 return instance;
0054 }
0055
0056 HadrontherapyLet::HadrontherapyLet(HadrontherapyDetectorConstruction* pDet)
0057 :filename("Let.out"),matrix(0)
0058 {
0059
0060 matrix = HadrontherapyMatrix::GetInstance();
0061
0062 if (!matrix)
0063 G4Exception("HadrontherapyLet::HadrontherapyLet",
0064 "Hadrontherapy0005", FatalException,
0065 "HadrontherapyMatrix not found. Firstly create an instance of it.");
0066
0067 nVoxels = matrix -> GetNvoxel();
0068
0069 numberOfVoxelAlongX = matrix -> GetNumberOfVoxelAlongX();
0070 numberOfVoxelAlongY = matrix -> GetNumberOfVoxelAlongY();
0071 numberOfVoxelAlongZ = matrix -> GetNumberOfVoxelAlongZ();
0072
0073 G4RunManager *runManager = G4RunManager::GetRunManager();
0074 pPGA = (HadrontherapyPrimaryGeneratorAction*)runManager -> GetUserPrimaryGeneratorAction();
0075
0076 detectorMat = pDet -> GetDetectorLogicalVolume() -> GetMaterial();
0077 density = detectorMat -> GetDensity();
0078
0079 totalLetD = new G4double[nVoxels];
0080 DtotalLetD = new G4double[nVoxels];
0081 totalLetT = new G4double[nVoxels];
0082 DtotalLetT = new G4double[nVoxels];
0083
0084 }
0085
0086 HadrontherapyLet::~HadrontherapyLet()
0087 {
0088 Clear();
0089 delete [] totalLetD;
0090 delete [] DtotalLetD;
0091 delete [] totalLetT;
0092 delete [] DtotalLetT;
0093 }
0094
0095
0096 void HadrontherapyLet::Initialize()
0097 {
0098 for(G4int v=0; v < nVoxels; v++) totalLetD[v] = DtotalLetD[v] = totalLetT[v] = DtotalLetT[v] = 0.;
0099 Clear();
0100 }
0101
0102
0103
0104 void HadrontherapyLet::Clear()
0105 {
0106 for (size_t i=0; i < ionLetStore.size(); i++)
0107 {
0108 delete [] ionLetStore[i].letDN;
0109 delete [] ionLetStore[i].letDD;
0110 delete [] ionLetStore[i].letTN;
0111 delete [] ionLetStore[i].letTD;
0112 }
0113 ionLetStore.clear();
0114 }
0115 void HadrontherapyLet::FillEnergySpectrum(G4int trackID,
0116 G4ParticleDefinition* particleDef,
0117 G4double ekinMean,
0118 const G4Material* mat,
0119 G4double DE,
0120 G4double DEEletrons,
0121 G4double DX,
0122 G4int i, G4int j, G4int k)
0123 {
0124 if (DE <= 0. || DX <=0. ) return;
0125 if (!doCalculation) return;
0126
0127
0128 G4int Z = particleDef -> GetAtomicNumber();
0129 if (Z<1) return;
0130
0131 G4int PDGencoding = particleDef -> GetPDGEncoding();
0132 PDGencoding -= PDGencoding%10;
0133
0134 G4int voxel = matrix -> Index(i,j,k);
0135
0136
0137 G4EmCalculator emCal;
0138
0139 G4double Lsn = emCal.ComputeElectronicDEDX(ekinMean, particleDef, mat);
0140
0141
0142
0143 totalLetD[voxel] += (DE + DEEletrons) * Lsn;
0144 DtotalLetD[voxel] += DE + DEEletrons;
0145 totalLetT[voxel] += DX * Lsn;
0146 DtotalLetT[voxel] += DX;
0147
0148
0149 size_t l;
0150 for (l=0; l < ionLetStore.size(); l++)
0151 {
0152
0153 if (ionLetStore[l].PDGencoding == PDGencoding)
0154 if ( ((trackID ==1) && (ionLetStore[l].isPrimary)) || ((trackID !=1) && (!ionLetStore[l].isPrimary)))
0155 break;
0156 }
0157
0158 if (l == ionLetStore.size())
0159 {
0160
0161 G4int A = particleDef -> GetAtomicMass();
0162
0163
0164 G4String fullName = particleDef -> GetParticleName();
0165 G4String name = fullName.substr (0, fullName.find("[") );
0166
0167 ionLet ion =
0168 {
0169 (trackID == 1) ? true:false,
0170 PDGencoding,
0171 fullName,
0172 name,
0173 Z,
0174 A,
0175 new G4double[nVoxels],
0176 new G4double[nVoxels],
0177 new G4double[nVoxels],
0178 new G4double[nVoxels],
0179 };
0180
0181
0182 for(G4int v=0; v < nVoxels; v++)
0183 {
0184 ion.letDN[v] = ion.letDD[v] = ion.letTN[v] = ion.letTD[v] = 0.;
0185 }
0186
0187
0188 ionLetStore.push_back(ion);
0189 }
0190
0191
0192 ionLetStore[l].letDN[voxel] += (DE + DEEletrons)* Lsn;
0193 ionLetStore[l].letDD[voxel] += DE + DEEletrons;
0194 ionLetStore[l].letTN[voxel] += DX* Lsn;
0195 ionLetStore[l].letTD[voxel] += DX;
0196
0197 }
0198
0199
0200
0201
0202 void HadrontherapyLet::LetOutput()
0203 {
0204 for(G4int v=0; v < nVoxels; v++)
0205 {
0206
0207 if (DtotalLetD[v]>0.) totalLetD[v] = totalLetD[v]/DtotalLetD[v];
0208 if (DtotalLetT[v]>0.) totalLetT[v] = totalLetT[v]/DtotalLetT[v];
0209 }
0210
0211
0212 std::sort(ionLetStore.begin(), ionLetStore.end());
0213
0214
0215
0216
0217 for(G4int v=0; v < nVoxels; v++)
0218 {
0219
0220 for (size_t ion=0; ion < ionLetStore.size(); ion++)
0221 {
0222
0223 if (ionLetStore[ion].letDD[v] >0.) ionLetStore[ion].letDN[v] = ionLetStore[ion].letDN[v] / ionLetStore[ion].letDD[v];
0224 if (ionLetStore[ion].letTD[v] >0.) ionLetStore[ion].letTN[v] = ionLetStore[ion].letTN[v] / ionLetStore[ion].letTD[v];
0225 }
0226 }
0227 }
0228
0229
0230
0231 void HadrontherapyLet::StoreLetAscii()
0232 {
0233 #define width 15L
0234
0235 if(ionLetStore.size())
0236 {
0237 ofs.open(filename, std::ios::out);
0238 if (ofs.is_open())
0239 {
0240
0241
0242 ofs << "i" << '\t' << "j" << '\t' << "k";
0243
0244 ofs << '\t' << "LDT";
0245 ofs << '\t' << "LTT";
0246
0247 for (size_t l=0; l < ionLetStore.size(); l++)
0248 {
0249 G4String a = (ionLetStore[l].isPrimary) ? "_1_D":"_D";
0250 ofs << '\t' << ionLetStore[l].name + a ;
0251 G4String b = (ionLetStore[l].isPrimary) ? "_1_T":"_T";
0252 ofs << '\t' << ionLetStore[l].name + b ;
0253 }
0254
0255
0256
0257
0258 G4AnalysisManager* LetFragmentTuple = G4AnalysisManager::Instance();
0259
0260 LetFragmentTuple->SetVerboseLevel(1);
0261 LetFragmentTuple->SetFirstHistoId(1);
0262 LetFragmentTuple->SetFirstNtupleId(1);
0263 LetFragmentTuple ->OpenFile("Let.csv");
0264
0265
0266 LetFragmentTuple ->CreateNtuple("coordinate", "Let");
0267
0268
0269 LetFragmentTuple ->CreateNtupleIColumn("i");
0270 LetFragmentTuple ->CreateNtupleIColumn("j");
0271 LetFragmentTuple ->CreateNtupleIColumn("k");
0272 LetFragmentTuple ->CreateNtupleDColumn("TotalLetD");
0273 LetFragmentTuple ->CreateNtupleDColumn("TotalLetT");
0274 LetFragmentTuple ->CreateNtupleIColumn("A");
0275 LetFragmentTuple ->CreateNtupleIColumn("Z");
0276 LetFragmentTuple ->CreateNtupleDColumn("IonLETD");
0277 LetFragmentTuple ->CreateNtupleDColumn("IonLETT");
0278 LetFragmentTuple ->FinishNtuple();
0279
0280
0281 for(G4int i = 0; i < numberOfVoxelAlongX; i++)
0282 for(G4int j = 0; j < numberOfVoxelAlongY; j++)
0283 for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
0284 {
0285 LetFragmentTuple->FillNtupleIColumn(1,0, i);
0286 LetFragmentTuple->FillNtupleIColumn(1,1, j);
0287 LetFragmentTuple->FillNtupleIColumn(1,2, k);
0288
0289 G4int v = matrix -> Index(i, j, k);
0290
0291
0292 ofs << G4endl;
0293 ofs << i << '\t' << j << '\t' << k ;
0294 ofs << '\t' << totalLetD[v]/(keV/um);
0295 ofs << '\t' << totalLetT[v]/(keV/um);
0296
0297
0298
0299 for (size_t l=0; l < ionLetStore.size(); l++)
0300 {
0301
0302
0303 if(ionLetStore[l].letDN)
0304 {
0305
0306 ofs << '\t' << ionLetStore[l].letDN[v]/(keV/um) ;
0307 ofs << '\t' << ionLetStore[l].letTN[v]/(keV/um);
0308 }
0309 }
0310
0311 LetFragmentTuple->FillNtupleDColumn(1,3, totalLetD[v]/(keV/um));
0312 LetFragmentTuple->FillNtupleDColumn(1,4, totalLetT[v]/(keV/um));
0313
0314
0315 for (size_t ll=0; ll < ionLetStore.size(); ll++)
0316 {
0317
0318
0319 LetFragmentTuple->FillNtupleIColumn(1,5, ionLetStore[ll].A);
0320 LetFragmentTuple->FillNtupleIColumn(1,6, ionLetStore[ll].Z);
0321
0322
0323 LetFragmentTuple->FillNtupleDColumn(1,7, ionLetStore[ll].letDN[v]/(keV/um));
0324 LetFragmentTuple->FillNtupleDColumn(1,8, ionLetStore[ll].letTN[v]/(keV/um));
0325 LetFragmentTuple->AddNtupleRow(1);
0326 }
0327 }
0328 ofs.close();
0329
0330 LetFragmentTuple->Write();
0331 LetFragmentTuple->CloseFile();
0332 }
0333
0334 }
0335
0336 }
0337