Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 09:21:59

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 //
0027 /// \file ScanDamage.cc
0028 /// \brief Implementation of the ScanDamage class
0029 
0030 #include "ScanDamage.hh"
0031 
0032 #include "TSystemDirectory.h"
0033 #include "TFile.h"
0034 #include "TTree.h"
0035 #include "TRandom.h"
0036 
0037 
0038 #include <iostream>
0039 #include <fstream>
0040 #include <sstream>
0041 #include <iostream>
0042 #include <filesystem>
0043 namespace fs = std::filesystem;
0044 TRandom gRandomGen; 
0045 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0046 
0047 ScanDamage::ScanDamage(): fSkipScanningIndirectDamage(false)
0048 {
0049     fThresholdEnergy = 17.5; //eV
0050     fEdepSumInNucleus = 0;
0051     fProbabilityForIndirectSB = 0.40; // 40%
0052 }
0053 
0054 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0055 
0056 std::map<unsigned int,std::map<unsigned int,std::vector<Damage> > > ScanDamage::ExtractDamage(){
0057     ReadCellandVoxelDefFilePaths();
0058     fMergedTables.clear();
0059     fDamage.clear();
0060     RetrieveVoxelBp();
0061     FillVoxelData();
0062     ScanDamageFromPhys();
0063     if (!fSkipScanningIndirectDamage) ScanDamageFromChem();
0064     MergeDamageFromPhysChem();
0065     for (const auto& [pChrom,table] : fMergedTables) {
0066         unsigned int evt;
0067         unsigned int strand;
0068         ullint cpyNb;
0069         unsigned int isBase;
0070         double time;
0071         double edep;
0072         double origin;
0073         Damage::DamageType pType;
0074         Damage::DamageCause pOrigin;
0075         std::map<unsigned int,std::vector<Damage> > perChromoDamage;
0076         for (const auto& v : table) {
0077             evt = v.at(0);
0078             strand = v.at(1);
0079             cpyNb = v.at(2);
0080             isBase = v.at(3);
0081             time = v.at(4);
0082             edep = v.at(5);
0083             origin = v.at(6);
0084             if(isBase==0)
0085                 pType=Damage::DamageType::fBackbone;
0086             else
0087                 pType=Damage::DamageType::fBase;
0088             if(origin==0)
0089                 pOrigin=Damage::DamageCause::fDirect;
0090             else
0091                 pOrigin=Damage::DamageCause::fIndirect;
0092             if (perChromoDamage.find(evt) == perChromoDamage.end()) {
0093                 std::vector<Damage> dm{Damage(pType,pChrom,evt,strand,cpyNb,Position(0,0,0),
0094                                             pOrigin,Damage::DamageChromatin::fUnspecified)};
0095                 perChromoDamage.insert({evt,dm});
0096             } else perChromoDamage[evt].push_back(Damage(pType,pChrom,evt,strand,cpyNb,Position(0,0,0),
0097                                             pOrigin,Damage::DamageChromatin::fUnspecified));
0098         }
0099         fDamage.insert({pChrom,perChromoDamage});
0100     }
0101     return fDamage;
0102 }
0103 
0104 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0105 
0106 void ScanDamage::RetrieveVoxelBp()
0107 {
0108     fBpPerVoxel.clear();
0109     
0110     for (const auto & entry : fVoxelDefFilesList) {
0111         std::ifstream file(entry);
0112         if(!file.good() )
0113         {
0114             std::cerr<<"**** Fatal Error *****"<<std::endl;
0115             std::cerr<<"ScanDamage::RetrieveVoxelBp: No file named "<<entry<<std::endl;
0116             std::cerr<<"*************** *****"<<std::endl;
0117             exit(EXIT_FAILURE);
0118         }
0119         std::string voxelName = "noName";
0120         std::string line;
0121         bool foundName = false;
0122         bool foundNumOfBp = false;
0123         while(std::getline(file, line)
0124             && !foundNumOfBp)
0125         {
0126             std::istringstream iss(line);
0127             std::string flag;
0128             iss >> flag;
0129             std::string charac;
0130             iss >> charac;
0131             // Look for the name of the voxel
0132             if(flag=="_Name")
0133             {
0134                 voxelName = charac;
0135                 foundName = true;
0136             }
0137             // Look for the flag "_Number"
0138             // And the characteristic "voxelBasePair"
0139             if(flag=="_Number" && charac=="voxelBasePair")
0140             {
0141                 int numOfBp;
0142                 iss >> numOfBp;
0143                 if(!foundName)
0144                 {
0145                     std::cerr<<"*** Fatal Error ***"<<std::endl;
0146                     std::cerr<<"ScanDamage::RetrieveVoxelBp: The number of bp was found before the name "
0147                     <<"of the voxel... This is an unexpected case."<<std::endl;
0148                     std::cerr<<"******"<<std::endl;
0149                     exit(EXIT_FAILURE);
0150                 }
0151                 else
0152                 {
0153                     fBpPerVoxel[voxelName] = numOfBp;
0154                     std::cout<<voxelName<<" has "<<numOfBp<<" bp"<<std::endl;
0155                     foundNumOfBp = true;
0156                 }
0157             }
0158         }
0159         file.close();
0160     }
0161     
0162     if (fBpPerVoxel.size() == 0) {
0163         std::cerr<<"**** Fatal Error *****"<<std::endl;
0164         std::cerr<<"ScanDamage::RetrieveVoxelBp: No Bp found in voxel definition files. \n Or make"
0165         <<" sure that file imp.info exists in working directory!"<<std::endl;
0166         std::cerr<<"*************** *****"<<std::endl;
0167         exit(EXIT_FAILURE);
0168     }
0169 }
0170 
0171 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0172 
0173 void ScanDamage::FillVoxelData()
0174 {   
0175     std::ifstream file(fCellDefFilePath);
0176     if(!file.good() )
0177     {
0178         std::cerr<<"**** Fatal Error *****"<<std::endl;
0179         std::cerr<<"FillVoxelData: No file named "<<fCellDefFilePath<<std::endl;
0180         std::cerr<<"*************** *****"<<std::endl;
0181         exit(EXIT_FAILURE);
0182     }
0183     ullint bpCount = 0;
0184     unsigned int voxelCount = 0;
0185     int chromo_previous = 0;
0186     // Read the file line by line
0187     std::string line;
0188     while(std::getline(file, line) )
0189     {
0190         std::istringstream iss(line);
0191         std::string flag;
0192         iss >> flag;
0193         // If the flag correspond to the placement of a voxel
0194         if(flag == "_pl")
0195         {
0196             std::string voxelName;
0197             iss >> voxelName;
0198             int chromo;
0199             iss >> chromo;
0200             int domain;
0201             iss >> domain;
0202             // If we change of chromosome then reset the number of bp.
0203             // Each chromosome starts at 0 bp.
0204             if(chromo != chromo_previous)
0205             {
0206                 bpCount = 0;
0207                 chromo_previous = chromo;
0208             }
0209             // Fill the data structure
0210             fVoxels.push_back( VoxelData(chromo, domain, bpCount) );
0211             int numBpinthisvoxel = int(fBpPerVoxel[voxelName]);
0212             bpCount += numBpinthisvoxel;
0213             if (fChromosomeBpMap.find(chromo) == fChromosomeBpMap.end()) {
0214                 fChromosomeBpMap.insert({chromo,numBpinthisvoxel});
0215             } else {
0216                 fChromosomeBpMap[chromo] += numBpinthisvoxel;
0217             }
0218             voxelCount++;
0219         }
0220     }
0221     file.close();
0222     
0223 
0224     if (fVoxels.size() == 0) {
0225         std::cerr<<"**** Fatal Error *****"<<std::endl;
0226         std::cerr<<"ScanDamage::FillVoxelData: NofVoxels info found in files "<<fCellDefFilePath<<std::endl;
0227         std::cerr<<"*************** *****"<<std::endl;
0228         exit(EXIT_FAILURE);
0229     }
0230     std::cout<<"Num of voxels: "<< fVoxels.size()<<" placed in Cell Nucleus."<<std::endl;
0231     std::cout<<"=====Choromosome sizes====="<<std::endl;
0232     std::cout<<"Chromosome ID\t Number of Bp"<<std::endl;
0233     for (auto const& [chrom, nBp] : fChromosomeBpMap) {
0234          std::cout<<chrom<< "\t"<<nBp<<std::endl;
0235     }
0236     std::cout<<"==========================="<<std::endl;
0237 }
0238 
0239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0240 
0241 void ScanDamage::ScanDamageFromPhys()
0242 {
0243     std::cout<<"===== Start Scanning Damages From Phys =====\n";
0244     fEdepSumInNucleus = 0;
0245     fphysTables.clear();
0246     fphysSlectedTables.clear();
0247     fs::path currentP{"phys_output"};
0248     fs::file_status s = fs::file_status{};
0249     auto isExist = fs::status_known(s) ? fs::exists(s) : fs::exists(currentP);
0250     if (isExist) {
0251         bool isFoundRootFiles = false;
0252         for (const auto entry : fs::directory_iterator(currentP)) {
0253             if (entry.path().extension() == ".root") {
0254                 std::cout <<"ScanDamageFromPhys(): Processing file: "<< entry.path().filename()<< std::endl;
0255                 AnaPhysRootFile(entry.path());
0256                 if (!isFoundRootFiles) isFoundRootFiles=true;
0257             }
0258         }
0259         if (!isFoundRootFiles) {
0260             std::cout<<"=====>> No root files found in folder \"phys_ouput\"!!! Skip Scanning Damages From Phys =====\n";
0261         }
0262         if (fphysTables.size() > 0) {
0263             SortPhysTableWithSelection();
0264         }
0265     } else {
0266         std::cout<<"=====>> Cannot find folder \"phys_ouput\"!!! Skip Scanning Damages From Phys =====\n";
0267     }
0268 
0269     std::cout<<"===== End Scanning Damages From Phys =====\n";
0270 }
0271 
0272 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0273 
0274 void ScanDamage::ScanDamageFromChem()
0275 {
0276     std::cout<<"===== Start Scanning Damages From Chem =====\n";
0277     fs::path currentP{"chem_output"};
0278     fs::file_status s = fs::file_status{};
0279     auto isExist = fs::status_known(s) ? fs::exists(s) : fs::exists(currentP);
0280     if (isExist) {
0281         bool isFoundRootFiles = false;
0282         for (const auto entry : fs::directory_iterator(currentP)) {
0283             if (entry.path().extension() == ".root") {
0284                 AnaChemRootFile(entry);
0285                 if (!isFoundRootFiles) isFoundRootFiles=true;
0286             }
0287         }
0288         if (!isFoundRootFiles) {
0289             std::cout<<"=====>> No root files found in folder \"chem_ouput\"!!! Skip Scanning Damages From Chem =====\n";
0290             fSkipScanningIndirectDamage = true;
0291         }
0292         if (fchemTables.size() > 0) {
0293             SortChemTableWithSelection();
0294         }
0295     } else {
0296         std::cout<<"=====>> Cannot find folder \"chem_ouput\"!!! Skip Scanning Damages From Chem =====\n";
0297         fSkipScanningIndirectDamage = true;
0298     }
0299     
0300     std::cout<<"===== End Scanning Damages From Chem =====\n";
0301 }
0302 
0303 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0304 
0305 void ScanDamage::AnaPhysRootFile(const std::string fileName)
0306 {
0307     TFile* f = new TFile(fileName.c_str());
0308     if(f->IsZombie() ){
0309         // File is corrupted
0310         std::cerr<<"*********** Warning *************"<<std::endl;
0311         std::cerr<<"The file "<<fileName<<" seems to be corrupted..."<<std::endl;
0312         std::cerr<<"We will skip it."<<std::endl;
0313         std::cerr<<"**********************************"<<std::endl;
0314         return;
0315     }
0316     AnaPhysRootTree1(f);
0317     AnaPhysRootTree2(f);
0318     f->Close();
0319 }
0320 
0321 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0322 
0323 void ScanDamage::AnaChemRootFile(fs::directory_entry entry)
0324 {
0325     std::string fnameWithoutExtension = entry.path().stem().string();
0326     auto [eventNumber, voxelNumber] = GetEventNberAndVoxelNberFromChemRoot(fnameWithoutExtension);
0327     
0328     // Voxel data retrieval
0329     VoxelData& voxelData = fVoxels.at(voxelNumber);
0330 
0331     int chromo = voxelData.fChromosome;
0332     ullint firstBpNum = voxelData.fFirstBpCopyNum;
0333     // *******************
0334     // Analyse of the ntuple to detect SB and associate them with a bpNumCorrected
0335     // *******************
0336 
0337     // Load the file, the directory and the ntuple
0338     TFile f(entry.path().c_str());
0339     if(f.IsZombie() ){
0340         corruptedFiles++;
0341         // File is corrupted
0342         std::cerr<<"*********** Warning *************"<<std::endl;
0343         std::cerr<<"The file "<<entry.path().string()<<" seems to be corrupted..."<<std::endl;
0344         std::cerr<<"We will skip it."<<std::endl;
0345         std::cerr<<"Number of corrupted files: "<< corruptedFiles<<std::endl;
0346         std::cerr<<"**********************************"<<std::endl;
0347     } else {
0348         TDirectoryFile *d = dynamic_cast<TDirectoryFile*> (f.Get("ntuple") );
0349         TTree* chemTree = (TTree*) d->Get("ntuple_2");
0350 
0351         if( (int) chemTree->GetEntries() >0)
0352         {
0353             double strand;
0354             double copyNumber;
0355             double xp;
0356             double yp;
0357             double zp;
0358             double time;
0359             double base;
0360             chemTree->SetBranchAddress("strand", &strand);
0361             chemTree->SetBranchAddress("copyNumber", &copyNumber);
0362             chemTree->SetBranchAddress("xp", &xp);
0363             chemTree->SetBranchAddress("yp", &yp);
0364             chemTree->SetBranchAddress("zp", &zp);
0365             chemTree->SetBranchAddress("time", &time);
0366             chemTree->SetBranchAddress("base", &base);
0367             unsigned int entryNumber = (int) chemTree->GetEntries();
0368             for (unsigned int e=0;e<entryNumber;e++)
0369             {
0370                 chemTree->GetEntry(e);
0371                 ullint cpNumCorrected = firstBpNum+int(copyNumber);
0372                 std::vector<ullint> newLine{ 
0373                     (ullint)eventNumber,(ullint)strand,cpNumCorrected,
0374                     (ullint)base,(ullint)(time*1000000)};
0375                 auto itr = fchemTables.find(chromo);
0376                 if ( itr == fchemTables.end()) {
0377                     Table tbforThisChro{newLine};
0378                     fchemTables.insert({chromo,tbforThisChro});
0379                 } else (itr->second).push_back(newLine);
0380             }
0381         }
0382     }//
0383 }
0384 
0385 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0386 
0387 std::tuple<unsigned int, unsigned int> ScanDamage::GetEventNberAndVoxelNberFromChemRoot(
0388     const std::string fileNameWithoutExtension)
0389 {
0390     unsigned int evnN, volxelN;
0391     auto fristPos = fileNameWithoutExtension.find_first_of("_");
0392     auto secondPos = fileNameWithoutExtension.substr(fristPos+1).find_first_of("_");
0393     auto lastPos = fileNameWithoutExtension.find_last_of("_");
0394     evnN = std::stoul(fileNameWithoutExtension.substr(fristPos+1,secondPos));
0395     volxelN = std::stoul(fileNameWithoutExtension.substr(lastPos+1));
0396     return  {evnN, volxelN};
0397 }
0398 
0399 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0400 
0401 void ScanDamage::AnaPhysRootTree1(TFile* f)
0402 {
0403     TDirectoryFile* d = dynamic_cast<TDirectoryFile*> (f->Get("ntuple") );
0404     TTree* tPhys = dynamic_cast<TTree*> (d->Get("ntuple_1") );
0405 
0406     if( tPhys->GetEntries()  > 0)
0407         {
0408         double flagParticle;
0409         double flagParentID;
0410         double flagProcess;
0411         double x;
0412         double y;
0413         double z;
0414         double edep;
0415         double eventNumber;
0416         double volumeName;
0417         double copyNumber;
0418         double lastMetVoxelCopyNum;
0419 
0420         tPhys->SetBranchAddress("flagParticle", &flagParticle);
0421         tPhys->SetBranchAddress("flagParentID", &flagParentID);
0422         tPhys->SetBranchAddress("flagProcess", &flagProcess);
0423         tPhys->SetBranchAddress("x", &x);
0424         tPhys->SetBranchAddress("y", &y);
0425         tPhys->SetBranchAddress("z", &z);
0426         tPhys->SetBranchAddress("edep", &edep);
0427         tPhys->SetBranchAddress("eventNumber", &eventNumber);
0428         tPhys->SetBranchAddress("volumeName", &volumeName);
0429         tPhys->SetBranchAddress("copyNumber", &copyNumber);
0430         tPhys->SetBranchAddress("lastMetVoxelCopyNum", &lastMetVoxelCopyNum);
0431 
0432         unsigned int entryNumber =  tPhys->GetEntries() ;
0433 
0434         // Loop on all the "lines" (ie entry) of the ntuple
0435         for(unsigned int e=0; e<entryNumber; e++)
0436         {
0437             // Set all the variables to the values corresponding to the entry number
0438             tPhys->GetEntry(e);
0439             // Check if the process is an ionisation
0440             // Only ionisation should trigger the removal of a DNA molecule from the chemical step
0441             if(flagProcess == 13 // e-_DNAIonisation
0442                     || flagProcess == 113 // e-_DNAPTBIonisation
0443                     || flagProcess == 18 // proton_DNAIonisation
0444                     || flagProcess == 21 // hydrogen_DNAIonisation
0445                     || flagProcess == 24 // alpha_DNAIonisation
0446                     || flagProcess == 27 // alpha+_DNAIonisation
0447                     || flagProcess == 31 // helium_DNAIonisation
0448                     || flagProcess == 12 // e-_DNAExcitation
0449                     || flagProcess == 112 // e-_DNAPTBExcitation
0450                     || flagProcess == 15 // e-_DNAVibExcitation
0451                     || flagProcess == 17 // proton_DNAExcitation
0452                     || flagProcess == 20 // hydrogen_DNAExcitation
0453                     || flagProcess == 23 // alpha_DNAExcitation
0454                     || flagProcess == 26 // alpha+_DNAExcitation
0455                     || flagProcess == 30 // helium_DNAExcitation
0456                     ) {
0457                 // Check the interaction happened in a dna molecule or its hydration shell
0458                 if(volumeName == 1 // d1
0459                         || volumeName == 11 // p1
0460                         || volumeName == 2 // d2
0461                         || volumeName == 22 // p2
0462                         || volumeName == 7 // d1_w
0463                         || volumeName == 71 // p1_w
0464                         || volumeName == 8 // d2_w
0465                         || volumeName == 81 // p2_w
0466                         )
0467                 {
0468                     // *************
0469 
0470                     // Retrieve the voxel copy number
0471                     double voxelCopyNumber  = lastMetVoxelCopyNum;
0472                     if (voxelCopyNumber >= 0 && voxelCopyNumber<fVoxels.size()){
0473                         // Chromosome, domain and firstNucleotideNum
0474                         const VoxelData& voxelData = fVoxels.at(size_t(voxelCopyNumber) );
0475                         int chromo = voxelData.fChromosome;
0476                         int domain = voxelData.fDomain;
0477                         ullint firstBpCN = voxelData.fFirstBpCopyNum;
0478                         ullint cpNumCorrected = firstBpCN+int(copyNumber);
0479 
0480                         // Get the event number
0481                         double eventNum = eventNumber;
0482 
0483                         // Determine the strand
0484                         double strand (-1);
0485                         if(volumeName==1
0486                                 || volumeName==11
0487                                 || volumeName==7
0488                                 || volumeName==71
0489                                 || volumeName==6 // ade
0490                                 || volumeName==9 // ade
0491                                 || volumeName==4 // gua
0492                                 || volumeName==10) // gua
0493                             strand = 1;
0494                         else if(volumeName==2
0495                                 || volumeName==22
0496                                 || volumeName==8
0497                                 || volumeName==81
0498                                 || volumeName==5 // thy
0499                                 || volumeName==12 // thy
0500                                 || volumeName==3 // cyto
0501                                 || volumeName==13) // cyto
0502                             strand = 2;
0503                         // Check if the chromo has already been registered
0504                         std::vector<ullint> newLine{ 
0505                             (ullint)eventNum,(ullint)strand,cpNumCorrected,
0506                             (ullint)volumeName,(ullint)flagProcess,(ullint)(edep*1000000)};
0507                             // *1000000 in edep is taken back after. This is done 
0508                             // because the number is "unsigned long long int" instead of "double".
0509                         auto itr = fphysTables.find(chromo);
0510                         if ( itr == fphysTables.end()) {
0511                             Table tbforThisChro{newLine};
0512                             fphysTables.insert({chromo,tbforThisChro});
0513                         } else (itr->second).push_back(newLine);
0514                     }
0515                 }
0516             }
0517         }
0518     }
0519 }
0520 
0521 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0522 
0523 void ScanDamage::AnaPhysRootTree2(TFile* f)
0524 {
0525     TDirectoryFile* d2 = dynamic_cast<TDirectoryFile*> (f->Get("ntuple") );
0526     TTree* tPhys2 = dynamic_cast<TTree*> (d2->Get("ntuple_3") );
0527 
0528     if( int(tPhys2->GetEntries() ) > 0)
0529     {
0530         double edep;
0531         double eventNumber;
0532 
0533         tPhys2->SetBranchAddress("edep", &edep);
0534         tPhys2->SetBranchAddress("eventNumber", &eventNumber);
0535 
0536         unsigned int entryNumber = int( tPhys2->GetEntries() );
0537 
0538         // Loop on all the "lines" (ie entry) of the ntuple
0539         for(unsigned int e=0; e<entryNumber; e++)
0540         {
0541             tPhys2->GetEntry(e);
0542             fEdepSumInNucleus += edep;
0543         }
0544     }
0545 }
0546 
0547 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0548 
0549 void ScanDamage::SortPhysTableWithSelection()
0550 {
0551     for(const auto [chrom, physTable] : fphysTables)
0552     {
0553         // Final table
0554         Table physTableWithSelection;
0555 
0556         std::map<ullint,std::map<ullint,std::map<ullint, ullint > > > energyMap;
0557         
0558         // Loop on all the lines of the table
0559         for(unsigned int line=0, eline=physTable.size(); line<eline; ++line)
0560         {
0561             ullint eventNum = physTable[line][0];
0562             ullint strand = physTable[line][1];
0563             ullint copyNumber = physTable[line][2];
0564             ullint volumeFlag = physTable[line][3];
0565             ullint processFlagr = physTable[line][4];
0566             ullint energy = physTable[line][5];
0567 
0568             // Cumulate the energy value
0569             energyMap[eventNum][strand][copyNumber] += energy;
0570         }
0571 
0572         int notDuplicatedLine = 0;
0573 
0574         // Loop on all the events
0575         std::map<ullint, std::map<ullint, std::map<ullint, ullint> > >::iterator iit = energyMap.begin();
0576         std::map<ullint, std::map<ullint, std::map<ullint, ullint> > >::iterator iite = energyMap.end();
0577         for(; iit!=iite;++iit)
0578         {
0579             ullint eventNum = iit->first;
0580 
0581             // Loop on all the strands
0582             std::map<ullint, std::map<ullint, ullint> >::iterator itt = iit->second.begin();
0583             std::map<ullint, std::map<ullint, ullint> >::iterator itte = iit->second.end();
0584             for(; itt!=itte;++itt)
0585             {
0586                 ullint strand = itt->first;
0587                 // Loop on all the copy numbers
0588                 std::map<ullint, ullint>::iterator ittt = itt->second.begin();
0589                 std::map<ullint, ullint>::iterator ittte = itt->second.end();
0590                 for(; ittt!=ittte;++ittt)
0591                 {
0592                     ullint copyNumber = ittt->first;
0593                     double currentE = double(ittt->second) / 1000000; // eV
0594                     // Energy condition(s) are set here
0595                     bool fill = false;                  
0596                      // Threshold condition
0597                      if(currentE < fThresholdEnergy)
0598                           fill=false;
0599                      else
0600                           fill=true;
0601 
0602                     if(fill)
0603                     {
0604                         // Add a line
0605                         physTableWithSelection.push_back(std::vector<ullint>());
0606                         // Fill the line
0607                         physTableWithSelection[notDuplicatedLine].push_back(eventNum);
0608                         physTableWithSelection[notDuplicatedLine].push_back(strand);
0609                         physTableWithSelection[notDuplicatedLine].push_back(copyNumber);
0610                         physTableWithSelection[notDuplicatedLine].push_back(0);
0611                         physTableWithSelection[notDuplicatedLine].push_back(0);
0612                         physTableWithSelection[notDuplicatedLine].push_back((ullint)(currentE*1000000) );
0613                         physTableWithSelection[notDuplicatedLine].push_back(0);
0614                         ++notDuplicatedLine;
0615                     }
0616                 }
0617             }
0618         }
0619         // *******************************************
0620         // Print the "physTableWithSelection" table for the current chromosome
0621         // *******************************************
0622         std::cout << "### Phys SB for chromosome "<<chrom<<" : " << physTableWithSelection.size() << " ###" << std::endl;
0623         if (physTableWithSelection.size()>0) fphysSlectedTables.insert({chrom,physTableWithSelection});
0624     }
0625     fphysTables.clear();//Free memory
0626 }
0627 
0628 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0629 
0630 void ScanDamage::SortChemTableWithSelection()
0631 {
0632     for (const auto& [chromo,chemTable] : fchemTables)
0633     {
0634         // Final table
0635         Table chemTableWithSelection;
0636         
0637         int notDuplicatedLine = 0;
0638 
0639         for(unsigned int line=0, eline=chemTable.size(); line<eline; ++line)
0640         {
0641             ullint eventNum = chemTable[line][0];
0642             ullint strand = chemTable[line][1];
0643             ullint copyNumber = chemTable[line][2];
0644             ullint base = chemTable[line][3];
0645             ullint time = chemTable[line][4];
0646         
0647             // Random number between 0 and <1
0648             if (base==1) {
0649                 // Add a line
0650                 chemTableWithSelection.push_back(std::vector<ullint>());
0651                 // Fill the line
0652                 chemTableWithSelection[notDuplicatedLine].push_back(eventNum);
0653                 chemTableWithSelection[notDuplicatedLine].push_back(strand);
0654                 chemTableWithSelection[notDuplicatedLine].push_back(copyNumber);
0655                 chemTableWithSelection[notDuplicatedLine].push_back(base);
0656                 chemTableWithSelection[notDuplicatedLine].push_back(time);
0657                 chemTableWithSelection[notDuplicatedLine].push_back(0);
0658                 chemTableWithSelection[notDuplicatedLine].push_back(1);              
0659                 ++notDuplicatedLine;
0660             }
0661             else { 
0662                 //double r = double(std::rand() ) / RAND_MAX;
0663                 double r = gRandomGen.Rndm(); 
0664                 //std::cout<<r<<std::endl;
0665                 if(r <= fProbabilityForIndirectSB){
0666                     // Add a line
0667                     chemTableWithSelection.push_back(std::vector<ullint>());
0668                     // Fill the line
0669                     chemTableWithSelection[notDuplicatedLine].push_back(eventNum);
0670                     chemTableWithSelection[notDuplicatedLine].push_back(strand);
0671                     chemTableWithSelection[notDuplicatedLine].push_back(copyNumber);
0672                     chemTableWithSelection[notDuplicatedLine].push_back(base);
0673                     chemTableWithSelection[notDuplicatedLine].push_back(time);
0674                     chemTableWithSelection[notDuplicatedLine].push_back(0);
0675                     chemTableWithSelection[notDuplicatedLine].push_back(1);                          
0676                     ++notDuplicatedLine;
0677                 }
0678             }
0679         }       
0680         if (chemTableWithSelection.size() > 0) fchemSlectedTables.insert({chromo,chemTableWithSelection});
0681     }
0682     fchemTables.clear();//free memory
0683 }
0684 
0685 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0686 
0687 void ScanDamage::MergeDamageFromPhysChem()
0688 {
0689     for(int  chromo=0; chromo<46; chromo++)
0690     {
0691         // *****************************
0692         // Add one table after the other
0693         // *****************************
0694 
0695         // MergedTable to be built
0696         Table mergedTable;
0697 
0698         auto itr = fphysSlectedTables.find(chromo);
0699         if(itr != fphysSlectedTables.end())
0700         {
0701             Table physTable= itr->second;
0702             for(auto const& vec : physTable) mergedTable.push_back(vec);
0703         }
0704         itr = fchemSlectedTables.find(chromo);
0705         if(itr != fchemSlectedTables.end())
0706         {
0707             Table chemTable = itr->second;
0708             for(auto const& vec : chemTable) mergedTable.push_back(vec);
0709         }
0710 
0711         // *******************************************
0712         // Sort the merged table to put the event in the correct order
0713         // *******************************************
0714         Trier tri;
0715         Table::iterator it = mergedTable.begin();
0716         Table::iterator ite = mergedTable.end();
0717         std::sort(it, ite, tri);
0718 
0719         // *******************************************
0720         // Delete duplicate SB
0721         // *******************************************
0722 
0723         std::map<ullint,std::map<ullint,std::map<ullint,std::map<ullint,std::vector<ullint>>>>> removeDuplicateValueMap;
0724 
0725         // Put all the values of the mergedTable in the map created just above.
0726         // Loop on all the lines of the mergedTable
0727         for(unsigned int line=0; line<mergedTable.size(); ++line)
0728         {
0729             ullint eventNum = mergedTable[line][0];
0730             ullint strand = mergedTable[line][1];
0731             ullint copyNumber = mergedTable[line][2];
0732             ullint base = mergedTable[line][3];
0733             std::vector<ullint> lineV;
0734             // If more elements are presents, add them here
0735             int lineSize = mergedTable[line].size();
0736             if(lineSize > 4)
0737             {
0738                 for(int i=4; i<lineSize; i++)
0739                 {
0740                     lineV.push_back(mergedTable[line][i]);
0741                 }
0742                 removeDuplicateValueMap[eventNum][strand][copyNumber][base]=lineV;
0743             }
0744             else
0745             {
0746                 lineV.push_back(0);
0747                 removeDuplicateValueMap[eventNum][strand][copyNumber][base]=lineV;
0748             }
0749         }
0750 
0751         // *******************************************
0752         // Create the "mergedTableWithoutDuplicatedSB" table
0753         // *******************************************
0754 
0755         // At this point, we have created a map named "removeDuplicateValueMap" that organized all the mergedTable content
0756         // AND that does not contain any duplicate because of the override caracteristic of a map.
0757         // Indeed, doing map[2] = "hello" followed by map[2]  = "bye" will put map[2] value to "bye" because it overrided the first "hello".
0758         // This is a cheap way to remove duplicates by overriding them.
0759 
0760         // The next part is dedicated to the creation of the "mergedTableWithoutDuplicatedSB" table from the "removeDuplicateValueMap" map.
0761         // Only the event, strand and copynumber and  will be put in this final table.
0762         Table mergedTableWithoutDuplicatedSB;
0763         Table mergedTableWithoutDuplicatedSBandbases;
0764         int notDuplicatedLine = 0;
0765         int notDuplicatedLine2= 0;
0766         // Loop on all the events
0767         std::map<ullint,std::map<ullint,std::map<ullint,std::map<ullint,std::vector<ullint>>>>>::iterator 
0768             iit = removeDuplicateValueMap.begin();
0769         std::map<ullint,std::map<ullint,std::map<ullint,std::map<ullint,std::vector<ullint>>>>>::iterator 
0770             iite = removeDuplicateValueMap.end();
0771         for(; iit!=iite;++iit)
0772         {
0773             ullint eventNum = iit->first;
0774             // Loop on all the strands
0775             std::map<ullint, std::map<ullint, std::map<ullint, std::vector<ullint > > > >::iterator 
0776                 itt = iit->second.begin();
0777             std::map<ullint, std::map<ullint, std::map<ullint, std::vector<ullint > > > >::iterator 
0778                 itte = iit->second.end();
0779             for(; itt!=itte;++itt)
0780             {
0781                 ullint strand = itt->first;
0782                 // Loop on all the copy numbers
0783                 std::map<ullint, std::map<ullint, std::vector<ullint > > >::iterator ittt = itt->second.begin();
0784                 std::map<ullint, std::map<ullint, std::vector<ullint > > >::iterator ittte = itt->second.end();
0785                 for(; ittt!=ittte;++ittt)
0786                 {
0787                     ullint copyNumber = ittt->first;                    
0788                     // Loop on all the base flag
0789                     std::map<ullint, std::vector<ullint > >::iterator itttt = ittt->second.begin();
0790                     std::map<ullint, std::vector<ullint > >::iterator itttte = ittt->second.end();
0791                     for(; itttt!=itttte;++itttt)
0792                     {
0793                         ullint base = itttt->first;
0794                         // Fill the table
0795                         if (strand>0 && strand<3)
0796                         {
0797                             // Add a line
0798                             mergedTableWithoutDuplicatedSB.push_back(std::vector<ullint>());                           
0799                             // Fill the line
0800                             mergedTableWithoutDuplicatedSB[notDuplicatedLine].push_back(eventNum);
0801                             mergedTableWithoutDuplicatedSB[notDuplicatedLine].push_back(strand);
0802                             mergedTableWithoutDuplicatedSB[notDuplicatedLine].push_back(copyNumber);
0803                             mergedTableWithoutDuplicatedSB[notDuplicatedLine].push_back(base);
0804                             mergedTableWithoutDuplicatedSB[notDuplicatedLine].push_back(
0805                                 removeDuplicateValueMap[eventNum][strand][copyNumber][base][0]);
0806                             mergedTableWithoutDuplicatedSB[notDuplicatedLine].push_back(
0807                                 removeDuplicateValueMap[eventNum][strand][copyNumber][base][1]);
0808                             mergedTableWithoutDuplicatedSB[notDuplicatedLine].push_back(
0809                                 removeDuplicateValueMap[eventNum][strand][copyNumber][base][2]);
0810                             ++notDuplicatedLine;                           
0811                             if (base==0)
0812                             {
0813                                 // Add a line
0814                                 mergedTableWithoutDuplicatedSBandbases.push_back(std::vector<ullint>());                              
0815                                 // Fill the line
0816                                 mergedTableWithoutDuplicatedSBandbases[notDuplicatedLine2].push_back(eventNum);
0817                                 mergedTableWithoutDuplicatedSBandbases[notDuplicatedLine2].push_back(strand);
0818                                 mergedTableWithoutDuplicatedSBandbases[notDuplicatedLine2].push_back(copyNumber);                               
0819                                 ++notDuplicatedLine2;
0820                             }
0821                         }
0822                     }
0823                 }
0824             }
0825         }
0826 
0827         // *******************************************
0828         // Print the "mergedTableWithoutDuplicatedSB" table for the current chromosome
0829         // *******************************************
0830         if (mergedTableWithoutDuplicatedSB.size() > 0) {
0831             //PrintTable(fMergeFolder + "/chromo_"+std::to_string(chromo)+".dat", 
0832             //mergedTableWithoutDuplicatedSB, "eventNum, strand, copyNumber, isbase, 
0833             //time(ns*1000000), edep, phy:0 chem:1");
0834             fMergedTables.insert({chromo,mergedTableWithoutDuplicatedSB});
0835         }
0836         mergedTable.clear();
0837         mergedTableWithoutDuplicatedSBandbases.clear();
0838         mergedTableWithoutDuplicatedSB.clear();
0839     }
0840     //free memory:
0841     fphysSlectedTables.clear();
0842     fchemSlectedTables.clear();
0843 }
0844 
0845 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0846 
0847 void ScanDamage::ReadCellandVoxelDefFilePaths()
0848 {
0849     fs::path thisP = fs::current_path();
0850     for (const auto entry : fs::directory_iterator(thisP)){
0851         if (entry.path().filename() == "imp.info") {
0852             std::ifstream file(entry.path().c_str());
0853             if(!file.good() ){
0854                 std::cerr<<"**** Fatal Error *****"<<std::endl;
0855                 std::cerr<<"ScanDamage::ReadCellandVoxelDefFilePaths(): File corupted: "
0856                 <<entry.path()<<std::endl;
0857                 std::cerr<<"*************** *****"<<std::endl;
0858                 exit(EXIT_FAILURE);
0859             }
0860 
0861             std::string line;
0862             while(std::getline(file, line) ){
0863                 std::istringstream iss(line);
0864                 std::string flag;
0865                 iss >> flag;
0866                 if ( flag == "_geovolxelpath") {
0867                     std::string voxname;
0868                     iss >> voxname;
0869                     fVoxelDefFilesList.insert(voxname);
0870                 }
0871                 if ( flag == "_geocellpath") {
0872                     std::string cellpname;
0873                     iss >> cellpname;
0874                     fCellDefFilePath = cellpname;
0875                 }
0876                 if ( flag == "_numberOfBasepairs") {
0877                     iss >> fTotalNbBpPlacedInGeo;
0878                 }
0879                 if ( flag == "_numberOfHistones") {
0880                     iss >> fTotalNbHistonePlacedInGeo;
0881                 }
0882                 if ( flag == "_nucleusVolume") {
0883                     iss >> fNucleusVolume;
0884                 }
0885                 if ( flag == "_nucleusMassDensity") {
0886                     iss >> fNucleusMassDensity;
0887                 }
0888                 if ( flag == "_nucleusMass") {
0889                     iss >> fNucleusMass;
0890                 }
0891             }
0892             file.close();
0893         }
0894     }
0895 }
0896 
0897 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....