Files
geant4/examples/advanced/dna/dsbandrepair/analysis/repairmodels/src/LEMIVModel.cc
T
2024-12-06 11:11:40 +01:00

210 lines
7.2 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
/// \file LEMIVModel.cc
/// \brief Implementation of the LEMIVModel class
#include "LEMIVModel.hh"
#include "ClassifiedDamage.hh"
#include "Damage.hh"
#include "DamageClassifier.hh"
#include <cmath>
#include <iostream>
#include <fstream>
#include <algorithm>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
LEMIVModel::LEMIVModel(double pLoopLength,double pNi, double pNc,
double pNDSB,double pFunrej,double pTfast,double pTslow):
fLoopLength(pLoopLength),
fNi(pNi),
fNc(pNc),
fNDSB(pNDSB),
fFunrej(pFunrej),
fTfast(pTfast),
fTslow(pTslow)
{
fBpForDSB = 10;
fDefaultsChromosomeSizes={250, 250, 242, 242, 198, 198, 190, 190, 182,
182, 171, 171, 159, 159, 145, 145, 138, 138, 134,
134, 135, 135, 133, 133, 114, 114, 107, 107, 102,
102, 90, 90, 83, 83, 80, 80, 59, 59, 64, 64, 47, 47, 51, 51, 156, 57}; // in Mbp
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
double LEMIVModel::ComputeUnrej(double pTime)
{
double lambdac = (fNDSB-fNi)/fNc;
double Ffast = fNi/fNDSB;
double Fslow = fNc*lambdac/fNDSB;
return Ffast*std::exp(-std::log(2)*pTime/fTfast)+
(Fslow-fFunrej)*std::exp(-std::log(2)*pTime/fTslow)+
fFunrej;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void LEMIVModel::ComputeAndSetDamageInput(std::vector<Damage> vecDamage)
{
double nidsb=0;
double ncdsb=0;
double ndsb=0;
DamageClassifier damclass = DamageClassifier();
auto sortedDamage = damclass.SortDamageByChromo(vecDamage);
// Check chromosome sizes:
if (fChromosomeBpMap.size() == 0) {// using default values
std::cout<<"=====> LEMIV Calculation will Using Default Choromosome sizes"<<std::endl;
for (int ii=0;ii<fDefaultsChromosomeSizes.size();ii++) {
unsigned long long int nBp = fDefaultsChromosomeSizes[ii]*1E6; // convert MBp tp Bp
fChromosomeBpMap.insert({ii,nBp});
}
}
// Loop on each chromosome
int i=0;
for(auto it=sortedDamage.begin();it!=sortedDamage.end();it++)
{
i++;
// Damage are now sorted by event, push all the damage in the same vector
std::vector<Damage> chromoDamage;
for(auto itt=it->second.begin();itt!=it->second.end();itt++)
{
std::move(itt->second.begin(), itt->second.end(), std::back_inserter(chromoDamage));
}
// sort the list of damage by ascending bp
std::sort(chromoDamage.begin(), chromoDamage.end(),
[](const Damage& a, const Damage& b) {
return a.GetCopyNb() < b.GetCopyNb();
});
// for each loop inside the chromosome
auto chromID = it->first;
if (fChromosomeBpMap.find(chromID) == fChromosomeBpMap.end()) {
std::cerr<<"**** Fatal Error *****"<<std::endl;
std::cerr<<"LEMIVModel::ComputeAndSetDamageInput: Cannot find size info for chrom ID "
<<chromID<<std::endl;
std::cerr<<"*************** *****"<<std::endl;
exit(EXIT_FAILURE);
}
for(auto startLoop=0;startLoop<fChromosomeBpMap[chromID];startLoop+=fLoopLength)
{
int n = GetDSBPerLoop(chromoDamage,startLoop);
ndsb+=n;
if(n==1)
nidsb+=1.0;
if(n>=2)
ncdsb+=1.0;
}
}
// Set in the model input parameters
SetNumDSB(ndsb/fDose);
SetNumDomainIsolated(nidsb/fDose);
SetNumDomainClustered(ncdsb/fDose);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int LEMIVModel::GetDSBPerLoop(std::vector<Damage> vecDamage,unsigned int startLoop)
{
// Start to fill a vector with damage having bp between startLopp and startLoop+2Mbp
std::vector<Damage> loopDamage;
for(int i=0;i<vecDamage.size();i++)
{
if((vecDamage[i].GetCopyNb()>startLoop)&&(vecDamage[i].GetCopyNb()<startLoop+fLoopLength))
{
loopDamage.push_back(vecDamage[i]);
}
}
// Make cluster
DamageClassifier dam;
auto classifiedDamage = dam.MakeCluster(loopDamage,fBpForDSB,false);
// Return the number of DSB in this loop
return dam.GetNumDSB(classifiedDamage);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void LEMIVModel::CalculateRepair(double pTMax, double pDeltaT)
{
if (pTMax <= 0.) {
std::cout<<"LEMIVModel::CalculateRepair() wrong value for timeMax !!!\n"
<<"Plese check the input macro file!!!"<<std::endl;
exit(0);
}
if (pDeltaT <= 0.) {
std::cout<<"LEMIVModel::CalculateRepair() wrong value for deltaTime !!!\n"
<<"Plese check the input macro file!!!"<<std::endl;
exit(0);
}
fUCurve.clear();
for(double time=0.;time<=pTMax;time+=pDeltaT)
{
fUCurve.push_back(std::make_pair(time,ComputeUnrej(time)));
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void LEMIVModel::WriteOutput(std::string pFileName)
{
std::fstream file;
file.open(pFileName.c_str(), std::ios_base::out);
//Header part
file <<"#============================================= LEMIV MODEL =============================================#\n";
file << " LEMIV Model, CalculateRepair with:\n";
file << "#Number of DSBs: " << fNDSB * fDose << " DSBs.\n";
file << "#Number of domains with clustered DSB, Nc = " << fNc * fDose << " domains.\n";
file << "#Number of domains with isolated DSB, Ni = " << fNi * fDose<< " domains.\n";
file << "#Funrej = " << fFunrej << "\n";
file << "#Tfast = " << fTfast << " h-1 " << "#Tslow = " << fTslow << " h-1\n";
file << "#LoopLength (length of domain) = " << fLoopLength<<" bp \n";
file <<"#========================================================================================================#\n";
file << "Time (h)\tU\n";
//End Header part
for(int i=0;i<fUCurve.size();i++)
{
file << fUCurve[i].first << "\t" << fUCurve[i].second << "\n";
}
file.close();
}