source: trunk/examples/extended/optical/LXe/src/LXeMainVolume.cc

Last change on this file was 1230, checked in by garnier, 15 years ago

update to geant4.9.3

File size: 11.1 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26#include "LXeMainVolume.hh"
27#include "globals.hh"
28#include "G4SDManager.hh"
29#include "G4LogicalSkinSurface.hh"
30#include "G4LogicalBorderSurface.hh"
31#include "LXePMTSD.hh"
32#include "LXeScintSD.hh"
33
34LXeScintSD* LXeMainVolume::scint_SD;
35LXePMTSD* LXeMainVolume::pmt_SD;
36
37G4LogicalVolume* LXeMainVolume::housing_log=NULL;
38
39LXeMainVolume::LXeMainVolume(G4RotationMatrix *pRot,
40                             const G4ThreeVector &tlate,
41                             G4LogicalVolume *pMotherLogical,
42                             G4bool pMany,
43                             G4int pCopyNo,
44                             LXeDetectorConstruction* c)
45  //Pass info to the G4PVPlacement constructor
46  :G4PVPlacement(pRot,tlate,
47                 //Temp logical volume must be created here
48                 new G4LogicalVolume(new G4Box("temp",1,1,1),
49                                     G4Material::GetMaterial("Vacuum"),
50                                     "temp",0,0,0),
51                 "housing",pMotherLogical,pMany,pCopyNo),constructor(c)
52{
53  CopyValues();
54
55  if(!housing_log || updated){
56   
57    G4double housing_x=scint_x+d_mtl;
58    G4double housing_y=scint_y+d_mtl;
59    G4double housing_z=scint_z+d_mtl;
60   
61    //*************************** housing and scintillator
62    scint_box = new G4Box("scint_box",scint_x/2.,scint_y/2.,scint_z/2.);
63    housing_box = new G4Box("housing_box",housing_x/2.,housing_y/2.,
64                            housing_z/2.);
65   
66    scint_log = new G4LogicalVolume(scint_box,G4Material::GetMaterial("LXe"),
67                                    "scint_log",0,0,0);
68    housing_log = new G4LogicalVolume(housing_box,
69                                      G4Material::GetMaterial("Al"),
70                                      "housing_log",0,0,0);
71   
72
73    scint_phys = new G4PVPlacement(0,G4ThreeVector(),scint_log,"scintillator",
74                                   housing_log,false,0); 
75   
76    //*************** Miscellaneous sphere to demonstrate skin surfaces
77    sphere = new G4Sphere("sphere",0.*mm,2.*cm,0.*deg,360.*deg,0.*deg,
78                          360.*deg);
79    sphere_log = new G4LogicalVolume(sphere,G4Material::GetMaterial("Al"),
80                                     "sphere_log");
81    if(sphereOn)
82      sphere_phys = new G4PVPlacement(0,G4ThreeVector(5.*cm,5.*cm,5.*cm),
83                                      sphere_log,"sphere",scint_log,false,0);
84   
85       
86    //****************** Build PMTs
87    G4double innerRadius_pmt = 0.*cm;
88    G4double height_pmt = d_mtl/2.;
89    G4double startAngle_pmt = 0.*deg;
90    G4double spanningAngle_pmt = 360.*deg;
91   
92    pmt = new G4Tubs("pmt_tube",innerRadius_pmt,outerRadius_pmt,
93                     height_pmt,startAngle_pmt,spanningAngle_pmt);
94   
95    //the "photocathode" is a metal slab at the back of the glass that
96    //is only a very rough approximation of the real thing since it only
97    //absorbs or detects the photons based on the efficiency set below
98    photocath = new G4Tubs("photocath_tube",innerRadius_pmt,outerRadius_pmt,
99                           height_pmt/2,startAngle_pmt,spanningAngle_pmt);
100   
101    pmt_log = new G4LogicalVolume(pmt,G4Material::GetMaterial("Glass"),
102                                  "pmt_log");
103    photocath_log = new G4LogicalVolume(photocath,
104                                        G4Material::GetMaterial("Al"),
105                                        "photocath_log");
106   
107    photocath_phys = new G4PVPlacement(0,G4ThreeVector(0,0,-height_pmt/2),
108                                       photocath_log,"photocath",
109                                       pmt_log,false,0);
110   
111   
112   
113    //***********Arrange pmts around the outside of housing**********
114    //---pmt sensitive detector
115    G4SDManager* SDman = G4SDManager::GetSDMpointer();
116   
117    if(!pmt_SD){
118      pmt_SD = new LXePMTSD("/LXeDet/pmtSD");
119      SDman->AddNewDetector(pmt_SD);
120      //Created here so it exists as pmts are being placed
121    }
122    pmt_SD->InitPMTs((nx*ny+nx*nz+ny*nz)*2); //let pmtSD know # of pmts
123    //-------
124   
125    G4double dx = scint_x/nx;
126    G4double dy = scint_y/ny;
127    G4double dz = scint_z/nz;
128   
129    G4double x,y,z;
130    G4double xmin = -scint_x/2. - dx/2.;
131    G4double ymin = -scint_y/2. - dy/2.;
132    G4double zmin = -scint_z/2. - dz/2.;
133    G4int k=0;
134   
135    z = -scint_z/2. - height_pmt;      //front
136    PlacePMTs(pmt_log,0,x,y,dx,dy,xmin,ymin,nx,ny,x,y,z,k,pmt_SD);
137    G4RotationMatrix* rm_z = new G4RotationMatrix();
138    rm_z->rotateY(180*deg);
139    z = scint_z/2. + height_pmt;       //back
140    PlacePMTs(pmt_log,rm_z,x,y,dx,dy,xmin,ymin,nx,ny,x,y,z,k,pmt_SD);
141   
142    G4RotationMatrix* rm_y1 = new G4RotationMatrix();
143    rm_y1->rotateY(-90*deg);
144    x = -scint_x/2. - height_pmt;      //left
145    PlacePMTs(pmt_log,rm_y1,y,z,dy,dz,ymin,zmin,ny,nz,x,y,z,k,pmt_SD);
146    G4RotationMatrix* rm_y2 = new G4RotationMatrix();
147    rm_y2->rotateY(90*deg);
148    x = scint_x/2. + height_pmt;      //right
149    PlacePMTs(pmt_log,rm_y2,y,z,dy,dz,ymin,zmin,ny,nz,x,y,z,k,pmt_SD);
150   
151    G4RotationMatrix* rm_x1 = new G4RotationMatrix();
152    rm_x1->rotateX(90*deg);
153    y = -scint_y/2. - height_pmt;     //bottom
154    PlacePMTs(pmt_log,rm_x1,x,z,dx,dz,xmin,zmin,nx,nz,x,y,z,k,pmt_SD);
155    G4RotationMatrix* rm_x2 = new G4RotationMatrix();
156    rm_x2->rotateX(-90*deg);
157    y = scint_y/2. + height_pmt;      //top
158    PlacePMTs(pmt_log,rm_x2,x,z,dx,dz,xmin,zmin,nx,nz,x,y,z,k,pmt_SD);
159   
160    //**********Setup Sensitive Detectors***************
161    if(!scint_SD){//determine if it has already been created
162      scint_SD = new LXeScintSD("/LXeDet/scintSD");
163      SDman->AddNewDetector(scint_SD);   
164    }
165    scint_log->SetSensitiveDetector(scint_SD);
166   
167    //sensitive detector is not actually on the photocathode.
168    //processHits gets done manually by the stepping action.
169    //It is used to detect when photons hit and get absorbed&detected at the
170    //boundary to the photocathode (which doesnt get done by attaching it to a
171    //logical volume.
172    //It does however need to be attached to something or else it doesnt get
173    //reset at the begining of events
174    photocath_log->SetSensitiveDetector(pmt_SD);
175
176    VisAttributes();
177    SurfaceProperties();
178  }
179
180  SetLogicalVolume(housing_log);
181}
182
183void LXeMainVolume::CopyValues(){
184  updated=constructor->GetUpdated();
185
186  scint_x=constructor->GetScintX();
187  scint_y=constructor->GetScintY();
188  scint_z=constructor->GetScintZ();
189  d_mtl=constructor->GetHousingThickness();
190  nx=constructor->GetNX();
191  ny=constructor->GetNY();
192  nz=constructor->GetNZ();
193  outerRadius_pmt=constructor->GetPMTRadius();
194  sphereOn=constructor->GetSphereOn();
195  refl=constructor->GetHousingReflectivity();
196}
197
198//_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
199void LXeMainVolume::PlacePMTs(G4LogicalVolume* pmt_log,
200                              G4RotationMatrix *rot,
201                              G4double &a, G4double &b, G4double da,
202                              G4double db, G4double amin,
203                              G4double bmin, G4int na, G4int nb,
204                              G4double &x, G4double &y, G4double &z,
205                              G4int &k,LXePMTSD* sd){
206/*PlacePMTs : a different way to parameterize placement that does not depend on
207  calculating the position from the copy number
208 
209  pmt_log = logical volume for pmts to be placed
210  rot = rotation matrix to apply
211  a,b = coordinates to vary(ie. if varying in the xy plane then pass x,y)
212  da,db = value to increment a,b by
213  amin,bmin = start values for a,b
214  na,nb = number of repitions in a and b
215  x,y,z = just pass x,y, and z by reference (the same ones passed for a,b)
216  k = copy number to start with
217  sd = sensitive detector for pmts
218*/
219  a=amin;
220  for(G4int j=1;j<=na;j++){
221    a+=da;
222    b=bmin;
223    for(G4int i=1;i<=nb;i++){
224      b+=db;
225      new G4PVPlacement(rot,G4ThreeVector(x,y,z),pmt_log,"pmt",
226                        housing_log,false,k);
227      sd->SetPMTPos(k,x,y,z);
228      k++;
229    }
230  }
231}
232
233void LXeMainVolume::VisAttributes(){
234  G4VisAttributes* housing_va = new G4VisAttributes(G4Colour(0.8,0.8,0.8));
235  housing_log->SetVisAttributes(housing_va);
236
237  G4VisAttributes* sphere_va = new G4VisAttributes();
238  sphere_va->SetForceSolid(true);
239  sphere_log->SetVisAttributes(sphere_va);
240}
241
242void LXeMainVolume::SurfaceProperties(){   
243  const G4int num = 2;
244  G4double Ephoton[num] = {7.0*eV, 7.14*eV}; 
245
246  //**Scintillator housing properties
247  G4double Reflectivity[num] = {refl, refl};
248  G4double Efficiency[num] = {0.0, 0.0}; 
249  G4MaterialPropertiesTable* scintHsngPT = new G4MaterialPropertiesTable(); 
250  scintHsngPT->AddProperty("REFLECTIVITY", Ephoton, Reflectivity, num);
251  scintHsngPT->AddProperty("EFFICIENCY", Ephoton, Efficiency, num);
252  G4OpticalSurface* OpScintHousingSurface =
253    new G4OpticalSurface("HousingSurface",unified,polished,dielectric_metal);
254  OpScintHousingSurface->SetMaterialPropertiesTable(scintHsngPT);
255 
256  //**Sphere surface properties
257  G4double SphereReflectivity[num] = {1.0, 1.0};
258  G4double SphereEfficiency[num] = {0.0, 0.0}; 
259  G4MaterialPropertiesTable* spherePT = new G4MaterialPropertiesTable();
260  spherePT->AddProperty("REFLECTIVITY", Ephoton, SphereReflectivity, num);
261  spherePT->AddProperty("EFFICIENCY", Ephoton, SphereEfficiency, num);
262  G4OpticalSurface* OpSphereSurface =
263    new G4OpticalSurface("SphereSurface",unified,polished,dielectric_metal);
264  OpSphereSurface->SetMaterialPropertiesTable(spherePT);
265 
266  //**Photocathode surface properties
267  G4double photocath_EFF[num]={1.,1.}; //Enables 'detection' of photons
268  G4double photocath_ReR[num]={1.92,1.92};
269  G4double photocath_ImR[num]={1.69,1.69};
270  G4MaterialPropertiesTable* photocath_mt = new G4MaterialPropertiesTable();
271  photocath_mt->AddProperty("EFFICIENCY",Ephoton,photocath_EFF,num);
272  photocath_mt->AddProperty("REALRINDEX",Ephoton,photocath_ReR,num);
273  photocath_mt->AddProperty("IMAGINARYRINDEX",Ephoton,photocath_ImR,num);
274  G4OpticalSurface* photocath_opsurf= 
275    new G4OpticalSurface("photocath_opsurf",glisur,polished,
276                         dielectric_metal);
277  photocath_opsurf->SetMaterialPropertiesTable(photocath_mt);
278
279
280  //**Create logical skin surfaces
281  new G4LogicalSkinSurface("photocath_surf",housing_log,
282                           OpScintHousingSurface);
283  new G4LogicalSkinSurface("sphere_surface",sphere_log,OpSphereSurface); 
284  new G4LogicalSkinSurface("photocath_surf",photocath_log,photocath_opsurf);
285}
286
287
288
Note: See TracBrowser for help on using the repository browser.