Files
geant4/examples/extended/medical/electronScattering/src/DetectorConstruction.cc
T
2016-06-10 12:08:39 +02:00

525 lines
21 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 medical/electronScattering/src/DetectorConstruction.cc
/// \brief Implementation of the DetectorConstruction class
//
// $Id: DetectorConstruction.cc 86064 2014-11-07 08:49:32Z gcosmo $
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "DetectorConstruction.hh"
#include "DetectorMessenger.hh"
#include "G4Material.hh"
#include "G4Tubs.hh"
#include "G4LogicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4GeometryManager.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4SolidStore.hh"
#include "G4UnitsTable.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::DetectorConstruction()
:fMaterial_World(0), fMaterial_Frame(0),
fMaterial_ExitWindow(0), fMaterial_ScatterFoil(0), fMaterial_MonitorChbr(0),
fMaterial_Bag(0), fMaterial_Gas(0), fMaterial_Ring(0),
fPvol_World(0), fPvol_Frame(0), fDetectorMessenger(0)
{
// materials
DefineMaterials();
// geometry
GeometryParameters();
// create commands for interactive definition of the calorimeter
fDetectorMessenger = new DetectorMessenger(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
DetectorConstruction::~DetectorConstruction()
{
delete fDetectorMessenger;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::Construct()
{
return ConstructVolumes();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::DefineMaterials()
{
G4double a, z, density;
G4int ncomponents, natoms;
G4double fractionmass;
G4double temperature, pressure;
// define Elements
//
G4Element* H = new G4Element("Hydrogen", "H", z= 1, a= 1.0079*g/mole);
G4Element* He = new G4Element("Helium", "He", z= 2, a= 4.0026*g/mole);
G4Element* Be = new G4Element("Beryllium","Be", z= 4, a= 9.1218*g/mole);
G4Element* C = new G4Element("Carbon", "C", z= 6, a= 12.0107*g/mole);
G4Element* N = new G4Element("Nitrogen", "N", z= 7, a= 14.0067*g/mole);
G4Element* O = new G4Element("Oxygen", "O", z= 8, a= 15.9994*g/mole);
G4Element* Al = new G4Element("Aluminium","Al", z=13, a= 26.9815*g/mole);
G4Element* Ar = new G4Element("Argon", "Ar", z=18, a= 39.9480*g/mole);
G4Element* Ti = new G4Element("Titanium", "Ti", z=22, a= 47.8670*g/mole);
G4Element* Va = new G4Element("Vanadium", "Va", z=23, a= 50.9415*g/mole);
G4Element* Cu = new G4Element("Copper", "Cu", z=29, a= 63.5460*g/mole);
G4Element* Ta = new G4Element("Tantalum", "Ta", z=73, a= 180.9479*g/mole);
G4Element* Au = new G4Element("Gold", "Au", z=79, a= 196.9666*g/mole);
// Air
//
G4Material* Air =
new G4Material("Air", density= 1.205*mg/cm3, ncomponents=4,
kStateGas, 293.*kelvin, 1.*atmosphere);
Air->AddElement(C, fractionmass=0.000124);
Air->AddElement(N, fractionmass=0.755267);
Air->AddElement(O, fractionmass=0.231782);
Air->AddElement(Ar,fractionmass=0.012827);
// Titanium
//
G4Material* Titanium =
new G4Material("Titanium", density= 4.42*g/cm3, ncomponents=3);
Titanium->AddElement(Ti, fractionmass=0.90);
Titanium->AddElement(Al, fractionmass=0.06);
Titanium->AddElement(Va, fractionmass=0.04);
// Mylar
//
G4Material* Mylar =
new G4Material("Mylar", density= 1.40*g/cm3, ncomponents=3);
Mylar->AddElement(H, natoms=4);
Mylar->AddElement(C, natoms=5);
Mylar->AddElement(O, natoms=2);
// Helium
//
G4Material* Helium =
new G4Material("Helium", density= 0.166*mg/cm3, ncomponents=1,
kStateGas, 293.*kelvin, 1.*atmosphere);
Helium->AddElement(He, fractionmass=1.0);
// Aluminium
//
G4Material* Aluminium =
new G4Material("Aluminium", density= 2.7*g/cm3, ncomponents=1);
Aluminium->AddElement(Al, fractionmass=1.0);
// Beryllium
//
G4Material* Beryllium =
new G4Material("Beryllium", density= 1.85*g/cm3, ncomponents=1);
Beryllium->AddElement(Be, fractionmass=1.0);
//Graphite
//
G4Material* Graphite =
new G4Material("Graphite", density= 2.18*g/cm3, ncomponents=1);
Graphite->AddElement(C, fractionmass=1.0);
// Copper
//
G4Material* Copper =
new G4Material("Copper", density= 8.92*g/cm3, ncomponents=1);
Copper->AddElement(Cu, fractionmass=1.0);
// Tantalum
//
G4Material* Tantalum =
new G4Material("Tantalum", density= 16.65*g/cm3, ncomponents=1);
Tantalum->AddElement(Ta, fractionmass=1.0);
// Gold
//
G4Material* Gold =
new G4Material("Gold", density= 19.30*g/cm3, ncomponents=1);
Gold->AddElement(Au, fractionmass=1.0);
// example of vacuum
//
density = universe_mean_density; //from PhysicalConstants.h
pressure = 3.e-18*pascal;
temperature = 2.73*kelvin;
G4Material* Vacuum =
new G4Material("Galactic", z=1, a=1.01*g/mole,density,
kStateGas,temperature,pressure);
//print
//
G4cout << *(G4Material::GetMaterialTable()) << G4endl;
// assign materials
//
fMaterial_World = Vacuum;
fMaterial_Frame = Air;
fMaterial_ExitWindow = Titanium;
fMaterial_ScatterFoil = fMaterial_Frame;
fMaterial_MonitorChbr = Mylar;
fMaterial_Bag = Mylar;
fMaterial_Gas = Helium;
fMaterial_Ring = Aluminium;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::GeometryParameters()
{
fZfront_ExitWindow = 0.0*um;
fThickness_ExitWindow = 41.2*um;
fZfront_ScatterFoil = 2.65*cm;
fThickness_ScatterFoil = 0.0*um;
fZfront_MonitorChbr = 50.*mm;
fThickness_MonitorChbr = 112.7*um;
fZfront_Bag = 64.975*mm;
fThickness_Bag = 110.0050*cm;
fThickness_Gas = 110.*cm;
fThickness_Ring = 14.*mm;
fInnerRadius_Ring = 20.*cm;
fZfront_Frame = 2.0*um;
fThickness_Frame = 118.2*cm;
fThickness_World = fZfront_Frame + fThickness_Frame;
fRadius_World = 23.3*cm;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VPhysicalVolume* DetectorConstruction::ConstructVolumes()
{
// Cleanup old geometry
//
G4GeometryManager::GetInstance()->OpenGeometry();
G4PhysicalVolumeStore::GetInstance()->Clean();
G4LogicalVolumeStore::GetInstance()->Clean();
G4SolidStore::GetInstance()->Clean();
// World
//
G4Tubs*
svol_World = new G4Tubs("World", //name
0*cm, fRadius_World, //r1, r2
0.5*fThickness_World, //half-length
0., twopi); //theta1, theta2
G4LogicalVolume*
lvol_World = new G4LogicalVolume(svol_World, //its solid
fMaterial_World, //its material
"World"); //its name
fPvol_World = new G4PVPlacement(0, //no rotation
G4ThreeVector(), //no translation
lvol_World, //its logical volume
"World", //its name
0, //its mother volume
false, //no boolean operation
0); //copy number
// Frame
//
G4Tubs*
svol_Frame = new G4Tubs("Frame", //name
0*cm, fRadius_World, //r1, r2
0.5*fThickness_Frame, //half-length
0., twopi); //theta1, theta2
G4LogicalVolume*
lvol_Frame = new G4LogicalVolume(svol_Frame, //its solid
fMaterial_Frame, //its material
"Frame"); //its name
G4double
zpos = fZfront_Frame;
fPvol_Frame = new G4PVPlacement(0, //no rotation
G4ThreeVector(0,0,zpos), //translation
lvol_Frame, //its logical volume
"Frame", //its name
lvol_World, //its mother volume
false, //no boolean operation
0); //copy number
// ExitWindow
//
G4Tubs*
svol_ExitWindow = new G4Tubs("ExitWindow", //name
0*cm, fRadius_World, //r1, r2
0.5*fThickness_ExitWindow, //half-length
0., twopi); //theta1, theta2
G4LogicalVolume*
lvol_ExitWindow = new G4LogicalVolume(svol_ExitWindow, //solid
fMaterial_ExitWindow, //material
"ExitWindow"); //name
zpos = fZfront_ExitWindow + 0.5*fThickness_ExitWindow - 0.5*fThickness_Frame;
new G4PVPlacement(0, //no rotation
G4ThreeVector(0,0,zpos), //translation
lvol_ExitWindow, //logical volume
"ExitWindow", //name
lvol_Frame, //mother volume
false, //no boolean operation
0); //copy number
// Monitor Chamber
//
G4Tubs*
svol_MonitorChbr = new G4Tubs("MonitorChbr", //name
0*cm, fRadius_World, //r1, r2
0.5*fThickness_MonitorChbr, //half-length
0., twopi); //theta1, theta2
G4LogicalVolume*
lvol_MonitorChbr = new G4LogicalVolume(svol_MonitorChbr,//solid
fMaterial_MonitorChbr, //material
"MonitorChbr"); //name
zpos = fZfront_MonitorChbr + 0.5*fThickness_MonitorChbr - 0.5*fThickness_Frame;
new G4PVPlacement(0, //no rotation
G4ThreeVector(0,0,zpos), //translation
lvol_MonitorChbr, //logical volume
"MonitorChbr", //name
lvol_Frame, //mother volume
false, //no boolean operation
0); //copy number
// Bag
//
G4Tubs*
svol_Bag = new G4Tubs("Bag", //name
0*cm, fRadius_World, //r1, r2
0.5*fThickness_Bag, //half-length
0., twopi); //theta1, theta2
G4LogicalVolume*
lvol_Bag = new G4LogicalVolume(svol_Bag, //solid
fMaterial_Bag, //material
"Bag"); //name
zpos = fZfront_Bag + 0.5*fThickness_Bag - 0.5*fThickness_Frame;
new G4PVPlacement(0, //no rotation
G4ThreeVector(0,0,zpos), //translation
lvol_Bag, //logical volume
"Bag", //name
lvol_Frame, //mother volume
false, //no boolean operation
0); //copy number
// Gas
//
G4Tubs*
svol_Gas = new G4Tubs("Gas", //name
0*cm, fRadius_World, //r1, r2
0.5*fThickness_Gas, //half-length
0., twopi); //theta1, theta2
G4LogicalVolume*
lvol_Gas = new G4LogicalVolume(svol_Gas, //solid
fMaterial_Gas, //material
"Gas"); //name
new G4PVPlacement(0, //no rotation
G4ThreeVector(), //no translation
lvol_Gas, //logical volume
"Gas", //name
lvol_Bag, //mother volume
false, //no boolean operation
0); //copy number
// Rings
//
G4Tubs*
svol_Ring = new G4Tubs("Ring", //name
fInnerRadius_Ring, fRadius_World, //r1, r2
0.5*fThickness_Ring, //half-length
0., twopi); //theta1, theta2
G4LogicalVolume*
lvol_Ring = new G4LogicalVolume(svol_Ring, //solid
fMaterial_Ring, //material
"Ring"); //name
zpos = 0.5*(fThickness_Gas - fThickness_Ring);
new G4PVPlacement(0, //no rotation
G4ThreeVector(0,0,zpos), //translation
lvol_Ring, //logical volume
"Ring", //name
lvol_Gas, //mother volume
false, //no boolean operation
1); //copy number
new G4PVPlacement(0, //no rotation
G4ThreeVector(0,0,-zpos), //translation
lvol_Ring, //logical volume
"Ring", //name
lvol_Gas, //mother volume
false, //no boolean operation
2); //copy number
// ScatterFoil (only if it is not Air)
//
if ((fMaterial_ScatterFoil != fMaterial_Frame) && (fThickness_ScatterFoil > 0.))
{
G4Tubs*
svol_ScatterFoil = new G4Tubs("ScatterFoil", //name
0*cm, fRadius_World, //r1, r2
0.5*fThickness_ScatterFoil, //half-length
0., twopi); //theta1, theta2
G4LogicalVolume*
lvol_ScatterFoil = new G4LogicalVolume(svol_ScatterFoil,//solid
fMaterial_ScatterFoil, //material
"ScatterFoil"); //name
zpos = fZfront_ScatterFoil + 0.5*fThickness_ScatterFoil - 0.5*fThickness_Frame;
new G4PVPlacement(0, //no rotation
G4ThreeVector(0,0,zpos), //translation
lvol_ScatterFoil, //logical volume
"ScatterFoil", //name
lvol_Frame, //mother volume
false, //no boolean operation
0); //copy number
}
PrintGeometry();
//always return the physical World
//
return fPvol_World;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::PrintGeometry()
{
// choose printing format
std::ios::fmtflags mode = G4cout.flags();
G4cout.setf(std::ios::fixed,std::ios::floatfield);
G4int prec = G4cout.precision(6);
G4cout << "\n \t \t" << "Material \t" << "Z_front \t" << "Thickness \n";
G4cout << "\n ExitWindow \t" << fMaterial_ExitWindow->GetName()
<< "\t" << G4BestUnit(fZfront_ExitWindow,"Length")
<< "\t" << G4BestUnit(fThickness_ExitWindow,"Length");
if (fMaterial_ScatterFoil != fMaterial_Frame) {
G4cout << "\n ScatterFoil \t" << fMaterial_ScatterFoil->GetName() << "\t"
<< "\t" << G4BestUnit(fZfront_ScatterFoil,"Length")
<< "\t" << G4BestUnit(fThickness_ScatterFoil,"Length");
}
G4cout << "\n MonitorChbr \t" << fMaterial_MonitorChbr->GetName() << "\t"
<< "\t" << G4BestUnit(fZfront_MonitorChbr,"Length")
<< "\t" << G4BestUnit(fThickness_MonitorChbr,"Length");
G4double thickBagWindow = 0.5*(fThickness_Bag - fThickness_Gas);
G4double zfrontGas = fZfront_Bag + thickBagWindow;
G4double zfrontBagWindow2 = zfrontGas + fThickness_Gas;
G4cout << "\n BagWindow1 \t" << fMaterial_Bag->GetName() << "\t"
<< "\t" << G4BestUnit(fZfront_Bag,"Length")
<< "\t" << G4BestUnit(thickBagWindow,"Length");
G4cout << "\n Gas \t" << fMaterial_Gas->GetName() << "\t"
<< "\t" << G4BestUnit(zfrontGas,"Length")
<< "\t" << G4BestUnit(fThickness_Gas,"Length");
G4cout << "\n BagWindow2 \t" << fMaterial_Bag->GetName() << "\t"
<< "\t" << G4BestUnit(zfrontBagWindow2,"Length")
<< "\t" << G4BestUnit(thickBagWindow,"Length");
G4cout << "\n ScoringPlane \t" << fMaterial_Frame->GetName() << "\t"
<< "\t" << G4BestUnit(fThickness_Frame,"Length") << "\n" << G4endl;
// restaure default formats
G4cout.setf(mode,std::ios::floatfield);
G4cout.precision(prec);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetMaterialScatter(G4String material)
{
// search the material by its name
G4Material* pMaterial = G4Material::GetMaterial(material);
if (pMaterial) fMaterial_ScatterFoil = pMaterial;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void DetectorConstruction::SetThicknessScatter(G4double val)
{
fThickness_ScatterFoil = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
#include "G4RunManager.hh"
void DetectorConstruction::UpdateGeometry()
{
G4RunManager::GetRunManager()->DefineWorldVolume(ConstructVolumes());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......