Files
geant4/examples/extended/medical/dna/dnadamage2/src/DetectorConstruction.cc
T

264 lines
8.9 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 DetectorConstruction.cc
/// \brief Implementation of the DetectorConstruction class
// This example is provided by the Geant4-DNA collaboration
// dnadamage2 example is derived from the chem6 example
// chem6 example authors: W. G. Shin and S. Incerti (CENBG, France)
//
// Any report or published results obtained using the Geant4-DNA software
// shall cite the following Geant4-DNA collaboration publication:
// J. Appl. Phys. 125 (2019) 104301
// Med. Phys. 45 (2018) e722-e739
// J. Comput. Phys. 274 (2014) 841-882
// Med. Phys. 37 (2010) 4692-4708
// Int. J. Model. Simul. Sci. Comput. 1 (2010) 157-178
// The Geant4-DNA web site is available at http://geant4-dna.org
//
// Authors: J. Naoki D. Kondo (UCSF, US)
// J. Ramos-Mendez and B. Faddegon (UCSF, US)
//
#include "DetectorConstruction.hh"
#include "ScoreLET.hh"
#include "ScoreSpecies.hh"
#include "ScoreStrandBreaks.hh"
#include "G4Box.hh"
#include "G4GeometryManager.hh"
#include "G4LogicalVolume.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4MultiFunctionalDetector.hh"
#include "G4NistManager.hh"
#include "G4PVPlacement.hh"
#include "G4PhysicalConstants.hh"
#include "G4RunManager.hh"
#include "G4SDManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4VPrimitiveScorer.hh"
#include "G4VisAttributes.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
DetectorConstruction::DetectorConstruction() : G4VUserDetectorConstruction()
{
fDetDir = new G4UIdirectory("/det/");
fDetDir->SetGuidance("Detector control.");
fSizeCmd = new G4UIcmdWithADoubleAndUnit("/det/setSize", this);
fSizeCmd->SetDefaultUnit("um");
fpOffSetFileUI = new G4UIcmdWithAString("/det/OffSetFile", this);
fpPlasmidNbUI = new G4UIcmdWithAnInteger("/det/NbOfPlasmids", this);
fpPlasmidFile = new G4UIcmdWithAString("/det/PlasmidFile", this);
fpUseDNA = new G4UIcmdWithABool("/det/UseDNAVolumes", this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
DetectorConstruction::~DetectorConstruction()
{
delete fSizeCmd;
delete fpOffSetFileUI;
delete fpPlasmidFile;
delete fpUseDNA;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void DetectorConstruction::SetNewValue(G4UIcommand* command, G4String newValue)
{
if (command == fSizeCmd) {
G4double size = fSizeCmd->GetNewDoubleValue(newValue);
SetSize(size);
}
if (command == fpPlasmidNbUI) {
fNbOfPlasmids = fpPlasmidNbUI->GetNewIntValue(newValue);
}
if (command == fpOffSetFileUI) {
G4String File = newValue;
ReadOffsetFile(File);
}
if (command == fpPlasmidFile) {
fPlasmidFile = newValue;
}
if (command == fpUseDNA) {
fUseDNAVolumes = fpUseDNA->GetNewBoolValue(newValue);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void DetectorConstruction::SetSize(G4double size)
{
G4GeometryManager::GetInstance()->OpenGeometry();
fPlasmidEnvelope->SetRadius(size / 2);
G4RunManager::GetRunManager()->GeometryHasBeenModified();
G4cout << "#### the geometry has been modified " << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4VPhysicalVolume* DetectorConstruction::Construct()
{
// Clear DNA information Containers
fSampleDNANames.clear();
fSampleDNAPositions.clear();
fSampleDNADetails.clear();
fDNANames.clear();
fDNAPositions.clear();
fDNADetails.clear();
// Water is defined from NIST material database
G4NistManager* man = G4NistManager::Instance();
G4Material* normalWater = man->FindOrBuildMaterial("G4_WATER");
G4Material* waterWorld =
man->BuildMaterialWithNewDensity("G4_WATER_WORLD", "G4_WATER", 1.0 * g / cm / cm / cm);
//
// World
G4Box* solidWenvelope = new G4Box("SWorld", 1 * um, 1 * um, 1 * um);
G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWenvelope, waterWorld, "LWorld");
G4VPhysicalVolume* physWorld =
new G4PVPlacement(0, G4ThreeVector(), "PWorld", logicWorld, 0, false, 0);
// Molecule
fPlasmidEnvelope = new G4Orb("plasmidEnvelope", 0.5 * fWorldSize);
G4LogicalVolume* tlogicPlasmid =
new G4LogicalVolume(fPlasmidEnvelope, normalWater, "PlasmidVolume");
new G4PVPlacement(0, G4ThreeVector(), tlogicPlasmid, "plasmid", logicWorld, false, 0);
// World Vis Attributes
G4VisAttributes worldVis(G4Colour(0.0, 0.0, 1.0));
logicWorld->SetVisAttributes(worldVis);
PhysGeoImport GeoImport = PhysGeoImport();
G4LogicalVolume* logicStraightVoxel;
logicStraightVoxel = GeoImport.CreateLogicVolumeXYZ(fPlasmidFile);
fSampleDNANames = GeoImport.GetMoleculesNames();
fSampleDNAPositions = GeoImport.GetMoleculesPositions();
fSampleDNADetails = GeoImport.GetMoleculesDetails();
for (int i = 0; i < fNbOfPlasmids; i++) {
if (fUseDNAVolumes)
new G4PVPlacement(0, fVOffset[i], logicStraightVoxel, "VoxelStraight", logicWorld, true, i);
AddDNAInformation(i, fVOffset[i]);
}
// always return the physical World
return physWorld;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void DetectorConstruction::ConstructSDandField()
{
G4SDManager::GetSDMpointer()->SetVerboseLevel(1);
// declare World as a MultiFunctionalDetector scorer
//
G4MultiFunctionalDetector* mfDetector = new G4MultiFunctionalDetector("mfDetector");
// LET scorer:
// - scores restricted or unrestricted LET
ScoreLET* LET = new ScoreLET("LET");
mfDetector->RegisterPrimitive(LET);
// Species scorer:
// - scores number of species over time
// - compute the radiochemical yields (G values)
G4VPrimitiveScorer* primitivSpecies = new ScoreSpecies("Species");
mfDetector->RegisterPrimitive(primitivSpecies);
// SB Scorer: Requires access to Geometry
// - scores number of Direct SB
// - scores number of Indirect SB
G4VPrimitiveScorer* primitiveSB = new ScoreStrandBreaks("StrandBreaks", this, &fWorldSize);
mfDetector->RegisterPrimitive(primitiveSB);
// Attach Detectors to Plasmid Volumes
G4LogicalVolumeStore* theLogicalVolumes = G4LogicalVolumeStore::GetInstance();
for (size_t t = 0; t < theLogicalVolumes->size(); t++) {
G4String lVolumeName = (*theLogicalVolumes)[t]->GetName();
if (lVolumeName != "LWorld") {
(*theLogicalVolumes)[t]->SetSensitiveDetector(mfDetector);
}
}
G4SDManager::GetSDMpointer()->AddNewDetector(mfDetector);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void DetectorConstruction::ReadOffsetFile(G4String file)
{
if (fVOffset.size() > 0) fVOffset.clear();
std::ifstream OffSetFile;
OffSetFile.open(file);
G4double x, y, z;
if (!OffSetFile) {
G4cout << "Plasmid Offset positions file not found!!!" << G4endl;
exit(1);
}
else {
while (OffSetFile >> x >> y >> z) {
fVOffset.push_back(G4ThreeVector(x * nm, y * nm, z * nm));
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void DetectorConstruction::AddDNAInformation(G4int copy, G4ThreeVector offset)
{
for (size_t i = 0; i < fSampleDNANames.size(); i++) {
fDNANames.push_back(fSampleDNANames[i]);
fDNAPositions.push_back(fSampleDNAPositions[i] + offset);
std::vector<G4int> Details = fSampleDNADetails[i];
Details[0] = copy;
fDNADetails.push_back(Details);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....