Files
geant4/source/processes/electromagnetic/dna/models/src/G4DNAMolecularReaction.cc
T
2016-06-09 16:46:55 +02:00

207 lines
8.1 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. *
// ********************************************************************
//
//
// Author: Mathieu Karamitros (kara@cenbg.in2p3.fr)
//
// WARNING : This class is released as a prototype.
// It might strongly evolve or even disapear in the next releases.
//
// History:
// -----------
// 10 Oct 2011 M.Karamitros created
//
// -------------------------------------------------------------------
#include "G4DNAMolecularReaction.hh"
#include "G4DNAMolecularReactionTable.hh"
#include "G4VDNAReactionModel.hh"
#include "G4ITManager.hh"
#include "G4UnitsTable.hh"
using namespace std;
G4DNAMolecularReaction::G4DNAMolecularReaction():G4VITReactionProcess(),
fMolReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fReactionTable))
{
//ctor
fVerbose = 0;
fReactionModel = 0;
fReactionRadius = -1;
fDistance = -1;
}
G4DNAMolecularReaction::~G4DNAMolecularReaction()
{
//dtor
if(fChanges) delete fChanges;
}
G4DNAMolecularReaction::G4DNAMolecularReaction(const G4DNAMolecularReaction& other):G4VITReactionProcess(other),
fMolReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fReactionTable))
{
//copy ctor
fVerbose = other.fVerbose ;
fMolReactionTable = other.fMolReactionTable;
fReactionModel = 0;
fReactionRadius = -1;
fDistance = -1;
}
G4DNAMolecularReaction& G4DNAMolecularReaction::operator=(const G4DNAMolecularReaction& rhs)
{
if (this == &rhs) return *this; // handle self assignment
fVerbose = rhs.fVerbose ;
fMolReactionTable = rhs.fMolReactionTable;
fReactionRadius = -1;
fDistance = -1;
//assignment operator
return *this;
}
G4bool G4DNAMolecularReaction::TestReactibility(const G4Track& trackA,
const G4Track& trackB,
const double currentStepTime,
const double /*previousStepTime*/,
bool userStepTimeLimit) /*const*/
{
G4Molecule* moleculeA = GetMolecule(trackA);
G4Molecule* moleculeB = GetMolecule(trackB);
if(!fReactionModel)
{
G4ExceptionDescription exceptionDescription ("You have to give a reaction model to the molecular reaction process");
G4Exception("G4DNAMolecularReaction::TestReactibility","MolecularReaction001",
FatalErrorInArgument,exceptionDescription);
return false; // makes coverity happy
}
if(fMolReactionTable==0)
{
G4ExceptionDescription exceptionDescription ("You have to give a reaction table to the molecular reaction process");
G4Exception("G4DNAMolecularReaction::TestReactibility","MolecularReaction002",
FatalErrorInArgument,exceptionDescription);
return false; // makes coverity happy
}
// Retrieve reaction range
fReactionRadius = -1 ; // reaction Range
fReactionRadius = fReactionModel -> GetReactionRadius(moleculeA, moleculeB);
fDistance = -1 ; // separation distance
if(currentStepTime == 0.)
{
userStepTimeLimit = false;
}
G4bool output = fReactionModel->FindReaction(trackA, trackB, fReactionRadius,fDistance, userStepTimeLimit);
#ifdef G4VERBOSE
// DEBUG
if(fVerbose > 1)
{
G4cout << "\033[1;39;36m" << "G4MolecularReaction "<< G4endl;
G4cout << "FindReaction returned : " << G4BestUnit(output,"Length") << G4endl;
G4cout << " reaction radius : " << G4BestUnit(fReactionRadius,"Length")
<< " real distance : " << G4BestUnit((trackA.GetPosition() - trackB.GetPosition()).mag(), "Length")
<< " calculated distance by model (= -1 if real distance > reaction radius and the user limitation step is not reached) : "
<< G4BestUnit(fDistance,"Length")
<< G4endl;
G4cout << "TrackID A : " << trackA.GetTrackID()
<< ", TrackID B : " << trackB.GetTrackID()
<< " | MolA " << moleculeA->GetName()
<< ", MolB " << moleculeB->GetName()
<<"\033[0m\n"
<< G4endl;
G4cout << "--------------------------------------------" << G4endl;
}
#endif
return output ;
}
G4ITReactionChange* G4DNAMolecularReaction::MakeReaction(const G4Track& trackA, const G4Track& trackB)
{
fChanges = new G4ITReactionChange();
fChanges->Initialize(trackA, trackB);
G4Molecule* moleculeA = GetMolecule(trackA);
G4Molecule* moleculeB = GetMolecule(trackB);
#ifdef G4VERBOSE
// DEBUG
if(fVerbose)
{
G4cout << "G4DNAMolecularReaction::MakeReaction" << G4endl;
G4cout<<"TrackA n°" << trackA.GetTrackID()
<<"\t | Track B n°" << trackB.GetTrackID() << G4endl;
G4cout<<"Track A : Position : " << G4BestUnit(trackA.GetPosition(),"Length")
<<"\t Global Time : " << G4BestUnit(trackA.GetGlobalTime(), "Time")<< G4endl;
G4cout<<"Track B : Position : " << G4BestUnit(trackB.GetPosition() ,"Length")
<<"\t Global Time : " << G4BestUnit(trackB.GetGlobalTime(), "Time")<< G4endl;
G4cout<<"Reaction range : " << G4BestUnit(fReactionRadius,"Length")
<< " \t Separation distance : " << G4BestUnit(fDistance,"Length")<< G4endl;
G4cout << "--------------------------------------------" << G4endl;
}
#endif
const G4DNAMolecularReactionData* reactionData = fMolReactionTable->GetReactionData(moleculeA, moleculeB);
G4int nbProducts = reactionData->GetNbProducts();
if (nbProducts)
{
G4double D1 = moleculeA->GetDiffusionCoefficient();
G4double D2 = moleculeB->GetDiffusionCoefficient();
G4double sqrD1 = sqrt(D1);
G4double sqrD2 = sqrt(D2);
G4double numerator = sqrD1 + sqrD2;
G4ThreeVector reactionSite = sqrD1/numerator * trackA.GetPosition()
+ sqrD2/numerator * trackB.GetPosition() ;
for (G4int j=0 ; j < nbProducts; j++)
{
G4Molecule* product = new G4Molecule(*reactionData->GetProduct(j));
G4Track* productTrack = product->BuildTrack(trackA.GetGlobalTime(),
reactionSite);
productTrack->SetTrackStatus(fAlive);
fChanges->AddSecondary(productTrack);
G4ITManager<G4Molecule>::Instance()->Push(productTrack);
}
}
fChanges->KillParents(true);
return fChanges;
}