463 lines
15 KiB
C++
463 lines
15 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: MedLinacDetectorConstruction.cc,v 1.6 2004/11/24 16:53:29 mpiergen Exp $
|
|
//
|
|
// Code developed by: M. Piergentili
|
|
//
|
|
//
|
|
//------------------------------ beam line along z axis---------------------
|
|
|
|
#include "MedLinacDetectorMessenger.hh"
|
|
#include "MedLinacDetectorConstruction.hh"
|
|
#include "MedLinacPhantomROGeometry.hh"
|
|
#include "MedLinacPhantomSD.hh"
|
|
#include "MedLinacVGeometryComponent.hh"
|
|
#include "MedLinacHead.hh"
|
|
#include "MedLinacDecorator.hh"
|
|
#include "MedLinacTargetAndFilterDecorator.hh"
|
|
#include "MedLinacMLCDecorator.hh"
|
|
#include "G4CSGSolid.hh"
|
|
#include "G4RotationMatrix.hh"
|
|
#include "G4Transform3D.hh"
|
|
#include "G4Material.hh"
|
|
#include "G4MaterialPropertiesTable.hh"
|
|
#include "G4MaterialTable.hh"
|
|
#include "G4MaterialPropertyVector.hh"
|
|
#include "G4Element.hh"
|
|
#include "G4ElementTable.hh"
|
|
#include "G4Box.hh"
|
|
#include "G4Cons.hh"
|
|
#include "G4Tubs.hh"
|
|
#include "G4LogicalVolume.hh"
|
|
#include "G4ThreeVector.hh"
|
|
#include "G4PVPlacement.hh"
|
|
#include "G4PVParameterised.hh"
|
|
#include "globals.hh"
|
|
#include "G4SDManager.hh"
|
|
#include "G4RunManager.hh"
|
|
#include "Randomize.hh"
|
|
#include "G4TransportationManager.hh"
|
|
#include "G4UserLimits.hh"
|
|
#include "G4GeometryManager.hh"
|
|
#include "G4BooleanSolid.hh"
|
|
#include "G4SubtractionSolid.hh"
|
|
#include "G4VSolid.hh"
|
|
#include "G4Region.hh"
|
|
|
|
#include "G4PhysicalVolumeStore.hh"
|
|
#include "G4LogicalVolumeStore.hh"
|
|
#include "G4SolidStore.hh"
|
|
#include "G4RegionStore.hh"
|
|
|
|
#include "G4VisAttributes.hh"
|
|
#include "G4Colour.hh"
|
|
|
|
#include "G4ios.hh"
|
|
|
|
MedLinacDetectorConstruction::MedLinacDetectorConstruction(G4String SDName)
|
|
: phantomSD(0),phantomROGeometry(0),
|
|
experimentalHall_log(0),vacuumBlock_log(0),
|
|
JawY1_log(0),JawY2_log(0),
|
|
JawX1_log(0),JawX2_log(0),
|
|
Phantom_log(0),
|
|
experimentalHall_phys(0),vacuumBlock_phys(0),
|
|
JawY1_phys(0), JawY2_phys(0),
|
|
JawX1_phys(0), JawX2_phys(0),
|
|
Phantom_phys(0)
|
|
{
|
|
numberOfVoxelsAlongX=300;
|
|
numberOfVoxelsAlongY=300;
|
|
numberOfVoxelsAlongZ=300;
|
|
|
|
ComputeDimVoxel();
|
|
|
|
sensitiveDetectorName = SDName;
|
|
|
|
// default parameter values
|
|
|
|
fieldX1 = -10.*cm;
|
|
fieldX2 = 10.*cm;
|
|
fieldY1 = -10.*cm;
|
|
fieldY2 = 10.*cm;
|
|
|
|
|
|
detectorMessenger = new MedLinacDetectorMessenger(this);
|
|
pHead = new MedLinacHead();
|
|
decorator = new MedLinacTargetAndFilterDecorator(pHead);
|
|
decorator1 = new MedLinacMLCDecorator(pHead);
|
|
}
|
|
|
|
MedLinacDetectorConstruction* MedLinacDetectorConstruction::instance = 0;
|
|
|
|
MedLinacDetectorConstruction* MedLinacDetectorConstruction::GetInstance(G4String SDName)
|
|
{
|
|
if (instance == 0)
|
|
{
|
|
instance = new MedLinacDetectorConstruction(SDName);
|
|
|
|
}
|
|
return instance;
|
|
}
|
|
|
|
MedLinacDetectorConstruction::~MedLinacDetectorConstruction()
|
|
{
|
|
delete detectorMessenger;
|
|
delete pHead;
|
|
delete decorator;
|
|
delete decorator1;
|
|
}
|
|
|
|
G4VPhysicalVolume* MedLinacDetectorConstruction::Construct()
|
|
{
|
|
return ConstructGeom();
|
|
}
|
|
|
|
G4VPhysicalVolume* MedLinacDetectorConstruction::ConstructGeom ()
|
|
{
|
|
|
|
// Cleanup old geometry
|
|
|
|
G4GeometryManager::GetInstance()->OpenGeometry();
|
|
G4PhysicalVolumeStore::GetInstance()->Clean();
|
|
G4LogicalVolumeStore::GetInstance()->Clean();
|
|
G4SolidStore::GetInstance()->Clean();
|
|
|
|
// materials
|
|
|
|
G4double a; // atomic mass
|
|
G4double z; // atomic number
|
|
G4double density;
|
|
G4int ncomponents;
|
|
G4int natoms;
|
|
G4String name;
|
|
G4String symbol;
|
|
G4double fractionmass;
|
|
G4double massOfMole;
|
|
G4double pressure;
|
|
G4double temperature;
|
|
|
|
a = 14.00674*g/mole;
|
|
G4Element* elN = new G4Element(name="Nitrogen" ,symbol="N", z=7., a);
|
|
|
|
a = 16.00*g/mole;
|
|
G4Element* elO = new G4Element(name="Oxygen",symbol="O", z=8., a);
|
|
|
|
a = 1.00794*g/mole;
|
|
G4Element* elH = new G4Element(name="Hydrogen",symbol="H", z=1., a);
|
|
|
|
density = 1.290*mg/cm3;
|
|
G4Material* Air = new G4Material(name="Air",density, ncomponents=2);
|
|
Air->AddElement(elN, fractionmass=70*perCent);
|
|
Air->AddElement(elO, fractionmass=30*perCent);
|
|
|
|
density = 1.000*g/cm3;
|
|
G4Material* H2O = new G4Material(name="Water",density, ncomponents=2);
|
|
H2O->AddElement(elH, natoms=2);
|
|
H2O->AddElement(elO, natoms=1);
|
|
|
|
a = 207.19*g/mole;
|
|
density = 11.35*g/cm3;
|
|
G4Material* Pb = new G4Material(name="Lead", z=82., a, density);
|
|
|
|
massOfMole = 1.008*g/mole;
|
|
density = 1.e-25*g/cm3;
|
|
temperature = 2.73*kelvin;
|
|
pressure = 3.e-18*pascal;
|
|
G4Material* Vacuum = new G4Material("interGalactic", z=1.,massOfMole,
|
|
density, kStateGas,temperature, pressure);
|
|
|
|
//------------------------------ beam line along z axis------------------
|
|
|
|
//---------jaws position--------
|
|
|
|
//----1Y------------------------
|
|
|
|
G4double thetaY1 = std::atan(-fieldY1/(100.*cm));// in rad
|
|
G4double JawY1Pos_y = -((3.9*cm+28.*cm)*std::sin(thetaY1)+5.*cm*std::cos(thetaY1));
|
|
G4double JawY1Pos_z =115.*cm-((3.9*cm+28.*cm)*std::cos(thetaY1))+5.*cm*std::sin(thetaY1);
|
|
//----2Y-------------------------
|
|
G4double thetaY2 = std::atan(fieldY2/(100.*cm)); // in rad
|
|
G4double JawY2Pos_y = (3.9*cm+28.*cm)*std::sin(thetaY2)+5.*cm*std::cos(thetaY2);
|
|
G4double JawY2Pos_z = 115.*cm-(3.9*cm+28.*cm)*std::cos(thetaY2)+5.*cm*std::sin(thetaY2);
|
|
//----1X-------------------------
|
|
G4double thetaX1 = std::atan(-fieldX1/(100.*cm));
|
|
G4double JawX1Pos_x = -((36.7*cm+3.9*cm)*std::sin(thetaX1)+5.*cm*std::cos(thetaX1));
|
|
G4double JawX1Pos_z =115.*cm-(36.7*cm+3.9*cm)*std::cos(thetaX1)+5.*cm*std::sin(thetaX1);
|
|
//----2X-------------------------
|
|
G4double thetaX2 = std::atan(fieldX2/(100.*cm));
|
|
G4double JawX2Pos_x = (36.7*cm+3.9*cm)*std::sin(thetaX2)+5.*cm*std::cos(thetaX2);
|
|
G4double JawX2Pos_z = 115.*cm-(36.7*cm+3.9*cm)*std::cos(thetaX2)+5.*cm*std::sin(thetaX2);
|
|
//---------rotation jaw1Y--------
|
|
|
|
G4RotationMatrix* rotatejaw1Y=new G4RotationMatrix();
|
|
rotatejaw1Y->rotateX(thetaY1);
|
|
|
|
//---------rotation jaw2Y--------
|
|
|
|
G4RotationMatrix* rotatejaw2Y=new G4RotationMatrix();
|
|
rotatejaw2Y->rotateX(-thetaY2);
|
|
|
|
//---------rotation jaw1X--------
|
|
|
|
G4RotationMatrix* rotatejaw1X=new G4RotationMatrix();
|
|
rotatejaw1X->rotateY(-thetaX1);
|
|
|
|
//---------rotation jaw2X--------
|
|
|
|
G4RotationMatrix* rotatejaw2X=new G4RotationMatrix();
|
|
rotatejaw2X->rotateY(thetaX2);
|
|
|
|
//---------------colors----------
|
|
|
|
G4Colour white (1.0, 1.0, 1.0);
|
|
G4Colour magenta (1.0, 0.0, 1.0);
|
|
G4Colour lblue (0.20, .50, .85);
|
|
|
|
//------------------------------------------------------ volumes
|
|
|
|
//------------------------------ beam line along z axis-------SSD=100cm--------------
|
|
|
|
//------------------------------ experimental hall (world volume)
|
|
G4double expHall_x = 3.0*m;
|
|
G4double expHall_y = 3.0*m;
|
|
G4double expHall_z = 3.0*m;
|
|
G4Box* experimentalHall_box
|
|
= new G4Box("expHall_box",expHall_x,expHall_y,expHall_z);
|
|
experimentalHall_log = new G4LogicalVolume(experimentalHall_box,
|
|
Air,"expHall_log",0,0,0);
|
|
experimentalHall_phys = new G4PVPlacement(0,G4ThreeVector(),
|
|
"expHall",experimentalHall_log,0,false,0);
|
|
|
|
|
|
|
|
//------------------------vacuum box------------------------
|
|
|
|
G4double vacudim_x = 9.*cm;
|
|
G4double vacudim_y = 9.*cm;
|
|
G4double vacudim_z = 8.755*cm;
|
|
G4Box* vacuumBlock_box = new G4Box("vacuumBlock_box",vacudim_x,
|
|
vacudim_y,vacudim_z);
|
|
vacuumBlock_log = new G4LogicalVolume(vacuumBlock_box,
|
|
Vacuum,"vacuumBlock_log",0,0,0);
|
|
G4double vacublockPos_x = 0.0*m;
|
|
G4double vacublockPos_y = 0.0*m;
|
|
G4double vacublockPos_z = 114.755*cm;
|
|
vacuumBlock_phys = new G4PVPlacement(0,
|
|
G4ThreeVector(vacublockPos_x,vacublockPos_y,vacublockPos_z),
|
|
"vacuBlock",vacuumBlock_log,experimentalHall_phys,false,0);
|
|
|
|
|
|
//----------------Jaw Y1 collimator---------------
|
|
|
|
G4double JawY1Dim_x = 10.0*cm;
|
|
G4double JawY1Dim_y = 5.0*cm;
|
|
G4double JawY1Dim_z = 2.5*cm;
|
|
G4Box* JawY1 = new G4Box("JawY1",JawY1Dim_x,
|
|
JawY1Dim_y,JawY1Dim_z);
|
|
JawY1_log = new G4LogicalVolume(JawY1,
|
|
Pb,"JawY1_log",0,0,0);
|
|
|
|
|
|
|
|
G4double JawY1Pos_x = 0.0*cm;
|
|
JawY1_phys = new G4PVPlacement(rotatejaw1Y,
|
|
G4ThreeVector(JawY1Pos_x,JawY1Pos_y,JawY1Pos_z),
|
|
"JawY1",JawY1_log,experimentalHall_phys,false,0);
|
|
|
|
//----------------Jaw Y2 collimator---------------
|
|
|
|
G4double JawY2Dim_x = 10.0*cm;
|
|
G4double JawY2Dim_y = 5.0*cm;
|
|
G4double JawY2Dim_z = 2.5*cm;
|
|
G4Box* JawY2 = new G4Box("JawY2",JawY2Dim_x,
|
|
JawY2Dim_y,JawY2Dim_z);
|
|
JawY2_log = new G4LogicalVolume(JawY2,
|
|
Pb,"JawY1_log",0,0,0);
|
|
G4double JawY2Pos_x = 0.0*cm;
|
|
JawY2_phys = new G4PVPlacement(rotatejaw2Y,
|
|
G4ThreeVector(JawY2Pos_x,JawY2Pos_y,JawY2Pos_z),
|
|
"JawY2",JawY2_log,experimentalHall_phys,false,0);
|
|
|
|
|
|
//----------------Jaw X1 collimator---------------
|
|
|
|
G4double JawX1Dim_x = 5.0*cm;
|
|
G4double JawX1Dim_y = 10.0*cm;
|
|
G4double JawX1Dim_z = 2.5*cm;
|
|
G4Box* JawX1 = new G4Box("JawX1",JawX1Dim_x,
|
|
JawX1Dim_y,JawX1Dim_z);
|
|
JawX1_log = new G4LogicalVolume(JawX1,
|
|
Pb,"JawX1_log",0,0,0);
|
|
|
|
G4double JawX1Pos_y = 0.0*cm;
|
|
JawX1_phys = new G4PVPlacement(rotatejaw1X,
|
|
G4ThreeVector(JawX1Pos_x,JawX1Pos_y,JawX1Pos_z),
|
|
"JawX1",JawX1_log,experimentalHall_phys,false,0);
|
|
|
|
//----------------Jaw X2 collimator---------------
|
|
|
|
G4double JawX2Dim_x = 5.0*cm;
|
|
G4double JawX2Dim_y = 10.0*cm;
|
|
G4double JawX2Dim_z = 2.5*cm;
|
|
G4Box* JawX2 = new G4Box("JawX2",JawX2Dim_x,
|
|
JawX2Dim_y,JawX2Dim_z);
|
|
JawX2_log = new G4LogicalVolume(JawX2,
|
|
Pb,"JawX1_log",0,0,0);
|
|
G4double JawX2Pos_y = 0.0*cm;
|
|
JawX2_phys = new G4PVPlacement(rotatejaw2X,
|
|
G4ThreeVector(JawX2Pos_x,JawX2Pos_y,JawX2Pos_z),
|
|
"JawX2",JawX2_log,experimentalHall_phys,false,0);
|
|
|
|
//----------------Phantom---------
|
|
phantomDim_x = 15.*cm;
|
|
phantomDim_y = 15.*cm;
|
|
phantomDim_z = 15.*cm;
|
|
G4Box* Phantom = new G4Box("Phantom",phantomDim_x,
|
|
phantomDim_y,phantomDim_z);
|
|
Phantom_log = new G4LogicalVolume(Phantom,
|
|
H2O,"Phantom_log",0,0,0);
|
|
G4double PhantomPos_x = 0.0*m;
|
|
G4double PhantomPos_y = 0.0*m;
|
|
G4double PhantomPos_z = 0.0*cm;
|
|
Phantom_phys = new G4PVPlacement(0,
|
|
G4ThreeVector(PhantomPos_x,PhantomPos_y,PhantomPos_z),
|
|
"Phantom_phys",Phantom_log,experimentalHall_phys,false,0);
|
|
|
|
PrintParameters();
|
|
|
|
//--------- Visualization attributes -------------------------------
|
|
|
|
|
|
|
|
G4VisAttributes* simpleH2OVisAtt= new G4VisAttributes(lblue);
|
|
simpleH2OVisAtt->SetVisibility(true);
|
|
simpleH2OVisAtt->SetForceSolid(true);
|
|
Phantom_log->SetVisAttributes(simpleH2OVisAtt);
|
|
|
|
G4VisAttributes* simpleVacuumWVisAtt= new G4VisAttributes(white);
|
|
simpleVacuumWVisAtt->SetVisibility(true);
|
|
simpleVacuumWVisAtt->SetForceWireframe(true);
|
|
vacuumBlock_log->SetVisAttributes(simpleVacuumWVisAtt);
|
|
|
|
G4VisAttributes* simpleLeadSVisAtt= new G4VisAttributes(magenta);
|
|
simpleLeadSVisAtt->SetVisibility(true);
|
|
simpleLeadSVisAtt->SetForceSolid(true);
|
|
JawY1_log->SetVisAttributes(simpleLeadSVisAtt);
|
|
JawY2_log->SetVisAttributes(simpleLeadSVisAtt);
|
|
JawX1_log->SetVisAttributes(simpleLeadSVisAtt);
|
|
JawX2_log->SetVisAttributes(simpleLeadSVisAtt);
|
|
|
|
|
|
G4VisAttributes* simpleWorldVisAtt= new G4VisAttributes(white);
|
|
simpleWorldVisAtt->SetVisibility(false);
|
|
experimentalHall_log ->SetVisAttributes(simpleWorldVisAtt);
|
|
|
|
//if you want not to see phantom, jaws e vacuum ...:
|
|
|
|
//Phantom_log->SetVisAttributes(simpleWorldVisAtt);
|
|
//JawY1_log->SetVisAttributes(simpleWorldVisAtt);
|
|
//JawY2_log->SetVisAttributes(simpleWorldVisAtt);
|
|
//JawX1_log->SetVisAttributes(simpleWorldVisAtt);
|
|
//JawX2_log->SetVisAttributes(simpleWorldVisAtt);
|
|
vacuumBlock_log->SetVisAttributes(simpleWorldVisAtt);
|
|
|
|
// Sets a max Step length in the detector
|
|
G4double maxStep = 0.1*mm;
|
|
Phantom_log->SetUserLimits(new G4UserLimits(maxStep));
|
|
|
|
ConstructVolume();
|
|
|
|
ConstructSensitiveDetector();
|
|
return experimentalHall_phys;
|
|
}
|
|
|
|
void MedLinacDetectorConstruction::PrintParameters()
|
|
{
|
|
G4cout <<"jaws1 x position "<< fieldX1/cm << " cm "<<G4endl ;
|
|
G4cout <<"jaws2 x position "<< fieldX2/cm << " cm "<<G4endl ;
|
|
G4cout <<"jaws1 y position "<< fieldY1/cm << " cm "<<G4endl ;
|
|
G4cout <<"jaws2 y position "<< fieldY2/cm << " cm "<<G4endl ;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MedLinacDetectorConstruction::SetJawX1Pos_x (G4double val)
|
|
{
|
|
fieldX1 = val;
|
|
}
|
|
|
|
|
|
void MedLinacDetectorConstruction::SetJawX2Pos_x (G4double val)
|
|
{
|
|
fieldX2 = val;
|
|
}
|
|
|
|
void MedLinacDetectorConstruction::SetJawY1Pos_y (G4double val)
|
|
{
|
|
fieldY1 = val;
|
|
}
|
|
|
|
void MedLinacDetectorConstruction::SetJawY2Pos_y (G4double val)
|
|
{
|
|
fieldY2 = val;
|
|
}
|
|
|
|
|
|
void MedLinacDetectorConstruction::UpdateGeometry()
|
|
{
|
|
G4cout <<"UpdateGeometry "<< G4endl;
|
|
|
|
G4RunManager::GetRunManager()->DefineWorldVolume(ConstructGeom());
|
|
}
|
|
|
|
void MedLinacDetectorConstruction::ConstructVolume()
|
|
{
|
|
pHead ->ConstructComponent(experimentalHall_phys,vacuumBlock_phys);
|
|
decorator ->ConstructComponent( experimentalHall_phys,vacuumBlock_phys);
|
|
decorator1 ->ConstructComponent( experimentalHall_phys,vacuumBlock_phys);
|
|
}
|
|
|
|
void MedLinacDetectorConstruction::ConstructSensitiveDetector()
|
|
// Sensitive Detector and ReadOut geometry definition
|
|
{
|
|
G4SDManager* pSDManager = G4SDManager::GetSDMpointer();
|
|
|
|
if(!phantomSD)
|
|
{
|
|
phantomSD = new MedLinacPhantomSD (sensitiveDetectorName);
|
|
|
|
pSDManager->AddNewDetector(phantomSD);
|
|
}
|
|
|
|
G4String ROGeometryName = "PhantomROGeometry";
|
|
phantomROGeometry = new MedLinacPhantomROGeometry (ROGeometryName, phantomDim_x,phantomDim_y,phantomDim_z,
|
|
numberOfVoxelsAlongX,numberOfVoxelsAlongY,numberOfVoxelsAlongZ);
|
|
|
|
phantomROGeometry->BuildROGeometry();
|
|
phantomSD->SetROgeometry(phantomROGeometry);
|
|
|
|
Phantom_log->SetSensitiveDetector(phantomSD);
|
|
}
|