333 lines
11 KiB
C++
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();
|
|
}
|
|
|