Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LXeMainVolume.cc
Go to the documentation of this file.
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 //
28 //
29 //
30 #include "LXeMainVolume.hh"
31 #include "globals.hh"
32 #include "G4SDManager.hh"
33 #include "G4LogicalSkinSurface.hh"
35 #include "LXePMTSD.hh"
36 #include "LXeScintSD.hh"
37 #include "G4SystemOfUnits.hh"
38 
39 LXeScintSD* LXeMainVolume::fScint_SD=NULL;
40 LXePMTSD* LXeMainVolume::fPmt_SD=NULL;
41 
42 G4LogicalVolume* LXeMainVolume::fHousing_log=NULL;
43 
44 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
45 
47  const G4ThreeVector &tlate,
48  G4LogicalVolume *pMotherLogical,
49  G4bool pMany,
50  G4int pCopyNo,
52  //Pass info to the G4PVPlacement constructor
53  :G4PVPlacement(pRot,tlate,
54  //Temp logical volume must be created here
55  new G4LogicalVolume(new G4Box("temp",1,1,1),
56  G4Material::GetMaterial("Vacuum"),
57  "temp",0,0,0),
58  "housing",pMotherLogical,pMany,pCopyNo),fConstructor(c)
59 {
60  CopyValues();
61 
62  if(!fHousing_log || fUpdated){
63 
64  G4double housing_x=fScint_x+fD_mtl;
65  G4double housing_y=fScint_y+fD_mtl;
66  G4double housing_z=fScint_z+fD_mtl;
67 
68  //*************************** housing and scintillator
69  fScint_box = new G4Box("scint_box",fScint_x/2.,fScint_y/2.,fScint_z/2.);
70  fHousing_box = new G4Box("housing_box",housing_x/2.,housing_y/2.,
71  housing_z/2.);
72 
73  fScint_log = new G4LogicalVolume(fScint_box,G4Material::GetMaterial("LXe"),
74  "scint_log",0,0,0);
75  fHousing_log = new G4LogicalVolume(fHousing_box,
77  "housing_log",0,0,0);
78 
79  new G4PVPlacement(0,G4ThreeVector(),fScint_log,"scintillator",
80  fHousing_log,false,0);
81 
82  //*************** Miscellaneous sphere to demonstrate skin surfaces
83  fSphere = new G4Sphere("sphere",0.*mm,2.*cm,0.*deg,360.*deg,0.*deg,
84  360.*deg);
85  fSphere_log = new G4LogicalVolume(fSphere,G4Material::GetMaterial("Al"),
86  "sphere_log");
87  if(fSphereOn)
88  new G4PVPlacement(0,G4ThreeVector(5.*cm,5.*cm,5.*cm),
89  fSphere_log,"sphere",fScint_log,false,0);
90 
91  //****************** Build PMTs
92  G4double innerRadius_pmt = 0.*cm;
93  G4double height_pmt = fD_mtl/2.;
94  G4double startAngle_pmt = 0.*deg;
95  G4double spanningAngle_pmt = 360.*deg;
96 
97  fPmt = new G4Tubs("pmt_tube",innerRadius_pmt,fOuterRadius_pmt,
98  height_pmt,startAngle_pmt,spanningAngle_pmt);
99 
100  //the "photocathode" is a metal slab at the back of the glass that
101  //is only a very rough approximation of the real thing since it only
102  //absorbs or detects the photons based on the efficiency set below
103  fPhotocath = new G4Tubs("photocath_tube",innerRadius_pmt,fOuterRadius_pmt,
104  height_pmt/2,startAngle_pmt,spanningAngle_pmt);
105 
106  fPmt_log = new G4LogicalVolume(fPmt,G4Material::GetMaterial("Glass"),
107  "pmt_log");
108  fPhotocath_log = new G4LogicalVolume(fPhotocath,
110  "photocath_log");
111 
112  new G4PVPlacement(0,G4ThreeVector(0,0,-height_pmt/2),
113  fPhotocath_log,"photocath",
114  fPmt_log,false,0);
115 
116  //***********Arrange pmts around the outside of housing**********
117  //---pmt sensitive detector
119 
120  if(!fPmt_SD){
121  fPmt_SD = new LXePMTSD("/LXeDet/pmtSD");
122  SDman->AddNewDetector(fPmt_SD);
123  //Created here so it exists as pmts are being placed
124  }
125  fPmt_SD->InitPMTs((fNx*fNy+fNx*fNz+fNy*fNz)*2); //let pmtSD know # of pmts
126  //-------
127 
128  G4double dx = fScint_x/fNx;
129  G4double dy = fScint_y/fNy;
130  G4double dz = fScint_z/fNz;
131 
132  G4double x,y,z;
133  G4double xmin = -fScint_x/2. - dx/2.;
134  G4double ymin = -fScint_y/2. - dy/2.;
135  G4double zmin = -fScint_z/2. - dz/2.;
136  G4int k=0;
137 
138  z = -fScint_z/2. - height_pmt; //front
139  PlacePMTs(fPmt_log,0,x,y,dx,dy,xmin,ymin,fNx,fNy,x,y,z,k,fPmt_SD);
140  G4RotationMatrix* rm_z = new G4RotationMatrix();
141  rm_z->rotateY(180*deg);
142  z = fScint_z/2. + height_pmt; //back
143  PlacePMTs(fPmt_log,rm_z,x,y,dx,dy,xmin,ymin,fNx,fNy,x,y,z,k,fPmt_SD);
144 
145  G4RotationMatrix* rm_y1 = new G4RotationMatrix();
146  rm_y1->rotateY(-90*deg);
147  x = -fScint_x/2. - height_pmt; //left
148  PlacePMTs(fPmt_log,rm_y1,y,z,dy,dz,ymin,zmin,fNy,fNz,x,y,z,k,fPmt_SD);
149  G4RotationMatrix* rm_y2 = new G4RotationMatrix();
150  rm_y2->rotateY(90*deg);
151  x = fScint_x/2. + height_pmt; //right
152  PlacePMTs(fPmt_log,rm_y2,y,z,dy,dz,ymin,zmin,fNy,fNz,x,y,z,k,fPmt_SD);
153 
154  G4RotationMatrix* rm_x1 = new G4RotationMatrix();
155  rm_x1->rotateX(90*deg);
156  y = -fScint_y/2. - height_pmt; //bottom
157  PlacePMTs(fPmt_log,rm_x1,x,z,dx,dz,xmin,zmin,fNx,fNz,x,y,z,k,fPmt_SD);
158  G4RotationMatrix* rm_x2 = new G4RotationMatrix();
159  rm_x2->rotateX(-90*deg);
160  y = fScint_y/2. + height_pmt; //top
161  PlacePMTs(fPmt_log,rm_x2,x,z,dx,dz,xmin,zmin,fNx,fNz,x,y,z,k,fPmt_SD);
162 
163  //**********Setup Sensitive Detectors***************
164  if(!fScint_SD){//determine if it has already been created
165  fScint_SD = new LXeScintSD("/LXeDet/scintSD");
166  SDman->AddNewDetector(fScint_SD);
167  }
168  fScint_log->SetSensitiveDetector(fScint_SD);
169 
170  //sensitive detector is not actually on the photocathode.
171  //processHits gets done manually by the stepping action.
172  //It is used to detect when photons hit and get absorbed&detected at the
173  //boundary to the photocathode (which doesnt get done by attaching it to a
174  //logical volume.
175  //It does however need to be attached to something or else it doesnt get
176  //reset at the begining of events
177  fPhotocath_log->SetSensitiveDetector(fPmt_SD);
178 
179  VisAttributes();
180  SurfaceProperties();
181  }
182 
183  SetLogicalVolume(fHousing_log);
184 }
185 
186 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
187 
188 void LXeMainVolume::CopyValues(){
189  fUpdated=fConstructor->GetUpdated();
190 
191  fScint_x=fConstructor->GetScintX();
192  fScint_y=fConstructor->GetScintY();
193  fScint_z=fConstructor->GetScintZ();
194  fD_mtl=fConstructor->GetHousingThickness();
195  fNx=fConstructor->GetNX();
196  fNy=fConstructor->GetNY();
197  fNz=fConstructor->GetNZ();
198  fOuterRadius_pmt=fConstructor->GetPMTRadius();
199  fSphereOn=fConstructor->GetSphereOn();
200  fRefl=fConstructor->GetHousingReflectivity();
201 }
202 
203 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
204 
205 void LXeMainVolume::PlacePMTs(G4LogicalVolume* pmt_log,
206  G4RotationMatrix *rot,
207  G4double &a, G4double &b, G4double da,
208  G4double db, G4double amin,
209  G4double bmin, G4int na, G4int nb,
210  G4double &x, G4double &y, G4double &z,
211  G4int &k,LXePMTSD* sd){
212 /*PlacePMTs : a different way to parameterize placement that does not depend on
213  calculating the position from the copy number
214 
215  pmt_log = logical volume for pmts to be placed
216  rot = rotation matrix to apply
217  a,b = coordinates to vary(ie. if varying in the xy plane then pass x,y)
218  da,db = value to increment a,b by
219  amin,bmin = start values for a,b
220  na,nb = number of repitions in a and b
221  x,y,z = just pass x,y, and z by reference (the same ones passed for a,b)
222  k = copy number to start with
223  sd = sensitive detector for pmts
224 */
225  a=amin;
226  for(G4int j=1;j<=na;j++){
227  a+=da;
228  b=bmin;
229  for(G4int i=1;i<=nb;i++){
230  b+=db;
231  new G4PVPlacement(rot,G4ThreeVector(x,y,z),pmt_log,"pmt",
232  fHousing_log,false,k);
233  sd->SetPMTPos(k,x,y,z);
234  k++;
235  }
236  }
237 }
238 
239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
240 
241 void LXeMainVolume::VisAttributes(){
242  G4VisAttributes* housing_va = new G4VisAttributes(G4Colour(0.8,0.8,0.8));
243  fHousing_log->SetVisAttributes(housing_va);
244 
245  G4VisAttributes* sphere_va = new G4VisAttributes();
246  sphere_va->SetForceSolid(true);
247  fSphere_log->SetVisAttributes(sphere_va);
248 }
249 
250 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
251 
252 void LXeMainVolume::SurfaceProperties(){
253  const G4int num = 2;
254  G4double ephoton[num] = {7.0*eV, 7.14*eV};
255 
256  //**Scintillator housing properties
257  G4double reflectivity[num] = {fRefl, fRefl};
258  G4double efficiency[num] = {0.0, 0.0};
260  scintHsngPT->AddProperty("REFLECTIVITY", ephoton, reflectivity, num);
261  scintHsngPT->AddProperty("EFFICIENCY", ephoton, efficiency, num);
262  G4OpticalSurface* OpScintHousingSurface =
263  new G4OpticalSurface("HousingSurface",unified,polished,dielectric_metal);
264  OpScintHousingSurface->SetMaterialPropertiesTable(scintHsngPT);
265 
266  //**Sphere surface properties
267  G4double sphereReflectivity[num] = {1.0, 1.0};
268  G4double sphereEfficiency[num] = {0.0, 0.0};
270  spherePT->AddProperty("REFLECTIVITY", ephoton, sphereReflectivity, num);
271  spherePT->AddProperty("EFFICIENCY", ephoton, sphereEfficiency, num);
272  G4OpticalSurface* OpSphereSurface =
273  new G4OpticalSurface("SphereSurface",unified,polished,dielectric_metal);
274  OpSphereSurface->SetMaterialPropertiesTable(spherePT);
275 
276  //**Photocathode surface properties
277  G4double photocath_EFF[num]={1.,1.}; //Enables 'detection' of photons
278  G4double photocath_ReR[num]={1.92,1.92};
279  G4double photocath_ImR[num]={1.69,1.69};
281  photocath_mt->AddProperty("EFFICIENCY",ephoton,photocath_EFF,num);
282  photocath_mt->AddProperty("REALRINDEX",ephoton,photocath_ReR,num);
283  photocath_mt->AddProperty("IMAGINARYRINDEX",ephoton,photocath_ImR,num);
284  G4OpticalSurface* photocath_opsurf=
285  new G4OpticalSurface("photocath_opsurf",glisur,polished,
287  photocath_opsurf->SetMaterialPropertiesTable(photocath_mt);
288 
289  //**Create logical skin surfaces
290  new G4LogicalSkinSurface("photocath_surf",fHousing_log,
291  OpScintHousingSurface);
292  new G4LogicalSkinSurface("sphere_surface",fSphere_log,OpSphereSurface);
293  new G4LogicalSkinSurface("photocath_surf",fPhotocath_log,photocath_opsurf);
294 }