525 lines
21 KiB
C++
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......
|
|
|