Files
geant4/examples/novice/N07/src/ExN07DetectorConstruction.cc
T
2016-06-09 10:15:15 +02:00

333 lines
11 KiB
C++

//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: ExN07DetectorConstruction.cc,v 1.3 2003/04/08 15:47:00 asaim Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
#include "ExN07DetectorConstruction.hh"
#include "G4RunManager.hh"
#include "G4Material.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4PVParameterised.hh"
#include "G4SDManager.hh"
#include "G4VisAttributes.hh"
#include "G4Colour.hh"
#include "G4ios.hh"
#include "ExN07DetectorMessenger.hh"
#include "ExN07CalorimeterSD.hh"
#include "ExN07GapParameterisation.hh"
#include "ExN07PrimaryGeneratorAction.hh"
ExN07DetectorConstruction::ExN07DetectorConstruction()
:numberOfLayers(40),worldMaterial(0),absorberMaterial(0),gapMaterial(0),
gapSolid(0),worldLogical(0),worldPhysical(0),serial(false)
{
for(size_t i=0;i<3;i++)
{
calorLogical[i] = 0;
layerLogical[i] = 0;
calorPhysical[i] = 0;
layerPhysical[i] = 0;
}
gapParam = new ExN07GapParameterisation;
gapParam->SetNumberOfLayers(numberOfLayers);
ExN07CalorimeterSD::SetNumberOfLayers(numberOfLayers);
DefineMaterials();
detectorMessenger = new ExN07DetectorMessenger(this);
}
ExN07DetectorConstruction::~ExN07DetectorConstruction()
{ delete detectorMessenger;}
void ExN07DetectorConstruction::DefineMaterials()
{
G4String name, symbol; //a=mass of a mole;
G4double a, z, density; //z=mean number of protons;
G4int iz, n; //iz=number of protons in an isotope;
// n=number of nucleons in an isotope;
G4int ncomponents, natoms;
G4double abundance, fractionmass;
G4double temperature, pressure;
//
// define Elements
//
a = 1.01*g/mole;
G4Element* H = new G4Element(name="Hydrogen",symbol="H" , z= 1., a);
a = 12.01*g/mole;
G4Element* C = new G4Element(name="Carbon" ,symbol="C" , z= 6., a);
a = 14.01*g/mole;
G4Element* N = new G4Element(name="Nitrogen",symbol="N" , z= 7., a);
a = 16.00*g/mole;
G4Element* O = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
//
// define an Element from isotopes, by relative abundance
//
G4Isotope* U5 = new G4Isotope(name="U235", iz=92, n=235, a=235.01*g/mole);
G4Isotope* U8 = new G4Isotope(name="U238", iz=92, n=238, a=238.03*g/mole);
G4Element* U = new G4Element(name="enriched Uranium",symbol="U",ncomponents=2);
U->AddIsotope(U5, abundance= 90.*perCent);
U->AddIsotope(U8, abundance= 10.*perCent);
//
// define simple materials
//
new G4Material(name="Aluminium", z=13., a=26.98*g/mole, density=2.700*g/cm3);
density = 1.390*g/cm3;
a = 39.95*g/mole;
G4Material* lAr = new G4Material(name="liquidArgon", z=18., a, density);
density = 11.35*g/cm3;
a = 207.19*g/mole;
G4Material* Pb = new G4Material(name="Lead" , z=82., a, density);
//
// define a material from elements. case 1: chemical molecule
//
density = 1.000*g/cm3;
G4Material* H2O = new G4Material(name="Water", density, ncomponents=2);
H2O->AddElement(H, natoms=2);
H2O->AddElement(O, natoms=1);
density = 1.032*g/cm3;
G4Material* Sci = new G4Material(name="Scintillator", density, ncomponents=2);
Sci->AddElement(C, natoms=9);
Sci->AddElement(H, natoms=10);
//
// define a material from elements. case 2: mixture by fractional mass
//
density = 1.290*mg/cm3;
G4Material* Air = new G4Material(name="Air" , density, ncomponents=2);
Air->AddElement(N, fractionmass=0.7);
Air->AddElement(O, fractionmass=0.3);
//
// examples of vacuum
//
density = universe_mean_density;
pressure = 3.e-18*pascal;
temperature = 2.73*kelvin;
G4Material* Vacuum = new G4Material(name="Galactic", z=1., a=1.01*g/mole,
density,kStateGas,temperature,pressure);
G4cout << *(G4Material::GetMaterialTable()) << G4endl;
//default materials of the calorimeter
worldMaterial = Vacuum;
absorberMaterial = Pb;
gapMaterial = lAr;
gapParam->SetAbsorberMaterial(absorberMaterial);
gapParam->SetGapMaterial(gapMaterial);
}
G4VPhysicalVolume* ExN07DetectorConstruction::Construct()
{
//
// World
//
G4VSolid* worldSolid = new G4Box("World",2.*m,2.*m,4.*m);
worldLogical = new G4LogicalVolume(worldSolid,worldMaterial,"World");
worldPhysical = new G4PVPlacement(0,G4ThreeVector(),worldLogical,"World",
0,false,0);
//
// Calorimeter
//
G4VSolid* calorSolid = new G4Box("Calor",0.5*m,0.5*m,1.*m);
G4int i;
G4String calNam[3] = {"Cal-A","Cal-B","Cal-C"};
for(i=0;i<3;i++)
{
calorLogical[i] = new G4LogicalVolume(calorSolid,absorberMaterial,calNam[i]);
if(serial)
{
calorPhysical[i] = new G4PVPlacement(0,
G4ThreeVector(0.,0.,G4double(i-1)*2.*m),
calorLogical[i],calNam[i],worldLogical,false,i);
}
else
{
calorPhysical[i] = new G4PVPlacement(0,
G4ThreeVector(0.,G4double(i-1)*m,0.),
calorLogical[i],calNam[i],worldLogical,false,i);
}
}
//
// Layers -- material is parameterised
//
gapSolid = new G4Box("Gap",0.5*m,0.5*m,1.*m/G4double(2*numberOfLayers));
for(i=0;i<3;i++)
{
layerLogical[i] = new G4LogicalVolume(gapSolid,absorberMaterial,"Layer");
layerPhysical[i] =
new G4PVParameterised("Layer",layerLogical[i],calorLogical[i],kZAxis,
2*numberOfLayers,gapParam);
}
//
// Regions
//
G4String regName[] = {"Calor-A","Calor-B","Calor-C"};
for(i=0;i<3;i++)
{
G4Region* aRegion = new G4Region(regName[i]);
calorLogical[i]->SetRegion(aRegion);
aRegion->AddRootLogicalVolume(calorLogical[i]);
}
//
// Sensitive Detectors: Absorber and Gap
//
G4SDManager* SDman = G4SDManager::GetSDMpointer();
G4String detName[] = {"CalorSD-A","CalorSD-B","CalorSD-C"};
for(i=0;i<3;i++)
{
G4VSensitiveDetector* calorSD = new ExN07CalorimeterSD(detName[i]);
SDman->AddNewDetector(calorSD);
layerLogical[i]->SetSensitiveDetector(calorSD);
}
//
// Visualization attributes
//
worldLogical->SetVisAttributes(G4VisAttributes::Invisible);
G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
simpleBoxVisAtt->SetVisibility(true);
for(i=0;i<3;i++)
{
calorLogical[i]->SetVisAttributes(simpleBoxVisAtt);
layerLogical[i]->SetVisAttributes(simpleBoxVisAtt);
}
PrintCalorParameters();
return worldPhysical;
}
void ExN07DetectorConstruction::PrintCalorParameters() const
{
G4cout << "--------------------------------------------------------" << G4endl;
if(serial)
{ G4cout << " Calorimeters are placed in serial." << G4endl; }
else
{ G4cout << " Calorimeters are placed in parallel." << G4endl; }
G4cout << " Absorber is made of " << absorberMaterial->GetName() << G4endl;
G4cout << " Gap is made of " << gapMaterial->GetName() << G4endl;
G4cout << "--------------------------------------------------------" << G4endl;
}
void ExN07DetectorConstruction::SetAbsorberMaterial(G4String materialChoice)
{
// search the material by its name
G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
if(pttoMaterial)
{
absorberMaterial = pttoMaterial;
gapParam->SetAbsorberMaterial(pttoMaterial);
for(size_t i=0;i<3;i++)
{
calorLogical[i]->SetMaterial(absorberMaterial);
layerLogical[i]->SetMaterial(absorberMaterial);
}
}
else
{ G4cerr << materialChoice << " is not defined. - Command is ignored." << G4endl; }
}
G4String ExN07DetectorConstruction::GetAbsorberMaterial() const
{ return absorberMaterial->GetName(); }
void ExN07DetectorConstruction::SetGapMaterial(G4String materialChoice)
{
// search the material by its name
G4Material* pttoMaterial = G4Material::GetMaterial(materialChoice);
if(pttoMaterial)
{
gapMaterial = pttoMaterial;
gapParam->SetGapMaterial(pttoMaterial);
}
else
{ G4cerr << materialChoice << " is not defined. - Command is ignored." << G4endl; }
}
G4String ExN07DetectorConstruction::GetGapMaterial() const
{ return gapMaterial->GetName(); }
void ExN07DetectorConstruction::SetSerialGeometry(G4bool ser)
{
if(serial==ser) return;
serial=ser;
for(G4int i=0;i<3;i++)
{
if(serial)
{ calorPhysical[i]->SetTranslation(G4ThreeVector(0.,0.,G4double(i-1)*2.*m)); }
else
{ calorPhysical[i]->SetTranslation(G4ThreeVector(0.,G4double(i-1)*m,0.)); }
}
ExN07PrimaryGeneratorAction* gen = (ExN07PrimaryGeneratorAction*)
G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction();
gen->SetSerial(serial);
G4RunManager::GetRunManager()->GeometryHasBeenModified();
}
void ExN07DetectorConstruction::SetNumberOfLayers(G4int nl)
{
numberOfLayers = nl;
gapSolid->SetZHalfLength(1.*m/G4double(2*numberOfLayers));
gapParam->SetNumberOfLayers(nl);
for(size_t i=0;i<3;i++)
{
if(layerPhysical[i])
{
calorLogical[i]->RemoveDaughter(layerPhysical[i]);
delete layerPhysical[i];
}
layerPhysical[i] =
new G4PVParameterised("Layer",layerLogical[i],calorLogical[i],kZAxis,
2*numberOfLayers,gapParam);
}
ExN07CalorimeterSD::SetNumberOfLayers(nl);
G4RunManager::GetRunManager()->GeometryHasBeenModified();
}