Import Geant4 6.2.0 source tree
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "LXeMainVolume.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4SDManager.hh"
|
||||
#include "G4LogicalSkinSurface.hh"
|
||||
#include "G4LogicalBorderSurface.hh"
|
||||
#include "LXePMTSD.hh"
|
||||
#include "LXeScintSD.hh"
|
||||
|
||||
LXeScintSD* LXeMainVolume::scint_SD;
|
||||
LXePMTSD* LXeMainVolume::pmt_SD;
|
||||
|
||||
G4LogicalVolume* LXeMainVolume::housing_log=NULL;
|
||||
|
||||
LXeMainVolume::LXeMainVolume(G4RotationMatrix *pRot,
|
||||
const G4ThreeVector &tlate,
|
||||
G4LogicalVolume *pMotherLogical,
|
||||
G4bool pMany,
|
||||
G4int pCopyNo,
|
||||
LXeDetectorConstruction* c)
|
||||
//Pass info to the G4PVPlacement constructor
|
||||
:G4PVPlacement(pRot,tlate,
|
||||
//Temp logical volume must be created here
|
||||
new G4LogicalVolume(new G4Box("temp",1,1,1),
|
||||
G4Material::GetMaterial("Vacuum"),
|
||||
"temp",0,0,0),
|
||||
"housing",pMotherLogical,pMany,pCopyNo),constructor(c)
|
||||
{
|
||||
CopyValues();
|
||||
|
||||
if(!housing_log || updated){
|
||||
|
||||
G4double housing_x=scint_x+d_mtl;
|
||||
G4double housing_y=scint_y+d_mtl;
|
||||
G4double housing_z=scint_z+d_mtl;
|
||||
|
||||
//*************************** housing and scintillator
|
||||
scint_box = new G4Box("scint_box",scint_x/2.,scint_y/2.,scint_z/2.);
|
||||
housing_box = new G4Box("housing_box",housing_x/2.,housing_y/2.,
|
||||
housing_z/2.);
|
||||
|
||||
scint_log = new G4LogicalVolume(scint_box,G4Material::GetMaterial("LXe"),
|
||||
"scint_log",0,0,0);
|
||||
housing_log = new G4LogicalVolume(housing_box,
|
||||
G4Material::GetMaterial("Al"),
|
||||
"housing_log",0,0,0);
|
||||
|
||||
|
||||
scint_phys = new G4PVPlacement(0,G4ThreeVector(),scint_log,"scintillator",
|
||||
housing_log,false,0);
|
||||
|
||||
//*************** Miscellaneous sphere to demonstrate skin surfaces
|
||||
sphere = new G4Sphere("sphere",0.*mm,2.*cm,0.*deg,360.*deg,0.*deg,
|
||||
360.*deg);
|
||||
sphere_log = new G4LogicalVolume(sphere,G4Material::GetMaterial("Al"),
|
||||
"sphere_log");
|
||||
if(sphereOn)
|
||||
sphere_phys = new G4PVPlacement(0,G4ThreeVector(5.*cm,5.*cm,5.*cm),
|
||||
sphere_log,"sphere",scint_log,false,0);
|
||||
|
||||
|
||||
//****************** Build PMTs
|
||||
G4double innerRadius_pmt = 0.*cm;
|
||||
G4double height_pmt = d_mtl/2.;
|
||||
G4double startAngle_pmt = 0.*deg;
|
||||
G4double spanningAngle_pmt = 360.*deg;
|
||||
|
||||
pmt = new G4Tubs("pmt_tube",innerRadius_pmt,outerRadius_pmt,
|
||||
height_pmt,startAngle_pmt,spanningAngle_pmt);
|
||||
|
||||
//the "photocathode" is a metal slab at the back of the glass that
|
||||
//is only a very rough approximation of the real thing since it only
|
||||
//absorbs or detects the photons based on the efficiency set below
|
||||
photocath = new G4Tubs("photocath_tube",innerRadius_pmt,outerRadius_pmt,
|
||||
height_pmt/2,startAngle_pmt,spanningAngle_pmt);
|
||||
|
||||
pmt_log = new G4LogicalVolume(pmt,G4Material::GetMaterial("Glass"),
|
||||
"pmt_log");
|
||||
photocath_log = new G4LogicalVolume(photocath,
|
||||
G4Material::GetMaterial("Al"),
|
||||
"photocath_log");
|
||||
|
||||
photocath_phys = new G4PVPlacement(0,G4ThreeVector(0,0,-height_pmt/2),
|
||||
photocath_log,"photocath",
|
||||
pmt_log,false,0);
|
||||
|
||||
|
||||
|
||||
//***********Arrange pmts around the outside of housing**********
|
||||
//---pmt sensitive detector
|
||||
G4SDManager* SDman = G4SDManager::GetSDMpointer();
|
||||
|
||||
if(!pmt_SD){
|
||||
pmt_SD = new LXePMTSD("/LXeDet/pmtSD");
|
||||
SDman->AddNewDetector(pmt_SD);
|
||||
//Created here so it exists as pmts are being placed
|
||||
}
|
||||
pmt_SD->InitPMTs((nx*ny+nx*nz+ny*nz)*2); //let pmtSD know # of pmts
|
||||
//-------
|
||||
|
||||
G4double dx = scint_x/nx;
|
||||
G4double dy = scint_y/ny;
|
||||
G4double dz = scint_z/nz;
|
||||
|
||||
G4double x,y,z;
|
||||
G4double xmin = -scint_x/2. - dx/2.;
|
||||
G4double ymin = -scint_y/2. - dy/2.;
|
||||
G4double zmin = -scint_z/2. - dz/2.;
|
||||
G4int k=0;
|
||||
|
||||
z = -scint_z/2. - height_pmt; //front
|
||||
PlacePMTs(pmt_log,0,x,y,dx,dy,xmin,ymin,nx,ny,x,y,z,k,pmt_SD);
|
||||
G4RotationMatrix* rm_z = new G4RotationMatrix();
|
||||
rm_z->rotateY(180*deg);
|
||||
z = scint_z/2. + height_pmt; //back
|
||||
PlacePMTs(pmt_log,rm_z,x,y,dx,dy,xmin,ymin,nx,ny,x,y,z,k,pmt_SD);
|
||||
|
||||
G4RotationMatrix* rm_y1 = new G4RotationMatrix();
|
||||
rm_y1->rotateY(-90*deg);
|
||||
x = -scint_x/2. - height_pmt; //left
|
||||
PlacePMTs(pmt_log,rm_y1,y,z,dy,dz,ymin,zmin,ny,nz,x,y,z,k,pmt_SD);
|
||||
G4RotationMatrix* rm_y2 = new G4RotationMatrix();
|
||||
rm_y2->rotateY(90*deg);
|
||||
x = scint_x/2. + height_pmt; //right
|
||||
PlacePMTs(pmt_log,rm_y2,y,z,dy,dz,ymin,zmin,ny,nz,x,y,z,k,pmt_SD);
|
||||
|
||||
G4RotationMatrix* rm_x1 = new G4RotationMatrix();
|
||||
rm_x1->rotateX(90*deg);
|
||||
y = -scint_y/2. - height_pmt; //bottom
|
||||
PlacePMTs(pmt_log,rm_x1,x,z,dx,dz,xmin,zmin,nx,nz,x,y,z,k,pmt_SD);
|
||||
G4RotationMatrix* rm_x2 = new G4RotationMatrix();
|
||||
rm_x2->rotateX(-90*deg);
|
||||
y = scint_y/2. + height_pmt; //top
|
||||
PlacePMTs(pmt_log,rm_x2,x,z,dx,dz,xmin,zmin,nx,nz,x,y,z,k,pmt_SD);
|
||||
|
||||
//**********Setup Sensitive Detectors***************
|
||||
if(!scint_SD){//determine if it has already been created
|
||||
scint_SD = new LXeScintSD("/LXeDet/scintSD");
|
||||
SDman->AddNewDetector(scint_SD);
|
||||
}
|
||||
scint_log->SetSensitiveDetector(scint_SD);
|
||||
|
||||
//sensitive detector is not actually on the photocathode.
|
||||
//processHits gets done manually by the stepping action.
|
||||
//It is used to detect when photons hit and get absorbed&detected at the
|
||||
//boundary to the photocathode (which doesnt get done by attaching it to a
|
||||
//logical volume.
|
||||
//It does however need to be attached to something or else it doesnt get
|
||||
//reset at the begining of events
|
||||
photocath_log->SetSensitiveDetector(pmt_SD);
|
||||
|
||||
VisAttributes();
|
||||
SurfaceProperties();
|
||||
}
|
||||
|
||||
SetLogicalVolume(housing_log);
|
||||
}
|
||||
|
||||
void LXeMainVolume::CopyValues(){
|
||||
updated=constructor->GetUpdated();
|
||||
|
||||
scint_x=constructor->GetScintX();
|
||||
scint_y=constructor->GetScintY();
|
||||
scint_z=constructor->GetScintZ();
|
||||
d_mtl=constructor->GetHousingThickness();
|
||||
nx=constructor->GetNX();
|
||||
ny=constructor->GetNY();
|
||||
nz=constructor->GetNZ();
|
||||
outerRadius_pmt=constructor->GetPMTRadius();
|
||||
sphereOn=constructor->GetSphereOn();
|
||||
refl=constructor->GetHousingReflectivity();
|
||||
}
|
||||
|
||||
//_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
|
||||
void LXeMainVolume::PlacePMTs(G4LogicalVolume* pmt_log,
|
||||
G4RotationMatrix *rot,
|
||||
G4double &a, G4double &b, G4double da,
|
||||
G4double db, G4double amin,
|
||||
G4double bmin, G4int na, G4int nb,
|
||||
G4double &x, G4double &y, G4double &z,
|
||||
G4int &k,LXePMTSD* sd){
|
||||
/*PlacePMTs : a different way to parameterize placement that does not depend on
|
||||
calculating the position from the copy number
|
||||
|
||||
pmt_log = logical volume for pmts to be placed
|
||||
rot = rotation matrix to apply
|
||||
a,b = coordinates to vary(ie. if varying in the xy plane then pass x,y)
|
||||
da,db = value to increment a,b by
|
||||
amin,bmin = start values for a,b
|
||||
na,nb = number of repitions in a and b
|
||||
x,y,z = just pass x,y, and z by reference (the same ones passed for a,b)
|
||||
k = copy number to start with
|
||||
sd = sensitive detector for pmts
|
||||
*/
|
||||
a=amin;
|
||||
for(G4int j=1;j<=na;j++){
|
||||
a+=da;
|
||||
b=bmin;
|
||||
for(G4int i=1;i<=nb;i++){
|
||||
b+=db;
|
||||
new G4PVPlacement(rot,G4ThreeVector(x,y,z),pmt_log,"pmt",
|
||||
housing_log,false,k);
|
||||
sd->SetPMTPos(k,x,y,z);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LXeMainVolume::VisAttributes(){
|
||||
G4VisAttributes* housing_va = new G4VisAttributes(G4Colour(0.8,0.8,0.8));
|
||||
housing_log->SetVisAttributes(housing_va);
|
||||
|
||||
G4VisAttributes* sphere_va = new G4VisAttributes();
|
||||
sphere_va->SetForceSolid(true);
|
||||
sphere_log->SetVisAttributes(sphere_va);
|
||||
}
|
||||
|
||||
void LXeMainVolume::SurfaceProperties(){
|
||||
const G4int num = 2;
|
||||
G4double Ephoton[num] = {7.0*eV, 7.14*eV};
|
||||
|
||||
//**Scintillator housing properties
|
||||
G4double Reflectivity[num] = {refl, refl};
|
||||
G4double Efficiency[num] = {0.0, 0.0};
|
||||
G4MaterialPropertiesTable* scintHsngPT = new G4MaterialPropertiesTable();
|
||||
scintHsngPT->AddProperty("REFLECTIVITY", Ephoton, Reflectivity, num);
|
||||
scintHsngPT->AddProperty("EFFICIENCY", Ephoton, Efficiency, num);
|
||||
G4OpticalSurface* OpScintHousingSurface =
|
||||
new G4OpticalSurface("HousingSurface",unified,polished,dielectric_metal);
|
||||
OpScintHousingSurface->SetMaterialPropertiesTable(scintHsngPT);
|
||||
|
||||
//**Sphere surface properties
|
||||
G4double SphereReflectivity[num] = {1.0, 1.0};
|
||||
G4double SphereEfficiency[num] = {0.0, 0.0};
|
||||
G4MaterialPropertiesTable* spherePT = new G4MaterialPropertiesTable();
|
||||
spherePT->AddProperty("REFLECTIVITY", Ephoton, SphereReflectivity, num);
|
||||
spherePT->AddProperty("EFFICIENCY", Ephoton, SphereEfficiency, num);
|
||||
G4OpticalSurface* OpSphereSurface =
|
||||
new G4OpticalSurface("SphereSurface",unified,polished,dielectric_metal);
|
||||
OpSphereSurface->SetMaterialPropertiesTable(spherePT);
|
||||
|
||||
//**Photocathode surface properties
|
||||
G4double photocath_EFF[num]={1.,1.}; //Enables 'detection' of photons
|
||||
G4double photocath_REFL[num]={0.,0.};
|
||||
G4MaterialPropertiesTable* photocath_mt = new G4MaterialPropertiesTable();
|
||||
photocath_mt->AddProperty("EFFICIENCY",Ephoton,photocath_EFF,num);
|
||||
photocath_mt->AddProperty("REFLECTIVITY",Ephoton,photocath_REFL,num);
|
||||
G4OpticalSurface* photocath_opsurf=
|
||||
new G4OpticalSurface("photocath_opsurf",glisur,polished,
|
||||
dielectric_metal);
|
||||
photocath_opsurf->SetMaterialPropertiesTable(photocath_mt);
|
||||
|
||||
|
||||
//**Create logical skin surfaces
|
||||
new G4LogicalSkinSurface("photocath_surf",housing_log,
|
||||
OpScintHousingSurface);
|
||||
new G4LogicalSkinSurface("sphere_surface",sphere_log,OpSphereSurface);
|
||||
new G4LogicalSkinSurface("photocath_surf",photocath_log,photocath_opsurf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user