Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /geant4/examples/advanced/dna/moleculardna/src/IRTDamageReactionModel.cc was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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 #include "IRTDamageReactionModel.hh"
0027 
0028 #include "DNAGeometry.hh"
0029 #include "DNAHit.hh"
0030 #include "DetectorConstruction.hh"
0031 #include "EventAction.hh"
0032 
0033 #include "G4DNAMolecularMaterial.hh"
0034 #include "G4DNAMolecularReactionTable.hh"
0035 #include "G4ErrorFunction.hh"
0036 #include "G4EventManager.hh"
0037 #include "G4IRTUtils.hh"
0038 #include "G4Molecule.hh"
0039 #include "G4PhysicalConstants.hh"
0040 #include "G4RunManager.hh"
0041 #include "G4Scheduler.hh"
0042 #include "G4SystemOfUnits.hh"
0043 #include "G4UnitsTable.hh"
0044 #include "Randomize.hh"
0045 
0046 #include <vector>
0047 
0048 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0049 
0050 IRTDamageReactionModel::IRTDamageReactionModel(const G4String& name)
0051   : G4VDNAHitModel(name), fMolecularReactionTable(G4DNAMolecularReactionTable::Instance())
0052 {
0053   auto det = dynamic_cast<const DetectorConstruction*>(
0054     G4RunManager::GetRunManager()->GetUserDetectorConstruction());
0055   fpDNAGeometry = det->GetDNAGeometry();
0056 }
0057 
0058 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0059 
0060 G4double IRTDamageReactionModel::GetTimeToEncounter(const G4MolecularConfiguration* molA,
0061                                                     const G4MolecularConfiguration* molB,
0062                                                     const G4double& distance)
0063 {
0064   G4double irt = -1;
0065   const auto pMoleculeA = molA;
0066   const auto pMoleculeB = molB;
0067   auto reactionData = fMolecularReactionTable->GetReactionData(pMoleculeA, pMoleculeB);
0068   G4double D = molA->GetDiffusionCoefficient() + molB->GetDiffusionCoefficient();
0069   auto kobs = reactionData->GetObservedReactionRateConstant();
0070   if (D == 0) {
0071     G4ExceptionDescription exceptionDescription;
0072     exceptionDescription << "D = 0"
0073                          << " for : " << molA->GetName() << " and " << molB->GetName();
0074     G4Exception(
0075       "IRTDamageReactionModel"
0076       "::GetTimeToEncounter()",
0077       "MolecularIRTDamageReactionModel002", FatalException, exceptionDescription);
0078     return -1;
0079   }
0080   G4double Reff = kobs / (4 * CLHEP::pi * D * CLHEP::Avogadro);
0081 
0082   if (distance < Reff) {
0083     return 0;  //
0084   }
0085 
0086   G4double Winf = 0;
0087 
0088   if (distance != 0) {
0089     Winf = Reff / distance;
0090   }
0091   else {
0092     G4ExceptionDescription exceptionDescription;
0093     exceptionDescription << "distance = " << distance << " is uncorrected with "
0094                          << " Reff = " << Reff << " for : " << molA->GetName() << " and "
0095                          << molB->GetName();
0096     G4Exception(
0097       "IRTDamageReactionModel"
0098       "::GetTimeToEncounter()",
0099       "MolecularIRTDamageReactionModel001", FatalException, exceptionDescription);
0100   }
0101 
0102   G4double U = G4UniformRand();
0103 
0104   if (Winf != 0 && U < Winf) {
0105     irt = (1.0 / (4 * D)) * std::pow((distance - Reff) / G4ErrorFunction::erfcInv(U / Winf), 2);
0106   }
0107   return irt;
0108 }
0109 
0110 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0111 
0112 void IRTDamageReactionModel::RecordDNADamage() const  // let's suppose that this is not so much
0113 {
0114   if (fpDNAPhyVolume == nullptr || fpTrack == nullptr) {
0115     G4ExceptionDescription exceptionDescription;
0116     exceptionDescription << "fpDNAPhyVolume == nullptr or fpTrack == nullptr";
0117     G4Exception(
0118       "IRTDamageReactionModel"
0119       "RecordDNA",
0120       "NO_VOLUME001", FatalException, exceptionDescription);
0121   }
0122   const G4VTouchable* touchable = fpTrack->GetTouchable();
0123   if (touchable == nullptr) {
0124     return;
0125   }
0126   auto pPhyVolum = const_cast<G4VPhysicalVolume*>(fpDNAPhyVolume);
0127   const G4MolecularConfiguration* radical = GetMolecule(fpTrack)->GetMolecularConfiguration();
0128 
0129   // particle position
0130   const G4ThreeVector& pos_particle = fpTrack->GetPosition();
0131   G4AffineTransform transform = touchable->GetHistory()->GetTopTransform();
0132   G4ThreeVector localpos_particle = transform.TransformPoint(pos_particle);
0133 
0134   // DNA position
0135   G4ThreeVector localPos_DNA = pPhyVolum->GetTranslation();
0136   G4ThreeVector globalPos_DNA =
0137     touchable->GetHistory()->GetTopTransform().Inverse().TransformPoint(localPos_DNA);
0138 
0139   const int64_t idx = fpDNAGeometry->GetGlobalUniqueID(pPhyVolum, touchable);
0140 
0141   int64_t bp = fpDNAGeometry->GetBasePairFromUniqueID(idx);
0142   G4int chainID = fpDNAGeometry->GetChainIDFromUniqueID(idx);
0143   G4int strandID = fpDNAGeometry->GetStrandIDFromUniqueID(idx);
0144   molecule mol = fpDNAGeometry->GetMoleculeFromUniqueID(idx);
0145   G4int placementIdx = fpDNAGeometry->GetPlacementIndexFromUniqueID(idx);
0146 
0147   G4String chromosome =
0148     fpDNAGeometry->GetChromosomeMapper()->GetCurrentChromosomeKey(globalPos_DNA);
0149 
0150   auto dnaHit = new DNAHit(mol, placementIdx, chainID, strandID, bp, globalPos_DNA, localPos_DNA,
0151                            chromosome, radical);
0152 
0153   dynamic_cast<EventAction*>(G4EventManager::GetEventManager()->GetUserEventAction())
0154     ->AddDNAHit(dnaHit);
0155 }
0156 
0157 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0158 
0159 void IRTDamageReactionModel::MakeReaction(const G4Track& track)
0160 {
0161   // G4Track *pTrackA = const_cast<G4Track *>(&track);
0162   if (track.GetTrackStatus() == fStopAndKill) {
0163     G4ExceptionDescription exceptionDescription;
0164     exceptionDescription << "this track is killed";
0165     G4Exception(
0166       "IRTDamageReactionModel"
0167       "MakeReaction",
0168       "NO_TRACK02", FatalException, exceptionDescription);
0169   }
0170   if (G4Scheduler::Instance()->GetVerbose() != 0) {
0171     G4cout << "At time : " << std::setw(7)
0172            << G4BestUnit(G4Scheduler::Instance()->GetGlobalTime(), "Time")
0173            << " Reaction : " << GetIT(track)->GetName() << " (" << track.GetTrackID() << ") + "
0174            << fpDNAPhyVolume->GetName() << " -> ";
0175     G4cout << " Damaged " + fpDNAPhyVolume->GetName();
0176     G4cout << G4endl;
0177   }
0178 }
0179 
0180 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0181 
0182 /// DoReaction means : kill species and record DNA damage
0183 G4bool IRTDamageReactionModel::DoReaction(const G4Track& track, const G4double& reactionTime,
0184                                           const DNANode& vp)
0185 {
0186   fReactionTime = reactionTime;
0187   fpTrack = &track;
0188   fpDNAPhyVolume = std::get<const G4VPhysicalVolume*>(vp);
0189   MakeReaction(track);
0190   RecordDNADamage();
0191   G4Scheduler::Instance()->SetInteractionStep(true);// reset reaction list to avoid crash.
0192   return true;
0193 }
0194 
0195 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0196 
0197 G4double IRTDamageReactionModel::CalculateReactionTime(const G4Track& track, DNANode& vp)
0198 {
0199   fpTrack = nullptr;
0200   fminTimeStep = DBL_MAX;
0201   fReactionTime = DBL_MAX;
0202   fpDNAPhyVolume = nullptr;
0203   if (fpDNAGeometry == nullptr) {
0204     G4ExceptionDescription exceptionDescription;
0205     exceptionDescription << "no fpDNAGeometry" << G4endl;
0206     G4Exception(
0207       "IRTDamageReactionModel"
0208       "::CalculateReactionTime()",
0209       "MolecularIRTDamageReactionModel007", FatalException, exceptionDescription);
0210   }
0211 
0212   auto pMoleculeA = GetMolecule(track);
0213   auto pMolConfA = pMoleculeA->GetMolecularConfiguration();
0214   const auto pReactantList = fMolecularReactionTable->CanReactWith(pMolConfA);
0215 
0216   if (pReactantList == nullptr) {
0217     G4ExceptionDescription exceptionDescription;
0218     exceptionDescription << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
0219     G4cout << "!!! WARNING" << G4endl;
0220     G4cout << "IRTDamageReactionModel::CalculateReactionTime will return infinity "
0221               "for the reaction because the molecule "
0222            << pMoleculeA->GetName() << " does not have any reactants given in the reaction table."
0223            << G4endl;
0224     G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
0225     G4Exception(
0226       "IRTDamageReactionModel"
0227       "::CalculateReactionTime()",
0228       "MolecularIRTDamageReactionModel003", FatalException, exceptionDescription);
0229     return -1;
0230   }
0231 
0232   size_t nbReactives = pReactantList->size();
0233 
0234   if (nbReactives == 0) {
0235     G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
0236     G4cout << "!!! WARNING" << G4endl;
0237     G4cout << "IRTDamageReactionModel::CalculateReactionTime will return infinity "
0238               "for the reaction because the molecule "
0239            << pMoleculeA->GetName() << " does not have any reactants given in the reaction table."
0240            << "This message can also result from a wrong implementation of the "
0241               "reaction table."
0242            << G4endl;
0243     G4cout << "!!!!!!!!!!!!!!!!!!!!" << G4endl;
0244     return -1;
0245   }
0246   const G4VTouchable* touchable = track.GetTouchable();
0247   if (touchable == nullptr) {
0248     return -1;
0249   }
0250 
0251   const G4LogicalVolume* logicalVolume = touchable->GetVolume()->GetLogicalVolume();
0252   const G4ThreeVector& globalPos_track = track.GetPosition();
0253   const G4ThreeVector& localPos =
0254     touchable->GetHistory()->GetTopTransform().TransformPoint(globalPos_track);
0255 
0256   G4double D = pMoleculeA->GetDiffusionCoefficient();
0257   std::vector<G4VPhysicalVolume*> result_pv;
0258   result_pv.clear();
0259   fpDNAGeometry->FindNearbyMolecules(logicalVolume, localPos, result_pv,
0260                                      G4IRTUtils::GetRCutOff(100 * ns));
0261 
0262   if (result_pv.empty()) {
0263     return -1;
0264   }
0265   for (const auto& physicalVolume : result_pv) {
0266     const G4Material* material = physicalVolume->GetLogicalVolume()->GetMaterial();
0267 
0268     G4MolecularConfiguration* dna_molConf =
0269       G4DNAMolecularMaterial::Instance()->GetMolecularConfiguration(material);
0270     auto it = std::find(pReactantList->begin(), pReactantList->end(), dna_molConf);
0271     if (it == pReactantList->end()) {
0272       continue;
0273     }
0274 
0275     G4ThreeVector localPos_DNA = physicalVolume->GetTranslation();
0276     G4ThreeVector globalPos_DNA =
0277       touchable->GetHistory()->GetTopTransform().Inverse().TransformPoint(localPos_DNA);
0278     G4double distance = (localPos_DNA - localPos).mag();
0279 
0280     G4double distance2 = distance * distance;
0281     auto reactionData =
0282       G4DNAMolecularReactionTable::Instance()->GetReactionData(pMolConfA, dna_molConf);
0283 
0284     G4double kobs = reactionData->GetObservedReactionRateConstant();
0285     G4double Reff = kobs / (4 * CLHEP::pi * D * CLHEP::Avogadro);
0286 
0287     if (distance2 < Reff * Reff) {
0288       fminTimeStep = 0.;
0289       vp = physicalVolume;
0290     }
0291     else {
0292       G4double tempMinET = GetTimeToEncounter(pMolConfA, dna_molConf, distance);
0293       if (tempMinET > G4Scheduler::Instance()->GetEndTime() || tempMinET < 0) {
0294         continue;
0295       }
0296       if (tempMinET >= fminTimeStep) {
0297         continue;
0298       }
0299       fminTimeStep = tempMinET;
0300       vp = physicalVolume;
0301     }
0302   }
0303   return fminTimeStep;
0304 }
0305 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......