Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // 26 // 27 /// \file optical/LXe/src/LXeMainVolume.cc 27 /// \file optical/LXe/src/LXeMainVolume.cc 28 /// \brief Implementation of the LXeMainVolume 28 /// \brief Implementation of the LXeMainVolume class 29 // 29 // 30 // 30 // >> 31 #include "globals.hh" >> 32 31 #include "LXeMainVolume.hh" 33 #include "LXeMainVolume.hh" 32 34 33 #include "G4Box.hh" << 34 #include "G4Colour.hh" << 35 #include "G4LogicalBorderSurface.hh" << 36 #include "G4LogicalSkinSurface.hh" 35 #include "G4LogicalSkinSurface.hh" 37 #include "G4LogicalVolume.hh" << 36 #include "G4LogicalBorderSurface.hh" 38 #include "G4Material.hh" << 37 39 #include "G4MaterialPropertiesTable.hh" << 40 #include "G4OpticalSurface.hh" << 41 #include "G4Sphere.hh" << 42 #include "G4SystemOfUnits.hh" 38 #include "G4SystemOfUnits.hh" 43 #include "G4Tubs.hh" << 44 #include "G4VisAttributes.hh" << 45 #include "globals.hh" << 46 39 47 //....oooOO0OOooo........oooOO0OOooo........oo 40 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 48 41 49 LXeMainVolume::LXeMainVolume(G4RotationMatrix* << 42 LXeMainVolume::LXeMainVolume(G4RotationMatrix *pRot, 50 G4LogicalVolume* << 43 const G4ThreeVector &tlate, >> 44 G4LogicalVolume *pMotherLogical, >> 45 G4bool pMany, >> 46 G4int pCopyNo, 51 LXeDetectorConstr 47 LXeDetectorConstruction* c) 52 // Pass info to the G4PVPlacement constructo << 48 //Pass info to the G4PVPlacement constructor 53 : G4PVPlacement( << 49 :G4PVPlacement(pRot,tlate, 54 pRot, tlate, << 50 //Temp logical volume must be created here 55 // Temp logical volume must be created h << 51 new G4LogicalVolume(new G4Box("temp",1,1,1), 56 new G4LogicalVolume(new G4Box("temp", 1, << 52 G4Material::GetMaterial("Vacuum"), 57 "housing", pMotherLogical, pMany, pCopyN << 53 "temp",0,0,0), 58 fConstructor(c) << 54 "housing",pMotherLogical,pMany,pCopyNo),fConstructor(c) 59 { 55 { 60 CopyValues(); 56 CopyValues(); 61 57 62 G4double housing_x = fScint_x + 2. * fD_mtl; << 58 G4double housing_x=fScint_x+2.*fD_mtl; 63 G4double housing_y = fScint_y + 2. * fD_mtl; << 59 G4double housing_y=fScint_y+2.*fD_mtl; 64 G4double housing_z = fScint_z + 2. * fD_mtl; << 60 G4double housing_z=fScint_z+2.*fD_mtl; 65 << 61 66 //*************************** housing and sc 62 //*************************** housing and scintillator 67 fScint_box = new G4Box("scint_box", fScint_x << 63 fScint_box = new G4Box("scint_box",fScint_x/2.,fScint_y/2.,fScint_z/2.); 68 fHousing_box = new G4Box("housing_box", hous << 64 fHousing_box = new G4Box("housing_box",housing_x/2.,housing_y/2., 69 << 65 housing_z/2.); 70 fScint_log = new G4LogicalVolume(fScint_box, << 66 71 fHousing_log = new G4LogicalVolume(fHousing_ << 67 fScint_log = new G4LogicalVolume(fScint_box,G4Material::GetMaterial("LXe"), 72 << 68 "scint_log",0,0,0); 73 new G4PVPlacement(nullptr, G4ThreeVector(), << 69 fHousing_log = new G4LogicalVolume(fHousing_box, 74 << 70 G4Material::GetMaterial("Al"), >> 71 "housing_log",0,0,0); >> 72 >> 73 new G4PVPlacement(0,G4ThreeVector(),fScint_log,"scintillator", >> 74 fHousing_log,false,0); >> 75 75 //*************** Miscellaneous sphere to de 76 //*************** Miscellaneous sphere to demonstrate skin surfaces 76 fSphere = new G4Sphere("sphere", 0., 2. * cm << 77 fSphere = new G4Sphere("sphere",0.*mm,2.*cm,0.*deg,360.*deg,0.*deg,360.*deg); 77 fSphere_log = new G4LogicalVolume(fSphere, G << 78 fSphere_log = new G4LogicalVolume(fSphere,G4Material::GetMaterial("Al"), 78 if (fSphereOn) << 79 "sphere_log"); 79 new G4PVPlacement(nullptr, G4ThreeVector(5 << 80 if(fSphereOn) 80 fScint_log, false, 0); << 81 new G4PVPlacement(0,G4ThreeVector(5.*cm,5.*cm,5.*cm), 81 << 82 fSphere_log,"sphere",fScint_log,false,0); >> 83 82 //****************** Build PMTs 84 //****************** Build PMTs 83 G4double innerRadius_pmt = 0.; << 85 G4double innerRadius_pmt = 0.*cm; 84 G4double height_pmt = fD_mtl / 2.; << 86 G4double height_pmt = fD_mtl/2.; 85 G4double startAngle_pmt = 0.; << 87 G4double startAngle_pmt = 0.*deg; 86 G4double spanningAngle_pmt = 360. * deg; << 88 G4double spanningAngle_pmt = 360.*deg; 87 << 89 88 fPmt = new G4Tubs("pmt_tube", innerRadius_pm << 90 fPmt = new G4Tubs("pmt_tube",innerRadius_pmt,fOuterRadius_pmt, 89 spanningAngle_pmt); << 91 height_pmt,startAngle_pmt,spanningAngle_pmt); 90 << 92 91 // the "photocathode" is a metal slab at the << 93 //the "photocathode" is a metal slab at the back of the glass that 92 // is only a very rough approximation of the << 94 //is only a very rough approximation of the real thing since it only 93 // absorbs or detects the photons based on t << 95 //absorbs or detects the photons based on the efficiency set below 94 fPhotocath = new G4Tubs("photocath_tube", in << 96 fPhotocath = new G4Tubs("photocath_tube",innerRadius_pmt,fOuterRadius_pmt, 95 startAngle_pmt, span << 97 height_pmt/2,startAngle_pmt,spanningAngle_pmt); 96 << 98 97 fPmt_log = new G4LogicalVolume(fPmt, G4Mater << 99 fPmt_log = new G4LogicalVolume(fPmt,G4Material::GetMaterial("Glass"), 98 fPhotocath_log = new G4LogicalVolume(fPhotoc << 100 "pmt_log"); 99 << 101 fPhotocath_log = new G4LogicalVolume(fPhotocath, 100 new G4PVPlacement(nullptr, G4ThreeVector(0., << 102 G4Material::GetMaterial("Al"), 101 fPmt_log, false, 0); << 103 "photocath_log"); 102 << 104 >> 105 new G4PVPlacement(0,G4ThreeVector(0,0,-height_pmt/2), >> 106 fPhotocath_log,"photocath", >> 107 fPmt_log,false,0); >> 108 103 //***********Arrange pmts around the outside 109 //***********Arrange pmts around the outside of housing********** 104 110 105 G4double dx = fScint_x / fNx; << 111 G4double dx = fScint_x/fNx; 106 G4double dy = fScint_y / fNy; << 112 G4double dy = fScint_y/fNy; 107 G4double dz = fScint_z / fNz; << 113 G4double dz = fScint_z/fNz; 108 << 114 109 G4double x, y, z; << 115 G4double x,y,z; 110 G4double xmin = -fScint_x / 2. - dx / 2.; << 116 G4double xmin = -fScint_x/2. - dx/2.; 111 G4double ymin = -fScint_y / 2. - dy / 2.; << 117 G4double ymin = -fScint_y/2. - dy/2.; 112 G4double zmin = -fScint_z / 2. - dz / 2.; << 118 G4double zmin = -fScint_z/2. - dz/2.; 113 G4int k = 0; << 119 G4int k=0; 114 << 120 115 z = -fScint_z / 2. - height_pmt; // front << 121 z = -fScint_z/2. - height_pmt; //front 116 PlacePMTs(fPmt_log, nullptr, x, y, dx, dy, x << 122 PlacePMTs(fPmt_log,0,x,y,dx,dy,xmin,ymin,fNx,fNy,x,y,z,k); 117 << 123 118 auto rm_z = new G4RotationMatrix(); << 124 G4RotationMatrix* rm_z = new G4RotationMatrix(); 119 rm_z->rotateY(180. * deg); << 125 rm_z->rotateY(180*deg); 120 z = fScint_z / 2. + height_pmt; // back << 126 z = fScint_z/2. + height_pmt; //back 121 PlacePMTs(fPmt_log, rm_z, x, y, dx, dy, xmin << 127 PlacePMTs(fPmt_log,rm_z,x,y,dx,dy,xmin,ymin,fNx,fNy,x,y,z,k); 122 << 128 123 auto rm_y1 = new G4RotationMatrix(); << 129 G4RotationMatrix* rm_y1 = new G4RotationMatrix(); 124 rm_y1->rotateY(-90. * deg); << 130 rm_y1->rotateY(-90*deg); 125 x = -fScint_x / 2. - height_pmt; // left << 131 x = -fScint_x/2. - height_pmt; //left 126 PlacePMTs(fPmt_log, rm_y1, y, z, dy, dz, ymi << 132 PlacePMTs(fPmt_log,rm_y1,y,z,dy,dz,ymin,zmin,fNy,fNz,x,y,z,k); 127 << 133 128 auto rm_y2 = new G4RotationMatrix(); << 134 G4RotationMatrix* rm_y2 = new G4RotationMatrix(); 129 rm_y2->rotateY(90. * deg); << 135 rm_y2->rotateY(90*deg); 130 x = fScint_x / 2. + height_pmt; // right << 136 x = fScint_x/2. + height_pmt; //right 131 PlacePMTs(fPmt_log, rm_y2, y, z, dy, dz, ymi << 137 PlacePMTs(fPmt_log,rm_y2,y,z,dy,dz,ymin,zmin,fNy,fNz,x,y,z,k); 132 << 138 133 auto rm_x1 = new G4RotationMatrix(); << 139 G4RotationMatrix* rm_x1 = new G4RotationMatrix(); 134 rm_x1->rotateX(90. * deg); << 140 rm_x1->rotateX(90*deg); 135 y = -fScint_y / 2. - height_pmt; // bottom << 141 y = -fScint_y/2. - height_pmt; //bottom 136 PlacePMTs(fPmt_log, rm_x1, x, z, dx, dz, xmi << 142 PlacePMTs(fPmt_log,rm_x1,x,z,dx,dz,xmin,zmin,fNx,fNz,x,y,z,k); 137 << 143 138 auto rm_x2 = new G4RotationMatrix(); << 144 G4RotationMatrix* rm_x2 = new G4RotationMatrix(); 139 rm_x2->rotateX(-90. * deg); << 145 rm_x2->rotateX(-90*deg); 140 y = fScint_y / 2. + height_pmt; // top << 146 y = fScint_y/2. + height_pmt; //top 141 PlacePMTs(fPmt_log, rm_x2, x, z, dx, dz, xmi << 147 PlacePMTs(fPmt_log,rm_x2,x,z,dx,dz,xmin,zmin,fNx,fNz,x,y,z,k); 142 << 148 143 VisAttributes(); 149 VisAttributes(); 144 SurfaceProperties(); 150 SurfaceProperties(); 145 151 146 SetLogicalVolume(fHousing_log); 152 SetLogicalVolume(fHousing_log); 147 } 153 } 148 154 149 //....oooOO0OOooo........oooOO0OOooo........oo 155 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 150 156 151 void LXeMainVolume::CopyValues() << 157 void LXeMainVolume::CopyValues(){ 152 { << 158 fScint_x=fConstructor->GetScintX(); 153 fScint_x = fConstructor->GetScintX(); << 159 fScint_y=fConstructor->GetScintY(); 154 fScint_y = fConstructor->GetScintY(); << 160 fScint_z=fConstructor->GetScintZ(); 155 fScint_z = fConstructor->GetScintZ(); << 161 fD_mtl=fConstructor->GetHousingThickness(); 156 fD_mtl = fConstructor->GetHousingThickness() << 162 fNx=fConstructor->GetNX(); 157 fNx = fConstructor->GetNX(); << 163 fNy=fConstructor->GetNY(); 158 fNy = fConstructor->GetNY(); << 164 fNz=fConstructor->GetNZ(); 159 fNz = fConstructor->GetNZ(); << 165 fOuterRadius_pmt=fConstructor->GetPMTRadius(); 160 fOuterRadius_pmt = fConstructor->GetPMTRadiu << 166 fSphereOn=fConstructor->GetSphereOn(); 161 fSphereOn = fConstructor->GetSphereOn(); << 167 fRefl=fConstructor->GetHousingReflectivity(); 162 fRefl = fConstructor->GetHousingReflectivity << 163 } 168 } 164 169 165 //....oooOO0OOooo........oooOO0OOooo........oo 170 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 166 171 167 void LXeMainVolume::PlacePMTs(G4LogicalVolume* << 172 void LXeMainVolume::PlacePMTs(G4LogicalVolume* pmt_log, 168 G4double& b, G4d << 173 G4RotationMatrix *rot, 169 G4int na, G4int << 174 G4double &a, G4double &b, G4double da, 170 { << 175 G4double db, G4double amin, 171 /* PlacePMTs : a different way to parameter << 176 G4double bmin, G4int na, G4int nb, 172 * on calculating the position from the copy << 177 G4double &x, G4double &y, G4double &z, 173 * << 178 G4int &k){ 174 * pmt_log = logical volume for pmts to be << 179 /*PlacePMTs : a different way to parameterize placement that does not depend on 175 * rot = rotation matrix to apply << 180 calculating the position from the copy number 176 * a,b = coordinates to vary(ie. if varying << 181 177 * da,db = value to increment a,b by << 182 pmt_log = logical volume for pmts to be placed 178 * amin,bmin = start values for a,b << 183 rot = rotation matrix to apply 179 * na,nb = number of repitions in a and b << 184 a,b = coordinates to vary(ie. if varying in the xy plane then pass x,y) 180 * x,y,z = just pass x,y, and z by referenc << 185 da,db = value to increment a,b by 181 * k = copy number to start with << 186 amin,bmin = start values for a,b 182 * sd = sensitive detector for pmts << 187 na,nb = number of repitions in a and b 183 */ << 188 x,y,z = just pass x,y, and z by reference (the same ones passed for a,b) 184 a = amin; << 189 k = copy number to start with 185 for (G4int j = 1; j <= na; ++j) { << 190 sd = sensitive detector for pmts 186 a += da; << 191 */ 187 b = bmin; << 192 a=amin; 188 for (G4int i = 1; i <= nb; ++i) { << 193 for(G4int j=1;j<=na;j++){ 189 b += db; << 194 a+=da; 190 new G4PVPlacement(rot, G4ThreeVector(x, << 195 b=bmin; 191 fPmtPositions.push_back(G4ThreeVector(x, << 196 for(G4int i=1;i<=nb;i++){ 192 ++k; << 197 b+=db; >> 198 new G4PVPlacement(rot,G4ThreeVector(x,y,z),pmt_log,"pmt", >> 199 fHousing_log,false,k); >> 200 fPmtPositions.push_back(G4ThreeVector(x,y,z)); >> 201 k++; 193 } 202 } 194 } 203 } 195 } 204 } 196 205 197 //....oooOO0OOooo........oooOO0OOooo........oo 206 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 198 207 199 void LXeMainVolume::VisAttributes() << 208 void LXeMainVolume::VisAttributes(){ 200 { << 209 G4VisAttributes* housing_va = new G4VisAttributes(G4Colour(0.8,0.8,0.8)); 201 auto housing_va = new G4VisAttributes(G4Colo << 202 fHousing_log->SetVisAttributes(housing_va); 210 fHousing_log->SetVisAttributes(housing_va); 203 211 204 auto sphere_va = new G4VisAttributes(); << 212 G4VisAttributes* sphere_va = new G4VisAttributes(); 205 sphere_va->SetForceSolid(true); 213 sphere_va->SetForceSolid(true); 206 fSphere_log->SetVisAttributes(sphere_va); 214 fSphere_log->SetVisAttributes(sphere_va); 207 } 215 } 208 216 209 //....oooOO0OOooo........oooOO0OOooo........oo 217 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 210 218 211 void LXeMainVolume::SurfaceProperties() << 219 void LXeMainVolume::SurfaceProperties(){ 212 { << 220 G4double ephoton[] = {7.0*eV, 7.14*eV}; 213 std::vector<G4double> ephoton = {7.0 * eV, 7 << 221 const G4int num = sizeof(ephoton)/sizeof(G4double); 214 222 215 //**Scintillator housing properties 223 //**Scintillator housing properties 216 std::vector<G4double> reflectivity = {fRefl, << 224 G4double reflectivity[] = {fRefl, fRefl}; 217 std::vector<G4double> efficiency = {0.0, 0.0 << 225 assert(sizeof(reflectivity) == sizeof(ephoton)); 218 auto scintHsngPT = new G4MaterialPropertiesT << 226 G4double efficiency[] = {0.0, 0.0}; 219 scintHsngPT->AddProperty("REFLECTIVITY", eph << 227 assert(sizeof(efficiency) == sizeof(ephoton)); 220 scintHsngPT->AddProperty("EFFICIENCY", ephot << 228 G4MaterialPropertiesTable* scintHsngPT = new G4MaterialPropertiesTable(); 221 auto OpScintHousingSurface = << 229 scintHsngPT->AddProperty("REFLECTIVITY", ephoton, reflectivity, num); 222 new G4OpticalSurface("HousingSurface", uni << 230 scintHsngPT->AddProperty("EFFICIENCY", ephoton, efficiency, num); >> 231 G4OpticalSurface* OpScintHousingSurface = >> 232 new G4OpticalSurface("HousingSurface",unified,polished,dielectric_metal); 223 OpScintHousingSurface->SetMaterialProperties 233 OpScintHousingSurface->SetMaterialPropertiesTable(scintHsngPT); 224 << 234 225 //**Sphere surface properties 235 //**Sphere surface properties 226 std::vector<G4double> sphereReflectivity = { << 236 G4double sphereReflectivity[] = {1.0, 1.0}; 227 std::vector<G4double> sphereEfficiency = {0. << 237 assert(sizeof(sphereReflectivity) == sizeof(ephoton)); 228 auto spherePT = new G4MaterialPropertiesTabl << 238 G4double sphereEfficiency[] = {0.0, 0.0}; 229 spherePT->AddProperty("REFLECTIVITY", ephoto << 239 assert(sizeof(sphereEfficiency) == sizeof(ephoton)); 230 spherePT->AddProperty("EFFICIENCY", ephoton, << 240 G4MaterialPropertiesTable* spherePT = new G4MaterialPropertiesTable(); 231 auto OpSphereSurface = new G4OpticalSurface( << 241 spherePT->AddProperty("REFLECTIVITY", ephoton, sphereReflectivity, num); >> 242 spherePT->AddProperty("EFFICIENCY", ephoton, sphereEfficiency, num); >> 243 G4OpticalSurface* OpSphereSurface = >> 244 new G4OpticalSurface("SphereSurface",unified,polished,dielectric_metal); 232 OpSphereSurface->SetMaterialPropertiesTable( 245 OpSphereSurface->SetMaterialPropertiesTable(spherePT); 233 << 246 234 //**Photocathode surface properties 247 //**Photocathode surface properties 235 std::vector<G4double> photocath_EFF = {1., 1 << 248 G4double photocath_EFF[]={1.,1.}; //Enables 'detection' of photons 236 std::vector<G4double> photocath_ReR = {1.92, << 249 assert(sizeof(photocath_EFF) == sizeof(ephoton)); 237 std::vector<G4double> photocath_ImR = {1.69, << 250 G4double photocath_ReR[]={1.92,1.92}; 238 auto photocath_mt = new G4MaterialProperties << 251 assert(sizeof(photocath_ReR) == sizeof(ephoton)); 239 photocath_mt->AddProperty("EFFICIENCY", epho << 252 G4double photocath_ImR[]={1.69,1.69}; 240 photocath_mt->AddProperty("REALRINDEX", epho << 253 assert(sizeof(photocath_ImR) == sizeof(ephoton)); 241 photocath_mt->AddProperty("IMAGINARYRINDEX", << 254 G4MaterialPropertiesTable* photocath_mt = new G4MaterialPropertiesTable(); 242 auto photocath_opsurf = << 255 photocath_mt->AddProperty("EFFICIENCY",ephoton,photocath_EFF,num); 243 new G4OpticalSurface("photocath_opsurf", g << 256 photocath_mt->AddProperty("REALRINDEX",ephoton,photocath_ReR,num); >> 257 photocath_mt->AddProperty("IMAGINARYRINDEX",ephoton,photocath_ImR,num); >> 258 G4OpticalSurface* photocath_opsurf= >> 259 new G4OpticalSurface("photocath_opsurf",glisur,polished, >> 260 dielectric_metal); 244 photocath_opsurf->SetMaterialPropertiesTable 261 photocath_opsurf->SetMaterialPropertiesTable(photocath_mt); 245 262 246 //**Create logical skin surfaces 263 //**Create logical skin surfaces 247 new G4LogicalSkinSurface("photocath_surf", f << 264 new G4LogicalSkinSurface("photocath_surf",fHousing_log, 248 new G4LogicalSkinSurface("sphere_surface", f << 265 OpScintHousingSurface); 249 new G4LogicalSkinSurface("photocath_surf", f << 266 new G4LogicalSkinSurface("sphere_surface",fSphere_log,OpSphereSurface); >> 267 new G4LogicalSkinSurface("photocath_surf",fPhotocath_log,photocath_opsurf); 250 } 268 } 251 269