Geant4 Cross Reference |
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 // 27 /// \file optical/LXe/src/LXeMainVolume.cc 28 /// \brief Implementation of the LXeMainVolume class 29 // 30 // 31 #include "LXeMainVolume.hh" 32 33 #include "G4Box.hh" 34 #include "G4Colour.hh" 35 #include "G4LogicalBorderSurface.hh" 36 #include "G4LogicalSkinSurface.hh" 37 #include "G4LogicalVolume.hh" 38 #include "G4Material.hh" 39 #include "G4MaterialPropertiesTable.hh" 40 #include "G4OpticalSurface.hh" 41 #include "G4Sphere.hh" 42 #include "G4SystemOfUnits.hh" 43 #include "G4Tubs.hh" 44 #include "G4VisAttributes.hh" 45 #include "globals.hh" 46 47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 48 49 LXeMainVolume::LXeMainVolume(G4RotationMatrix* pRot, const G4ThreeVector& tlate, 50 G4LogicalVolume* pMotherLogical, G4bool pMany, G4int pCopyNo, 51 LXeDetectorConstruction* c) 52 // Pass info to the G4PVPlacement constructor 53 : G4PVPlacement( 54 pRot, tlate, 55 // Temp logical volume must be created here 56 new G4LogicalVolume(new G4Box("temp", 1, 1, 1), G4Material::GetMaterial("Vacuum"), "temp"), 57 "housing", pMotherLogical, pMany, pCopyNo), 58 fConstructor(c) 59 { 60 CopyValues(); 61 62 G4double housing_x = fScint_x + 2. * fD_mtl; 63 G4double housing_y = fScint_y + 2. * fD_mtl; 64 G4double housing_z = fScint_z + 2. * fD_mtl; 65 66 //*************************** housing and scintillator 67 fScint_box = new G4Box("scint_box", fScint_x / 2., fScint_y / 2., fScint_z / 2.); 68 fHousing_box = new G4Box("housing_box", housing_x / 2., housing_y / 2., housing_z / 2.); 69 70 fScint_log = new G4LogicalVolume(fScint_box, G4Material::GetMaterial("LXe"), "scint_log"); 71 fHousing_log = new G4LogicalVolume(fHousing_box, G4Material::GetMaterial("Al"), "housing_log"); 72 73 new G4PVPlacement(nullptr, G4ThreeVector(), fScint_log, "scintillator", fHousing_log, false, 0); 74 75 //*************** Miscellaneous sphere to demonstrate skin surfaces 76 fSphere = new G4Sphere("sphere", 0., 2. * cm, 0. * deg, 360. * deg, 0. * deg, 360. * deg); 77 fSphere_log = new G4LogicalVolume(fSphere, G4Material::GetMaterial("Al"), "sphere_log"); 78 if (fSphereOn) 79 new G4PVPlacement(nullptr, G4ThreeVector(5. * cm, 5. * cm, 5. * cm), fSphere_log, "sphere", 80 fScint_log, false, 0); 81 82 //****************** Build PMTs 83 G4double innerRadius_pmt = 0.; 84 G4double height_pmt = fD_mtl / 2.; 85 G4double startAngle_pmt = 0.; 86 G4double spanningAngle_pmt = 360. * deg; 87 88 fPmt = new G4Tubs("pmt_tube", innerRadius_pmt, fOuterRadius_pmt, height_pmt, startAngle_pmt, 89 spanningAngle_pmt); 90 91 // the "photocathode" is a metal slab at the back of the glass that 92 // is only a very rough approximation of the real thing since it only 93 // absorbs or detects the photons based on the efficiency set below 94 fPhotocath = new G4Tubs("photocath_tube", innerRadius_pmt, fOuterRadius_pmt, height_pmt / 2., 95 startAngle_pmt, spanningAngle_pmt); 96 97 fPmt_log = new G4LogicalVolume(fPmt, G4Material::GetMaterial("Glass"), "pmt_log"); 98 fPhotocath_log = new G4LogicalVolume(fPhotocath, G4Material::GetMaterial("Al"), "photocath_log"); 99 100 new G4PVPlacement(nullptr, G4ThreeVector(0., 0., -height_pmt / 2.), fPhotocath_log, "photocath", 101 fPmt_log, false, 0); 102 103 //***********Arrange pmts around the outside of housing********** 104 105 G4double dx = fScint_x / fNx; 106 G4double dy = fScint_y / fNy; 107 G4double dz = fScint_z / fNz; 108 109 G4double x, y, z; 110 G4double xmin = -fScint_x / 2. - dx / 2.; 111 G4double ymin = -fScint_y / 2. - dy / 2.; 112 G4double zmin = -fScint_z / 2. - dz / 2.; 113 G4int k = 0; 114 115 z = -fScint_z / 2. - height_pmt; // front 116 PlacePMTs(fPmt_log, nullptr, x, y, dx, dy, xmin, ymin, fNx, fNy, x, y, z, k); 117 118 auto rm_z = new G4RotationMatrix(); 119 rm_z->rotateY(180. * deg); 120 z = fScint_z / 2. + height_pmt; // back 121 PlacePMTs(fPmt_log, rm_z, x, y, dx, dy, xmin, ymin, fNx, fNy, x, y, z, k); 122 123 auto rm_y1 = new G4RotationMatrix(); 124 rm_y1->rotateY(-90. * deg); 125 x = -fScint_x / 2. - height_pmt; // left 126 PlacePMTs(fPmt_log, rm_y1, y, z, dy, dz, ymin, zmin, fNy, fNz, x, y, z, k); 127 128 auto rm_y2 = new G4RotationMatrix(); 129 rm_y2->rotateY(90. * deg); 130 x = fScint_x / 2. + height_pmt; // right 131 PlacePMTs(fPmt_log, rm_y2, y, z, dy, dz, ymin, zmin, fNy, fNz, x, y, z, k); 132 133 auto rm_x1 = new G4RotationMatrix(); 134 rm_x1->rotateX(90. * deg); 135 y = -fScint_y / 2. - height_pmt; // bottom 136 PlacePMTs(fPmt_log, rm_x1, x, z, dx, dz, xmin, zmin, fNx, fNz, x, y, z, k); 137 138 auto rm_x2 = new G4RotationMatrix(); 139 rm_x2->rotateX(-90. * deg); 140 y = fScint_y / 2. + height_pmt; // top 141 PlacePMTs(fPmt_log, rm_x2, x, z, dx, dz, xmin, zmin, fNx, fNz, x, y, z, k); 142 143 VisAttributes(); 144 SurfaceProperties(); 145 146 SetLogicalVolume(fHousing_log); 147 } 148 149 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 150 151 void LXeMainVolume::CopyValues() 152 { 153 fScint_x = fConstructor->GetScintX(); 154 fScint_y = fConstructor->GetScintY(); 155 fScint_z = fConstructor->GetScintZ(); 156 fD_mtl = fConstructor->GetHousingThickness(); 157 fNx = fConstructor->GetNX(); 158 fNy = fConstructor->GetNY(); 159 fNz = fConstructor->GetNZ(); 160 fOuterRadius_pmt = fConstructor->GetPMTRadius(); 161 fSphereOn = fConstructor->GetSphereOn(); 162 fRefl = fConstructor->GetHousingReflectivity(); 163 } 164 165 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 166 167 void LXeMainVolume::PlacePMTs(G4LogicalVolume* pmt_log, G4RotationMatrix* rot, G4double& a, 168 G4double& b, G4double da, G4double db, G4double amin, G4double bmin, 169 G4int na, G4int nb, G4double& x, G4double& y, G4double& z, G4int& k) 170 { 171 /* PlacePMTs : a different way to parameterize placement that does not depend 172 * on calculating the position from the copy number 173 * 174 * pmt_log = logical volume for pmts to be placed 175 * rot = rotation matrix to apply 176 * a,b = coordinates to vary(ie. if varying in the xy plane then pass x,y) 177 * da,db = value to increment a,b by 178 * amin,bmin = start values for a,b 179 * na,nb = number of repitions in a and b 180 * x,y,z = just pass x,y, and z by reference (the same ones passed for a,b) 181 * k = copy number to start with 182 * sd = sensitive detector for pmts 183 */ 184 a = amin; 185 for (G4int j = 1; j <= na; ++j) { 186 a += da; 187 b = bmin; 188 for (G4int i = 1; i <= nb; ++i) { 189 b += db; 190 new G4PVPlacement(rot, G4ThreeVector(x, y, z), pmt_log, "pmt", fHousing_log, false, k); 191 fPmtPositions.push_back(G4ThreeVector(x, y, z)); 192 ++k; 193 } 194 } 195 } 196 197 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 198 199 void LXeMainVolume::VisAttributes() 200 { 201 auto housing_va = new G4VisAttributes(G4Colour(0.8, 0.8, 0.8)); 202 fHousing_log->SetVisAttributes(housing_va); 203 204 auto sphere_va = new G4VisAttributes(); 205 sphere_va->SetForceSolid(true); 206 fSphere_log->SetVisAttributes(sphere_va); 207 } 208 209 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 210 211 void LXeMainVolume::SurfaceProperties() 212 { 213 std::vector<G4double> ephoton = {7.0 * eV, 7.14 * eV}; 214 215 //**Scintillator housing properties 216 std::vector<G4double> reflectivity = {fRefl, fRefl}; 217 std::vector<G4double> efficiency = {0.0, 0.0}; 218 auto scintHsngPT = new G4MaterialPropertiesTable(); 219 scintHsngPT->AddProperty("REFLECTIVITY", ephoton, reflectivity); 220 scintHsngPT->AddProperty("EFFICIENCY", ephoton, efficiency); 221 auto OpScintHousingSurface = 222 new G4OpticalSurface("HousingSurface", unified, polished, dielectric_metal); 223 OpScintHousingSurface->SetMaterialPropertiesTable(scintHsngPT); 224 225 //**Sphere surface properties 226 std::vector<G4double> sphereReflectivity = {1.0, 1.0}; 227 std::vector<G4double> sphereEfficiency = {0.0, 0.0}; 228 auto spherePT = new G4MaterialPropertiesTable(); 229 spherePT->AddProperty("REFLECTIVITY", ephoton, sphereReflectivity); 230 spherePT->AddProperty("EFFICIENCY", ephoton, sphereEfficiency); 231 auto OpSphereSurface = new G4OpticalSurface("SphereSurface", unified, polished, dielectric_metal); 232 OpSphereSurface->SetMaterialPropertiesTable(spherePT); 233 234 //**Photocathode surface properties 235 std::vector<G4double> photocath_EFF = {1., 1.}; 236 std::vector<G4double> photocath_ReR = {1.92, 1.92}; 237 std::vector<G4double> photocath_ImR = {1.69, 1.69}; 238 auto photocath_mt = new G4MaterialPropertiesTable(); 239 photocath_mt->AddProperty("EFFICIENCY", ephoton, photocath_EFF); 240 photocath_mt->AddProperty("REALRINDEX", ephoton, photocath_ReR); 241 photocath_mt->AddProperty("IMAGINARYRINDEX", ephoton, photocath_ImR); 242 auto photocath_opsurf = 243 new G4OpticalSurface("photocath_opsurf", glisur, polished, dielectric_metal); 244 photocath_opsurf->SetMaterialPropertiesTable(photocath_mt); 245 246 //**Create logical skin surfaces 247 new G4LogicalSkinSurface("photocath_surf", fHousing_log, OpScintHousingSurface); 248 new G4LogicalSkinSurface("sphere_surface", fSphere_log, OpSphereSurface); 249 new G4LogicalSkinSurface("photocath_surf", fPhotocath_log, photocath_opsurf); 250 } 251