{ //////////////////////////////////////////// gROOT->Reset(); bool saveImage = true; string imageFileName = "microdosimetricSpectra.png"; bool saveLinearEdep = true; bool saveLogEdep = true; bool saveydySpec = true; //////////////////////////////////////////// //Open File where data has been stored //////////////////////////////////////////// TFile* f = new TFile("radioprotection_t0.root"); TDirectory* dir = (TDirectory*)f->Get("radioprotection_ntuple"); TTree * nEdep = (TTree*)dir->Get("102"); Double_t edep; nEdep->SetBranchAddress("edep", &edep); double meanChordLength = 1; //change based on the thickness of the sensitive volume (make sure to apply a conversion factor if converting to a tissue equivalent material) //////////////////////////////////////////// //Put hits in microdosimeter into linear binned space histogram (typical of experimental setup) //////////////////////////////////////////// int numberLinearBins = 4096; double minLinealEnergy = 0; double maxLinealEnergy = 1000; TH1D* histoLin = new TH1D("h1", "f(y)", numberLinearBins, minLinealEnergy, maxLinealEnergy); TH1D* histoYFY = new TH1D("h2", "yf(y)", numberLinearBins, minLinealEnergy, maxLinealEnergy); TH1D* histoDY = new TH1D("h3", "d(y)", numberLinearBins, minLinealEnergy, maxLinealEnergy); //////////////////////////////////////////// //Create log bin for microdosimetric plotting //////////////////////////////////////////// //Log bin stuff int B = 20; //the number of increments in each decade //eg if B = 10: 1 2 3 ... 9 10 20 30 ... 90 100 200 ... double yMin = 0.01; // y = lineal energy double yMax = 1000; double range = yMax / yMin; double fooRange = range; double fooMag = 10; //any old silly no > 1 int order = 0; while (fooMag > 1) { fooMag = fooRange / 10 ; fooRange = fooRange / 10 ; order = order + 1 ; } int binsPerDecade = B; const int numberOfLogBins = binsPerDecade * order +1; //get the total number of bins vector xbins; for (int b = 0; b < numberOfLogBins; b++) { xbins.push_back((yMin)*pow(10, ((b) / double(B)))); // cout << b << " " << xbins[b] << endl; } TH1D* histoLog = new TH1D("l1", "edepLin", (numberOfLogBins-1), &xbins[0]); //////////////////////////////////////////// //loop through the hits in the detector stored in the ntuple //////////////////////////////////////////// int numberHits = nEdep->GetEntries(); cout << "Number of hits in detector = " << numberHits << endl; for (int i = 0; i < numberHits; i++) { nEdep->GetEntry(i); if (edep <= 0) { cout << "Edep = 0" << endl; } histoLin->Fill(edep/meanChordLength); histoLog->Fill(edep/meanChordLength); } //////////////////////////////////////////// //Normalise the log histogram based on the bin width //////////////////////////////////////////// for (int bb = 1; bb <= numberOfLogBins-1; bb++) { histoLog->SetBinContent(bb, (histoLog->GetBinContent(bb) / histoLog->GetBinWidth(bb))); } //////////////////////////////////////////// //---------Save values to file-------------- //////////////////////////////////////////// ofstream outFile; if (saveLinearEdep) { outFile.open("linEdepSpec.txt"); for (int i = 1 ; i <= numberLinearBins; i++) { outFile << histoLin->GetBinCenter(i) * meanChordLength << "\t" << histoLin->GetBinContent(i) << endl; } outFile.close(); } if (saveLogEdep) { outFile.open("logEdepSpec.txt"); for (int bb = 1; bb <= numberOfLogBins-1; bb++) { outFile << histoLog->GetBinCenter(bb) * meanChordLength << "\t" << histoLog->GetBinContent(bb) << endl; } outFile.close(); } //////////////////////////////////////////// //----------Normalise Histo to get f(y)---- //////////////////////////////////////////// double intOfHist = histoLin->Integral("width") ; //gets counts in each histogram and multiplies by bin width histoLin->Scale(1./intOfHist); //histoLin->Sumw2(); double intOfLogHist = histoLog->Integral("width") ; histoLog->Scale(1./intOfLogHist); //histoLog->Sumw2(); ////////////////////////////////////////////////////////////// //-------Calculate RBE using the modified MK model----------- ///////////////////////////////////////////////////////////// //Technically the use of the modified MKM is applied in //therapeutic ion beams and not used for radioprotection applications //though it is included here for convience. //NOTE: the form used here is for "heavy ions" and not applicable //to the more dose depedent protons //--------------------------------- //Constants //--------------------------------- const double satPar = 150.; //saturation paramater obv. in keV/um double satParSqr = satPar * satPar; const double pi = 3.14159265359; const double SiToMuscleCorrection = 0.57; //Cell reltated numbers double alpha0 = 0.13;//0.164;//0.13; //Gy^-1 //0.13 for carbon double beta = 0.05; //Gy^-2 double rho = 1.; //g/cm^3 double rSV = 0.42; //um, the radius of the HSG cell //----------------------------------------------------------- //In order for consistent units, which in their raw form are: //(1/(Gy^2))(keV/g)(cm^3/um^3) // (1/Gy^2)(keV/um)(cm^3/g)(1/um^2) //------------------------------------------------------------ //So convert (keV/g) into Gy it is scaled by (1.602E-16/0.001)(J/kg) //And to get cm^3 into um^3 just scale by 10E12 //------------------------------------------------------------ double scaleGray = 1.602E-16/0.001; double scaleLength = 1.E12; //-------Calculate y*-------- double topIntegral = 0.; double botIntegral = 0.; //top integral for (Int_t i = 1; i <= numberLinearBins; i++) { topIntegral += (1 - exp(-(histoLin->GetBinCenter(i) * histoLin->GetBinCenter(i)) / satParSqr))*histoLin->GetBinContent(i) * histoLin->GetBinWidth(i); // (1 - exp(-y^2/y_{0}^2)) * f(y) * dy } //bottom integral for (Int_t i = 1; i <= numberLinearBins; i++) { botIntegral += (histoLin->GetBinCenter(i) * histoLin->GetBinContent(i) * histoLin->GetBinWidth(i)); // y (size of each being time bin number) * f(y) * dy (bin size) } //cout << "Top: " << topIntegral << endl; //cout << "Bot: " << botIntegral << endl; //saturation corrected dose averaged linel energy value (y*) double satCor = satParSqr * topIntegral / botIntegral; //(y_{0})^2*top/bottom //cout << "--------------------------------" << endl; //cout << "y* = " << satCor << endl; //cout << "--------------------------------" << endl; //-----------alpha-------- double alpha = alpha0 + (beta / (rho*pi*rSV*rSV))*satCor*scaleGray*scaleLength; //cout << "alpha = " << alpha << endl; //-----------finally RBE itself-------- double ln01 = -2.302585093; double RBE10;//= (2*beta*5.)((sqrt(alpha*alpha - 4*beta*ln01) - alpha)); double topRBE = (2 * beta*5.); double botRBE = (sqrt(alpha*alpha - 4 * beta*ln01) - alpha); RBE10 = topRBE / botRBE; //cout << "--------------------------------" << endl; cout << "RBE10 = " << RBE10 << endl; //cout << "--------------------------------" << endl; //////////////////////////////////////////// //-----------Calculate yF------------------- //////////////////////////////////////////// //yF = int(y * f(y) dy) double linyF = 0.; for (int i = 1 ; i <= numberLinearBins; i++) { linyF += histoLin->GetBinCenter(i) * histoLin->GetBinContent(i) * histoLin->GetBinWidth(i) ; } cout << "yF = " << linyF << endl; double logyF = 0; for (int i = 1 ; i <= numberOfLogBins; i++) { logyF += histoLog->GetBinCenter(i) * histoLog->GetBinContent(i) * histoLog->GetBinWidth(i) ; } cout << "Log yF = " << logyF << endl; //////////////////////////////////////////// //--------------Calculate d(y)-------------- //////////////////////////////////////////// //d(y) = y*f(y) / yF for (int i = 1 ; i <= numberLinearBins; i++) { histoLin->SetBinContent(i, (histoLin->GetBinCenter(i) * histoLin->GetBinContent(i) / linyF)); } //check that it's normalised to 1 double intOfHistDy = histoLin->Integral("width") ; cout << "Int of d(y) = " << intOfHistDy << endl; for (int bb = 1; bb <= numberOfLogBins-1; bb++) { histoLog->SetBinContent(bb, (histoLog->GetBinCenter(bb)* histoLog->GetBinContent(bb) / logyF)); } double intOfHistLogDy = histoLog->Integral("width") ; cout << "Int of log d(y) = " << intOfHistLogDy << endl; //////////////////////////////////////////// //-------Calculate Average Q(y)----------- //////////////////////////////////////////// //Q(y) = (a1/y)[1-exp(-(a2)y*y - (a3)y*y*y)] //Quality factor values from ICRP 60 report double qualityCoeff1 = 5510.; double qualityCoeff2 = 5.E-5; double qualityCoeff3 = 2.E-7; double aveQuality = 0.; //AveQuality = int(Q(y)d(y)dy) for (int i = 1 ; i <= numberLinearBins; i++) { aveQuality += (qualityCoeff1/histoLin->GetBinCenter(i))* (1 - exp(-qualityCoeff2*pow(histoLin->GetBinCenter(i), 2.)-qualityCoeff3*pow(histoLin->GetBinCenter(i), 3.)))* histoLin->GetBinContent(i)* histoLin->GetBinWidth(i) ; } cout << " = " << aveQuality << endl; //////////////////////////////////////////// //---------Calculate yD-------------------- //////////////////////////////////////////// //yD = int (y * d(y) dy) double linyD = 0.; for (int i = 1 ; i <= numberLinearBins; i++) { linyD += histoLin->GetBinCenter(i) * histoLin->GetBinContent(i) * histoLin -> GetBinWidth(i) ; } cout << "yD = " << linyD << endl; double logyD = 0.; for (int bb = 1; bb <= numberOfLogBins-1; bb++) { logyD += histoLog->GetBinCenter(bb) * histoLog->GetBinContent(bb) * histoLog -> GetBinWidth(bb) ; } cout << "log yD = " << logyD << endl; //////////////////////////////////////////// //---------Create yd(y)------------------- //////////////////////////////////////////// for (int bb = 1; bb <= numberOfLogBins-1; bb++) { histoLog->SetBinContent(bb, (histoLog->GetBinCenter(bb)* histoLog->GetBinContent(bb)) ); } //Scale bins by log(10)/B //See Appendix B of the ICRU 36 report for more details histoLog->Scale((log(10) / B)); if (saveydySpec) { outFile.open("logYDYspec.txt"); for (int bb = 1; bb <= numberOfLogBins-1; bb++) { outFile << histoLog->GetBinCenter(bb) << "\t" << histoLog->GetBinContent(bb) << endl; } outFile.close(); } if (saveImage) { TCanvas *c1 = new TCanvas("c1", "", 1000, 800); //gStyle->SetOptStat(0); //un-comment to remove stat box on top right histoLog->SetTitle(""); histoLog->GetXaxis()->SetTitle("y (keV/#mum)"); histoLog->GetYaxis()->SetTitle("yd(y)"); histoLog->GetYaxis()->SetLabelFont(42); histoLog->GetXaxis()->SetLabelFont(42); histoLog->GetYaxis()->SetTitleFont(42); histoLog->GetXaxis()->SetTitleFont(42); histoLog->GetYaxis()->CenterTitle(1); histoLog->GetXaxis()->CenterTitle(1); histoLog->GetXaxis()->SetTitleSize(0.045); histoLog->GetYaxis()->SetTitleSize(0.045); //histoLog->GetYaxis()->SetRangeUser(0., 1.8); //histoLog -> GetXaxis()->SetRangeUser(0.01., 1000.); histoLog->GetYaxis()->SetLabelSize(0.04); histoLog->GetXaxis()->SetLabelSize(0.04); histoLog->SetLineColor(1); histoLog->SetLineWidth(4); c1->SetLogx(); //c1->SetLogy(); //Plotting misbehaves in root6.XX histoLog->Draw(""); c1->SaveAs(imageFileName.c_str()); } }