Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-28 07:50:40

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 /// \file ScoreStrandBreaks.cc
0027 /// \brief Implementation of the ScoreStrandBreaks class
0028 
0029 // This example is provided by the Geant4-DNA collaboration
0030 // Any report or published results obtained using the Geant4-DNA software
0031 // shall cite the following Geant4-DNA collaboration publication:
0032 // Med. Phys. 37 (2010) 4692-4708
0033 // J. Comput. Phys. 274 (2014) 841-882
0034 // The Geant4-DNA web site is available at http://geant4-dna.org
0035 //
0036 // Authors: J. Naoki D. Kondo (UCSF, US)
0037 //          J. Ramos-Mendez and B. Faddegon (UCSF, US)
0038 //
0039 
0040 #include "ScoreStrandBreaks.hh"
0041 
0042 #include "G4AnalysisManager.hh"
0043 #include "G4DNAChemistryManager.hh"
0044 #include "G4Event.hh"
0045 #include "G4EventManager.hh"
0046 #include "G4Scheduler.hh"
0047 #include "G4UImessenger.hh"
0048 #include "G4UnitsTable.hh"
0049 
0050 #include <G4EventManager.hh>
0051 #include <G4SystemOfUnits.hh>
0052 #include <globals.hh>
0053 
0054 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0055 
0056 ScoreStrandBreaks::ScoreStrandBreaks(G4String name, DetectorConstruction* detect, G4double* radius)
0057   : G4VPrimitiveScorer(name), G4UImessenger(), fpDetector(detect)
0058 {
0059   fpOutputFileUI = new G4UIcmdWithAString("/scorer/StrandBreak/OutputFile", this);
0060   fpOutputFileUI->SetGuidance("Set output file name");
0061 
0062   fpOutputTypeUI = new G4UIcmdWithAString("/scorer/StrandBreak/OutputFormat", this);
0063   fpOutputTypeUI->SetGuidance("Set output file format: ASCII by default");
0064 
0065   fpBreakEnergyUI = new G4UIcmdWithADoubleAndUnit("/scorer/StrandBreak/BreakEnergy", this);
0066   fpBreakEnergyUI->SetDefaultUnit("eV");
0067   fpBreakEnergyUI->SetGuidance("Direct SSB energy treshold");
0068 
0069   fRadius = radius;
0070   fpGun = new MoleculeInserter(true);
0071   // G4DNAChemistryManager::Instance()->SetGun(fpGun);
0072 }
0073 
0074 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0075 
0076 ScoreStrandBreaks::~ScoreStrandBreaks()
0077 {
0078   delete fpOutputFileUI;
0079   delete fpBreakEnergyUI;
0080   delete fpOutputTypeUI;
0081   delete fpGun;
0082 }
0083 
0084 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0085 
0086 void ScoreStrandBreaks::SetNewValue(G4UIcommand* command, G4String newValue)
0087 {
0088   if (command == fpOutputFileUI) {
0089     fOutputName = newValue;
0090   }
0091 
0092   if (command == fpBreakEnergyUI) {
0093     fBreakEnergy = fpBreakEnergyUI->GetNewDoubleValue(newValue);
0094   }
0095 
0096   if (command == fpOutputTypeUI) {
0097     fOutputType = newValue;
0098     G4StrUtil::to_lower(fOutputType);
0099   }
0100 }
0101 
0102 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0103 
0104 G4bool ScoreStrandBreaks::ProcessHits(G4Step* aStep, G4TouchableHistory*)
0105 {
0106   G4double edep = aStep->GetTotalEnergyDeposit();
0107   if (edep <= 0) {
0108     return FALSE;
0109   }
0110   fEnergyDeposit += edep;
0111 
0112   G4StepPoint* aStepPoint = aStep->GetTrack()->GetStep()->GetPreStepPoint();
0113   G4TouchableHandle aTouchable = aStepPoint->GetTouchableHandle();
0114   G4String volumeName = aTouchable->GetVolume()->GetName();
0115   G4StrUtil::to_lower(volumeName);
0116   G4int strand = 0;
0117 
0118   if (G4StrUtil::contains(volumeName, "deoxyribose")
0119       || G4StrUtil::contains(volumeName, "phosphate"))
0120   {
0121     if (G4StrUtil::contains(volumeName, "1"))
0122       strand = 1;
0123     else if (G4StrUtil::contains(volumeName, "2"))
0124       strand = 2;
0125 
0126     G4int StrandID = strand;
0127     G4int BaseID = aTouchable->GetReplicaNumber(0);
0128     G4int PlasmidID = aTouchable->GetReplicaNumber(1);
0129     G4int EventID = G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID();
0130 
0131     fEnergyDepositMap[EventID][PlasmidID][BaseID][StrandID] += edep;
0132     return TRUE;
0133   }
0134 
0135   if (!fDNAInserted) {
0136     // Insert DNA molecules
0137     std::vector<std::vector<G4int>> DNADetails = fpDetector->GetDNADetails();
0138     std::vector<G4ThreeVector> DNAPositions = fpDetector->GetDNAPositions();
0139     std::vector<G4String> DNAMolecules = fpDetector->GetDNANames();
0140 
0141     fpGun->Clean();
0142     for (size_t i = 0; i < DNAPositions.size(); i++) {
0143       fpGun->AddMolecule(DNAMolecules[i], DNAPositions[i], 1.0 * ps);
0144     }
0145     fpGun->DefineTracks();
0146 
0147     fDNAInserted = true;
0148   }
0149   return FALSE;
0150 }
0151 
0152 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0153 
0154 void ScoreStrandBreaks::Initialize(G4HCofThisEvent*) {}
0155 
0156 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0157 
0158 void ScoreStrandBreaks::EndOfEvent(G4HCofThisEvent*)
0159 {
0160   // Get EventID
0161   G4int EventID = G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID();
0162 
0163   // Absorbed Dose
0164   G4double volume = 4.0 / 3 * 3.14159 * (*fRadius) * (*fRadius) * (*fRadius) / 8;
0165   G4double density = 1.0 * g / cm3;
0166   G4double mass = density * volume;
0167   G4double Dose = fEnergyDeposit / mass;
0168   fDoseArray[EventID] = Dose / gray;
0169 
0170   // Direct Strand Breaks
0171   for (auto EventAndElse : fEnergyDepositMap) {
0172     G4int event = EventAndElse.first;
0173     for (auto PlasmidAndElse : EventAndElse.second) {
0174       G4int plasmid = PlasmidAndElse.first;
0175       for (auto BaseAndElse : PlasmidAndElse.second) {
0176         G4int base = BaseAndElse.first;
0177         for (auto StrandAndEdep : BaseAndElse.second) {
0178           G4int strand = StrandAndEdep.first;
0179           G4double edep = StrandAndEdep.second;
0180           if (edep > fBreakEnergy) fDirectDamageMap[event].push_back({plasmid, base, strand});
0181         }
0182       }
0183     }
0184   }
0185   fEnergyDepositMap.clear();
0186 
0187   // Indirect Strand Breaks
0188   std::vector<std::vector<G4int>> DNADetails = fpDetector->GetDNADetails();
0189   std::vector<G4Track*> InsertedTracks = fpGun->GetInsertedTracks();
0190   std::vector<std::vector<G4int>> IndirectBreaks;
0191 
0192   for (size_t i = 0; i < InsertedTracks.size(); i++) {
0193     if (InsertedTracks[i]->GetTrackStatus() == fStopAndKill)
0194       IndirectBreaks.push_back(DNADetails[i]);
0195   }
0196 
0197   for (size_t i = 0; i < IndirectBreaks.size(); i++) {
0198     fIndirectDamageMap[EventID].push_back(IndirectBreaks[i]);
0199   }
0200 
0201   fEnergyDeposit = 0;
0202   fDNAInserted = false;
0203   fnbOfEvents++;
0204 }
0205 
0206 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0207 
0208 void ScoreStrandBreaks::AbsorbResultsFromWorkerScorer(G4VPrimitiveScorer* workerScorer)
0209 {
0210   ScoreStrandBreaks* right =
0211     dynamic_cast<ScoreStrandBreaks*>(dynamic_cast<G4VPrimitiveScorer*>(workerScorer));
0212 
0213   if (right == 0) return;
0214   if (right == this) return;
0215 
0216   DamageMap WorkerDirectDamageMap = right->fDirectDamageMap;
0217   DamageMap WorkerIndirectDamageMap = right->fIndirectDamageMap;
0218   std::map<G4int, G4double> WorkerDose = right->fDoseArray;
0219 
0220   for (auto EventAndBreaks : WorkerDirectDamageMap) {
0221     G4int EventID = EventAndBreaks.first;
0222     std::vector<std::vector<G4int>> Breaks = EventAndBreaks.second;
0223     for (size_t i = 0; i < Breaks.size(); i++) {
0224       fDirectDamageMap[EventID].push_back(Breaks[i]);
0225     }
0226   }
0227 
0228   for (auto EventAndBreaks : WorkerIndirectDamageMap) {
0229     G4int EventID = EventAndBreaks.first;
0230     std::vector<std::vector<G4int>> Breaks = EventAndBreaks.second;
0231     for (size_t i = 0; i < Breaks.size(); i++) {
0232       fIndirectDamageMap[EventID].push_back(Breaks[i]);
0233     }
0234   }
0235 
0236   for (auto EventAndDose : WorkerDose) {
0237     G4int EventID = EventAndDose.first;
0238     G4double dose = EventAndDose.second;
0239     fDoseArray[EventID] = dose;
0240   }
0241 
0242   fnbOfEvents += right->fnbOfEvents;
0243   right->Clear();
0244 }
0245 
0246 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0247 
0248 void ScoreStrandBreaks::Clear()
0249 {
0250   if (fDirectDamageMap.size() != 0) fDirectDamageMap.clear();
0251 
0252   if (fIndirectDamageMap.size() != 0) fIndirectDamageMap.clear();
0253 
0254   if (fEnergyDepositMap.size() != 0) fEnergyDepositMap.clear();
0255 
0256   if (fDoseArray.size() != 0) fDoseArray.clear();
0257 }
0258 
0259 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0260 
0261 void ScoreStrandBreaks::DrawAll() {}
0262 
0263 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0264 
0265 void ScoreStrandBreaks::PrintAll() {}
0266 
0267 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0268 
0269 void ScoreStrandBreaks::OutputAndClear(G4double LET, G4double LET_STD)
0270 {
0271   if (G4Threading::IsWorkerThread()) return;
0272 
0273   if (fOutputType != "ascii") {
0274     G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0275 
0276     if (fOutputType == "csv")
0277       analysisManager->SetDefaultFileType("csv");
0278 
0279     else if (fOutputType == "root")
0280       analysisManager->SetDefaultFileType("root");
0281 
0282     else if (fOutputType == "xml")
0283       analysisManager->SetDefaultFileType("xml");
0284 
0285     WriteWithAnalysisManager(analysisManager);
0286   }
0287 
0288   else
0289     ASCII(LET, LET_STD);
0290 
0291   Clear();
0292 }
0293 
0294 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0295 
0296 void ScoreStrandBreaks::WriteWithAnalysisManager(G4VAnalysisManager* analysisManager)
0297 {
0298   analysisManager->OpenFile(fOutputName);
0299   int fNtupleID = analysisManager->CreateNtuple("SB", "Direct And Indirect SBs");
0300   analysisManager->CreateNtupleIColumn(fNtupleID, "EventID");
0301   analysisManager->CreateNtupleIColumn(fNtupleID, "PlasmidID");
0302   analysisManager->CreateNtupleIColumn(fNtupleID, "StrandID");
0303   analysisManager->CreateNtupleIColumn(fNtupleID, "BaseID");
0304   analysisManager->CreateNtupleIColumn(fNtupleID, "DamageID");
0305   analysisManager->CreateNtupleIColumn(fNtupleID, "BreakID");
0306   analysisManager->FinishNtuple(fNtupleID);
0307 
0308   for (G4int i = 0; i < fnbOfEvents; i++) {
0309     if (fDirectDamageMap.find(i) != fDirectDamageMap.end()) {
0310       for (size_t j = 0; j < fDirectDamageMap[i].size(); j++) {
0311         std::vector<G4int> Break = fDirectDamageMap[i][j];
0312         analysisManager->FillNtupleIColumn(fNtupleID, 0, i);
0313         analysisManager->FillNtupleIColumn(fNtupleID, 1, Break[0]);
0314         analysisManager->FillNtupleIColumn(fNtupleID, 2, Break[1]);
0315         analysisManager->FillNtupleIColumn(fNtupleID, 3, Break[2]);
0316         analysisManager->FillNtupleIColumn(fNtupleID, 4, 1);
0317         analysisManager->AddNtupleRow(fNtupleID);
0318       }
0319     }
0320 
0321     if (fIndirectDamageMap.find(i) != fIndirectDamageMap.end()) {
0322       for (size_t j = 0; j < fIndirectDamageMap[i].size(); j++) {
0323         std::vector<G4int> Break = fIndirectDamageMap[i][j];
0324         analysisManager->FillNtupleIColumn(fNtupleID, 0, i);
0325         analysisManager->FillNtupleIColumn(fNtupleID, 1, Break[0]);
0326         analysisManager->FillNtupleIColumn(fNtupleID, 2, Break[1]);
0327         analysisManager->FillNtupleIColumn(fNtupleID, 3, Break[2]);
0328         analysisManager->FillNtupleIColumn(fNtupleID, 4, 2);
0329         analysisManager->AddNtupleRow(fNtupleID);
0330       }
0331     }
0332   }
0333 
0334   analysisManager->Write();
0335   analysisManager->CloseFile();
0336 }
0337 
0338 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0339 
0340 void ScoreStrandBreaks::ASCII(G4double LET, G4double LET_STD)
0341 {
0342   std::ofstream dna(fOutputName + ".txt");
0343 
0344   dna << "# DNA SB Map File" << G4endl;
0345   dna << "# LET = " << LET / (keV / um) << " +- " << LET_STD / (keV / um) << " keV / um" << G4endl;
0346   dna << "#" << std::setw(11) << "Event-ID" << std::setw(12) << "Plasmid-ID" << std::setw(12)
0347       << "BP-ID" << std::setw(12) << "Strand-ID" << std::setw(10) << "Break-ID" << std::setw(12)
0348       << "Dose (Gy) " << G4endl;
0349 
0350   for (G4int i = 0; i < fnbOfEvents; i++) {
0351     if (fDirectDamageMap.find(i) != fDirectDamageMap.end()) {
0352       for (size_t j = 0; j < fDirectDamageMap[i].size(); j++) {
0353         std::vector<G4int> Break = fDirectDamageMap[i][j];
0354         dna << std::setw(12) << i << std::setw(12) << Break[0] << std::setw(12) << Break[1]
0355             << std::setw(12) << Break[2] << std::setw(10) << 1 << std::setw(12) << fDoseArray[i]
0356             << G4endl;
0357       }
0358     }
0359 
0360     if (fIndirectDamageMap.find(i) != fIndirectDamageMap.end()) {
0361       for (size_t j = 0; j < fIndirectDamageMap[i].size(); j++) {
0362         std::vector<G4int> Break = fIndirectDamageMap[i][j];
0363         dna << std::setw(12) << i << std::setw(12) << Break[0] << std::setw(12) << Break[1]
0364             << std::setw(12) << Break[2] << std::setw(10) << 2 << std::setw(12) << fDoseArray[i]
0365             << G4endl;
0366       }
0367     }
0368   }
0369 
0370   dna.close();
0371 }
0372 
0373 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......