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/wls/src/WLSDetectorConstruct << 28 /// \brief Implementation of the WLSDetectorCo << 29 // 27 // 30 // << 31 << 32 #include "WLSDetectorConstruction.hh" << 33 28 34 #include "WLSDetectorMessenger.hh" << 29 #include "G4ios.hh" 35 #include "WLSMaterials.hh" << 30 #include "globals.hh" 36 #include "WLSPhotonDetSD.hh" << 37 31 38 #include "G4Box.hh" 32 #include "G4Box.hh" 39 #include "G4Colour.hh" << 33 #include "G4Tubs.hh" 40 #include "G4EllipticalTube.hh" 34 #include "G4EllipticalTube.hh" 41 #include "G4GeometryManager.hh" << 35 42 #include "G4LogicalBorderSurface.hh" << 43 #include "G4LogicalSkinSurface.hh" << 44 #include "G4LogicalVolume.hh" 36 #include "G4LogicalVolume.hh" 45 #include "G4LogicalVolumeStore.hh" << 37 #include "G4PVPlacement.hh" >> 38 >> 39 #include "G4OpBoundaryProcess.hh" >> 40 #include "G4LogicalBorderSurface.hh" >> 41 46 #include "G4Material.hh" 42 #include "G4Material.hh" 47 #include "G4NistManager.hh" 43 #include "G4NistManager.hh" 48 #include "G4OpticalSurface.hh" << 44 49 #include "G4PVPlacement.hh" << 45 #include "G4GeometryManager.hh" 50 #include "G4PhysicalConstants.hh" << 51 #include "G4PhysicalVolumeStore.hh" << 52 #include "G4RunManager.hh" << 53 #include "G4SDManager.hh" 46 #include "G4SDManager.hh" >> 47 54 #include "G4SolidStore.hh" 48 #include "G4SolidStore.hh" 55 #include "G4SystemOfUnits.hh" << 49 #include "G4RegionStore.hh" 56 #include "G4Tubs.hh" << 50 #include "G4LogicalVolumeStore.hh" >> 51 #include "G4PhysicalVolumeStore.hh" >> 52 >> 53 #include "G4RunManager.hh" >> 54 >> 55 #include "WLSDetectorConstruction.hh" >> 56 #include "WLSDetectorMessenger.hh" >> 57 #include "WLSMaterials.hh" >> 58 #include "WLSPhotonDetSD.hh" >> 59 57 #include "G4UserLimits.hh" 60 #include "G4UserLimits.hh" 58 #include "G4VisAttributes.hh" << 59 #include "G4ios.hh" << 60 #include "globals.hh" << 61 61 62 //....oooOO0OOooo........oooOO0OOooo........oo << 62 WLSPhotonDetSD* WLSDetectorConstruction::mppcSD = NULL; 63 63 64 WLSDetectorConstruction::WLSDetectorConstructi << 64 WLSDetectorConstruction::WLSDetectorConstruction() >> 65 : physiWorld(NULL) 65 { 66 { 66 fDetectorMessenger = new WLSDetectorMessenge << 67 67 68 fMPPCHalfL = fWLSfiberRY; << 68 detectorMessenger = new WLSDetectorMessenger(this); 69 fClrfiberZ = fMPPCZ + 10. * nm; << 69 materials = NULL; 70 fHoleLength = fBarLength; << 71 } << 72 70 73 //....oooOO0OOooo........oooOO0OOooo........oo << 71 numOfCladLayers = 0; >> 72 >> 73 surfaceRoughness = 1; >> 74 >> 75 mirrorToggle = true; >> 76 mirrorPolish = 1.; >> 77 mirrorReflectivity = 1.; >> 78 >> 79 mppcPolish = 1.; >> 80 mppcReflectivity = 0.; >> 81 >> 82 extrusionPolish = 1.; >> 83 extrusionReflectivity = 1.; >> 84 >> 85 XYRatio = 1.0; >> 86 >> 87 wlsfiberZ = 1.*m; >> 88 wlsfiberRY = 0.5*mm; >> 89 wlsfiberOrigin = 0.0; >> 90 >> 91 mppcShape = "Circle"; >> 92 mppcHalfL = wlsfiberRY; >> 93 mppcDist = 0.00*mm; >> 94 mppcTheta = 0.0*deg; >> 95 mppcZ = 0.05*mm; >> 96 >> 97 clrfiberZ = mppcZ + 10.*nm ; >> 98 mirrorZ = 0.1*mm; >> 99 >> 100 barLength = 1.*m; >> 101 barBase = 9.6*mm; >> 102 holeRadius = 0.9*mm; >> 103 holeLength = barLength; >> 104 coatingThickness = 0.25*mm; >> 105 coatingRadius = 1.875*mm; >> 106 >> 107 UpdateGeometryParameters(); >> 108 } 74 109 75 WLSDetectorConstruction::~WLSDetectorConstruct 110 WLSDetectorConstruction::~WLSDetectorConstruction() 76 { 111 { 77 delete fDetectorMessenger; << 112 if (detectorMessenger) delete detectorMessenger; 78 delete fMaterials; << 113 if (materials) delete materials; 79 for (auto visAttributes : fVisAttributes) { << 80 delete visAttributes; << 81 } << 82 } 114 } 83 115 84 //....oooOO0OOooo........oooOO0OOooo........oo << 85 << 86 G4VPhysicalVolume* WLSDetectorConstruction::Co 116 G4VPhysicalVolume* WLSDetectorConstruction::Construct() 87 { 117 { 88 if (fPhysiWorld) { << 118 materials = WLSMaterials::GetInstance(); 89 G4GeometryManager::GetInstance()->OpenGeom << 90 G4PhysicalVolumeStore::GetInstance()->Clea << 91 G4LogicalVolumeStore::GetInstance()->Clean << 92 G4SolidStore::GetInstance()->Clean(); << 93 G4LogicalSkinSurface::CleanSurfaceTable(); << 94 G4LogicalBorderSurface::CleanSurfaceTable( << 95 } << 96 << 97 fMaterials = WLSMaterials::GetInstance(); << 98 UpdateGeometryParameters(); << 99 119 100 return ConstructDetector(); 120 return ConstructDetector(); 101 } 121 } 102 122 103 //....oooOO0OOooo........oooOO0OOooo........oo << 104 << 105 G4VPhysicalVolume* WLSDetectorConstruction::Co 123 G4VPhysicalVolume* WLSDetectorConstruction::ConstructDetector() 106 { 124 { 107 auto air = FindMaterial("G4_AIR"); << 108 // G4cout << "\nMaterial Properties Table fo << 109 // air->GetMaterialPropertiesTable()->DumpTa << 110 << 111 //------------------------------------------ 125 //-------------------------------------------------- 112 // World 126 // World 113 //------------------------------------------ 127 //-------------------------------------------------- 114 128 115 G4VSolid* solidWorld = new G4Box("World", fW << 129 G4VSolid* solidWorld = >> 130 new G4Box("World", worldSizeX, worldSizeY, worldSizeZ); 116 131 117 fLogicWorld = new G4LogicalVolume(solidWorld << 132 logicWorld = new G4LogicalVolume(solidWorld, 118 << 133 FindMaterial("G4_AIR"), 119 fPhysiWorld = << 134 "World"); 120 new G4PVPlacement(nullptr, G4ThreeVector() << 135 >> 136 physiWorld = new G4PVPlacement(0, >> 137 G4ThreeVector(), >> 138 logicWorld, >> 139 "World", >> 140 0, >> 141 false, >> 142 0); 121 143 122 //------------------------------------------ 144 //-------------------------------------------------- 123 // Extrusion 145 // Extrusion 124 //------------------------------------------ 146 //-------------------------------------------------- 125 147 126 auto coating = FindMaterial("Coating"); << 127 << 128 G4VSolid* solidExtrusion = 148 G4VSolid* solidExtrusion = 129 new G4Box("Extrusion", GetBarBase() / 2., << 149 new G4Box("Extrusion",GetBarBase()/2,GetBarBase()/2,GetBarLength()/2); 130 << 131 auto logicExtrusion = new G4LogicalVolume(so << 132 << 133 auto TiO2Surface = << 134 new G4OpticalSurface("TiO2Surface", glisur << 135 << 136 auto TiO2SurfaceProperty = new G4MaterialPro << 137 << 138 std::vector<G4double> p_TiO2 = {2.00 * eV, 3 << 139 150 140 std::vector<G4double> refl_TiO2 = {fExtrusio << 151 G4LogicalVolume* logicExtrusion = 141 std::vector<G4double> effi_TiO2 = {0., 0.}; << 152 new G4LogicalVolume(solidExtrusion, >> 153 FindMaterial("Coating"), >> 154 "Extrusion"); >> 155 >> 156 G4OpticalSurface* TiO2Surface = new G4OpticalSurface("TiO2Surface", >> 157 glisur, >> 158 ground, >> 159 dielectric_metal, >> 160 extrusionPolish); >> 161 >> 162 G4MaterialPropertiesTable* TiO2SurfaceProperty = >> 163 new G4MaterialPropertiesTable(); >> 164 >> 165 G4double p_TiO2[2] = {2.00*eV, 3.47*eV}; >> 166 G4double refl_TiO2[2] = {extrusionReflectivity,extrusionReflectivity}; >> 167 G4double effi_TiO2[2] = {0, 0}; >> 168 >> 169 TiO2SurfaceProperty -> AddProperty("REFLECTIVITY",p_TiO2,refl_TiO2,2); >> 170 TiO2SurfaceProperty -> AddProperty("EFFICIENCY",p_TiO2,effi_TiO2,2); >> 171 >> 172 TiO2Surface -> SetMaterialPropertiesTable(TiO2SurfaceProperty); >> 173 >> 174 new G4PVPlacement(0, >> 175 G4ThreeVector(), >> 176 logicExtrusion, >> 177 "Extrusion", >> 178 logicWorld, >> 179 false, >> 180 0); 142 181 143 TiO2SurfaceProperty->AddProperty("REFLECTIVI << 182 new G4LogicalSkinSurface("TiO2Surface",logicExtrusion,TiO2Surface); 144 TiO2SurfaceProperty->AddProperty("EFFICIENCY << 145 << 146 TiO2Surface->SetMaterialPropertiesTable(TiO2 << 147 << 148 new G4PVPlacement(nullptr, G4ThreeVector(), << 149 << 150 new G4LogicalSkinSurface("TiO2Surface", logi << 151 183 152 //------------------------------------------ 184 //-------------------------------------------------- 153 // Scintillator 185 // Scintillator 154 //------------------------------------------ 186 //-------------------------------------------------- 155 187 156 auto polystyrene = FindMaterial("Polystyrene << 188 G4VSolid* solidScintillator = new G4Box("Scintillator", 157 // G4cout << "\nMaterial Properties Table fo << 189 GetBarBase()/2-GetCoatingThickness() 158 // polystyrene->GetMaterialPropertiesTable() << 190 -GetCoatingRadius(), 159 << 191 GetBarBase()/2-GetCoatingThickness() 160 G4VSolid* solidScintillator = << 192 -GetCoatingRadius(), 161 new G4Box("Scintillator", GetBarBase() / 2 << 193 GetBarLength()/2); 162 GetBarBase() / 2. - GetCoatingTh << 194 163 << 195 G4LogicalVolume* logicScintillator = 164 auto logicScintillator = new G4LogicalVolume << 196 new G4LogicalVolume(solidScintillator, 165 << 197 FindMaterial("Polystyrene"), 166 new G4PVPlacement(nullptr, G4ThreeVector(), << 198 "Scintillator"); 167 false, 0); << 199 168 << 200 new G4PVPlacement(0, 169 G4LogicalVolume* logicScintSide = nullptr; << 201 G4ThreeVector(), 170 G4LogicalVolume* logicScintCrnr = nullptr; << 202 logicScintillator, 171 if (GetCoatingRadius() > 0.) { << 203 "Scintillator", 172 G4VSolid* solidScintside = << 204 logicExtrusion, 173 new G4Box("SideOfBar", GetBarBase() / 2. << 205 false, 174 GetCoatingRadius() / 2., GetBa << 206 0); 175 << 207 176 G4VSolid* solidScintcrnr = new G4Tubs("Crn << 208 if (GetCoatingRadius() > 0.*mm) { 177 GetB << 209 G4VSolid* solidScintside = new G4Box("SideOfBar", 178 << 210 GetBarBase()/2-GetCoatingThickness() 179 logicScintSide = new G4LogicalVolume(solid << 211 -GetCoatingRadius(), 180 << 212 GetCoatingRadius()/2, 181 logicScintCrnr = new G4LogicalVolume(solid << 213 GetBarLength()/2); 182 << 214 G4VSolid* solidScintcrnr = new G4Tubs("CrnrOfBar", 183 G4double pos = GetBarBase() / 2. - GetCoat << 215 0.0*cm, 184 << 216 GetCoatingRadius(), 185 new G4PVPlacement(nullptr, G4ThreeVector(0 << 217 GetBarLength()/2, 186 logicExtrusion, false, 0 << 218 0.*deg, 187 << 219 90.*deg); 188 new G4PVPlacement(nullptr, G4ThreeVector(0 << 220 G4LogicalVolume* logicScintSide = 189 logicExtrusion, false, 1 << 221 new G4LogicalVolume(solidScintside, 190 << 222 FindMaterial("Polystyrene"), 191 auto rot1 = new G4RotationMatrix(); << 223 "SideOfBar"); 192 rot1->rotateZ(-90. * deg); << 224 193 << 225 G4LogicalVolume* logicScintCrnr = 194 new G4PVPlacement(rot1, G4ThreeVector(pos, << 226 new G4LogicalVolume(solidScintcrnr, 195 false, 2); << 227 FindMaterial("Polystyrene"), 196 << 228 "CrnrOfBar"); 197 new G4PVPlacement(rot1, G4ThreeVector(-pos << 229 198 logicExtrusion, false, 3 << 230 G4double x=GetBarBase()/2-GetCoatingThickness()-GetCoatingRadius()/2; 199 << 231 G4double y=GetBarBase()/2-GetCoatingThickness()-GetCoatingRadius()/2; 200 pos = GetBarBase() / 2. - GetCoatingThickn << 232 201 << 233 new G4PVPlacement(0, 202 new G4PVPlacement(nullptr, G4ThreeVector(p << 234 G4ThreeVector(0,-y,0), 203 logicExtrusion, false, 0 << 235 logicScintSide, 204 << 236 "SideOfBar", 205 new G4PVPlacement(rot1, G4ThreeVector(-pos << 237 logicExtrusion, 206 logicExtrusion, false, 1 << 238 false, 207 << 239 0); 208 auto rot2 = new G4RotationMatrix(); << 240 new G4PVPlacement(0, 209 rot2->rotateZ(-180. * deg); << 241 G4ThreeVector(0, y,0), 210 << 242 logicScintSide, 211 new G4PVPlacement(rot2, G4ThreeVector(-pos << 243 "SideOfBar", 212 logicExtrusion, false, 2 << 244 logicExtrusion, 213 << 245 false, 214 auto rot3 = new G4RotationMatrix(); << 246 1); 215 rot3->rotateZ(-270. * deg); << 247 216 << 248 G4RotationMatrix* g4rot = new G4RotationMatrix(); 217 new G4PVPlacement(rot3, G4ThreeVector(pos, << 249 *g4rot = stringToRotationMatrix("Z90"); 218 logicExtrusion, false, 3 << 250 *g4rot = g4rot->inverse(); >> 251 if (*g4rot == G4RotationMatrix()) g4rot = NULL; >> 252 >> 253 new G4PVPlacement(g4rot, >> 254 G4ThreeVector(x,0,0), >> 255 logicScintSide, >> 256 "SideOfBar", >> 257 logicExtrusion, >> 258 false, >> 259 2); >> 260 new G4PVPlacement(g4rot, >> 261 G4ThreeVector(-x,0,0), >> 262 logicScintSide, >> 263 "SideOfBar", >> 264 logicExtrusion, >> 265 false, >> 266 3); >> 267 >> 268 x = GetBarBase()/2-GetCoatingThickness()-GetCoatingRadius(); >> 269 y = GetBarBase()/2-GetCoatingThickness()-GetCoatingRadius(); >> 270 >> 271 new G4PVPlacement(0, >> 272 G4ThreeVector(x,y,0), >> 273 logicScintCrnr, >> 274 "CrnrOfBar", >> 275 logicExtrusion, >> 276 false, >> 277 0); >> 278 >> 279 new G4PVPlacement(g4rot, >> 280 G4ThreeVector(-x,y,0), >> 281 logicScintCrnr, >> 282 "CrnrOfBar", >> 283 logicExtrusion, >> 284 false, >> 285 1); >> 286 >> 287 g4rot = new G4RotationMatrix(); >> 288 *g4rot = stringToRotationMatrix("Z180"); >> 289 *g4rot = g4rot->inverse(); >> 290 if (*g4rot == G4RotationMatrix()) g4rot = NULL; >> 291 >> 292 new G4PVPlacement(g4rot, >> 293 G4ThreeVector(-x,-y,0), >> 294 logicScintCrnr, >> 295 "CrnrOfBar", >> 296 logicExtrusion, >> 297 false, >> 298 2); >> 299 >> 300 g4rot = new G4RotationMatrix(); >> 301 *g4rot = stringToRotationMatrix("Z270"); >> 302 *g4rot = g4rot->inverse(); >> 303 if (*g4rot == G4RotationMatrix()) g4rot = NULL; >> 304 >> 305 new G4PVPlacement(g4rot, >> 306 G4ThreeVector(x,-y,0), >> 307 logicScintCrnr, >> 308 "CrnrOfBar", >> 309 logicExtrusion, >> 310 false, >> 311 3); >> 312 >> 313 } >> 314 >> 315 if (GetFiberRadius()<GetHoleRadius()) { >> 316 >> 317 G4VSolid* solidHole = new G4Tubs("Hole", >> 318 0.0*cm, >> 319 GetHoleRadius(), >> 320 GetHoleLength()/2, >> 321 0.*deg, >> 322 360.*deg); >> 323 logicHole = new G4LogicalVolume(solidHole, >> 324 FindMaterial("G4_AIR"), >> 325 "Hole"); >> 326 >> 327 physiHole = new G4PVPlacement(0, >> 328 G4ThreeVector(), >> 329 logicHole, >> 330 "Hole", >> 331 logicScintillator, >> 332 false, >> 333 0); 219 } 334 } 220 335 221 if (GetFiberRadius() < GetHoleRadius()) { << 336 //-------------------------------------------------- 222 G4VSolid* solidHole = << 337 // Fiber 223 new G4Tubs("Hole", 0., GetHoleRadius(), << 338 //-------------------------------------------------- 224 << 225 fLogicHole = new G4LogicalVolume(solidHole << 226 339 227 fPhysiHole = << 340 ConstructFiber(); 228 new G4PVPlacement(nullptr, G4ThreeVector << 229 } << 230 341 231 //------------------------------------------ 342 //-------------------------------------------------- 232 // Fiber << 343 // End of Construction 233 //------------------------------------------ 344 //-------------------------------------------------- 234 345 235 if (!(fLogicHole) || !(fPhysiHole)) { << 346 return physiWorld; 236 G4ExceptionDescription ed; << 347 } 237 ed << "The Fiber Hole has not been constru << 348 238 G4Exception("WLSDetectorConstruction", "wl << 349 void WLSDetectorConstruction::ConstructFiber() >> 350 { >> 351 if (!(logicHole) || !(physiHole) ) { >> 352 std::ostringstream o; >> 353 o << "The Fiber Hole has not been constructed"; >> 354 G4Exception("WLSDetectorConstruction::ConstructFiber","", >> 355 FatalException,o.str().c_str()); 239 } 356 } 240 357 241 // Pointers to the most recently constructed 358 // Pointers to the most recently constructed volume 242 G4LogicalVolume* logicPlacement = fLogicHole << 359 G4LogicalVolume* logicPlacement = logicHole; 243 G4VPhysicalVolume* physiPlacement = fPhysiHo << 360 G4VPhysicalVolume* physiPlacement = physiHole; 244 361 245 //------------------------------------------ 362 //-------------------------------------------------- 246 // Fiber Construction 363 // Fiber Construction 247 //------------------------------------------ << 364 //-------------------------------------------------- 248 365 249 // Boundary Surface Properties 366 // Boundary Surface Properties 250 G4OpticalSurface* opSurface = nullptr; << 367 G4OpticalSurface* OpSurface = NULL; >> 368 >> 369 if (surfaceRoughness < 1.) >> 370 OpSurface = new G4OpticalSurface("RoughSurface", // Surface Name >> 371 glisur, // SetModel >> 372 ground, // SetFinish >> 373 dielectric_dielectric, // SetType >> 374 surfaceRoughness); // SetPolish 251 375 252 if (fSurfaceRoughness < 1.) << 376 G4LogicalVolume *logicClad1, *logicClad2; 253 opSurface = new G4OpticalSurface("RoughSur << 377 G4VPhysicalVolume *physiClad1, *physiClad2; 254 fSurfaceR << 255 << 256 G4LogicalVolume* logicWLSfiber = nullptr; << 257 G4LogicalVolume* logicClad1 = nullptr; << 258 G4LogicalVolume* logicClad2 = nullptr; << 259 G4VPhysicalVolume* physiClad1 = nullptr; << 260 G4VPhysicalVolume* physiClad2 = nullptr; << 261 << 262 auto fpethylene = FindMaterial("FPethylene") << 263 auto pethylene = FindMaterial("Pethylene"); << 264 auto pmma = FindMaterial("PMMA"); << 265 378 266 // Determine the number of cladding layers t 379 // Determine the number of cladding layers to be built 267 switch (fNumOfCladLayers) { << 380 switch ( numOfCladLayers ) { >> 381 268 case 2: 382 case 2: 269 383 270 //-------------------------------------- << 384 //-------------------------------------------------- 271 // Cladding 2 << 385 // Cladding 2 272 //-------------------------------------- << 386 //-------------------------------------------------- 273 << 387 274 // G4cout << "\nMaterial Properties Tabl << 388 G4VSolid* solidClad2; 275 // fpethylene->GetMaterialPropertiesTabl << 389 276 << 390 if (XYRatio == 1.) 277 G4VSolid* solidClad2; << 391 solidClad2 = new G4Tubs("Clad2",0.,clad2RX,clad2Z,0.0*rad,twopi*rad); 278 << 392 else 279 if (fXYRatio == 1.) << 393 solidClad2 = new G4EllipticalTube("Clad2",clad2RX,clad2RY,clad2Z); 280 solidClad2 = new G4Tubs("Clad2", 0., f << 394 281 else << 395 logicClad2 = new G4LogicalVolume(solidClad2, 282 solidClad2 = new G4EllipticalTube("Cla << 396 FindMaterial("FPethylene"), 283 << 397 "Clad2"); 284 logicClad2 = new G4LogicalVolume(solidCl << 398 285 << 399 physiClad2 = new G4PVPlacement(0, 286 physiClad2 = new G4PVPlacement(nullptr, << 400 G4ThreeVector(0.0,0.0,wlsfiberOrigin), 287 "Clad2", << 401 logicClad2, 288 << 402 "Clad2", 289 // Place the rough surface only if neede << 403 logicPlacement, 290 if (opSurface) { << 404 false, 291 new G4LogicalBorderSurface("surfaceCla << 405 0); 292 new G4LogicalBorderSurface("surfaceCla << 406 293 } << 407 // Place the rough surface only if needed 294 << 408 if (OpSurface) { 295 logicPlacement = logicClad2; << 409 new G4LogicalBorderSurface("surfaceClad2Out", 296 physiPlacement = physiClad2; << 410 physiClad2, 297 [[fallthrough]]; << 411 physiPlacement, 298 << 412 OpSurface); 299 case 1: << 413 new G4LogicalBorderSurface("surfaceClad2In", 300 << 414 physiPlacement, 301 //-------------------------------------- << 415 physiClad2, 302 // Cladding 1 << 416 OpSurface); 303 //-------------------------------------- << 417 } 304 << 305 // G4cout << "\nMaterial Properties Tabl << 306 // pethylene->GetMaterialPropertiesTable << 307 418 308 G4VSolid* solidClad1; << 419 logicPlacement = logicClad2; >> 420 physiPlacement = physiClad2; 309 421 310 if (fXYRatio == 1.) << 422 case 1: 311 solidClad1 = new G4Tubs("Clad1", 0., f << 312 else << 313 solidClad1 = new G4EllipticalTube("Cla << 314 << 315 logicClad1 = new G4LogicalVolume(solidCl << 316 << 317 physiClad1 = new G4PVPlacement(nullptr, << 318 "Clad1", << 319 << 320 // Place the rough surface only if neede << 321 if (opSurface) { << 322 new G4LogicalBorderSurface("surfaceCla << 323 423 324 new G4LogicalBorderSurface("surfaceCla << 424 //-------------------------------------------------- 325 } << 425 // Cladding 1 >> 426 //-------------------------------------------------- >> 427 >> 428 G4VSolid* solidClad1; >> 429 >> 430 if (XYRatio == 1.) >> 431 solidClad1 = new G4Tubs("Clad1",0.,clad1RX,clad1Z,0.0*rad,twopi*rad); >> 432 else >> 433 solidClad1 = new G4EllipticalTube("Clad1",clad1RX,clad1RY,clad1Z); >> 434 >> 435 logicClad1 = new G4LogicalVolume(solidClad1, >> 436 FindMaterial("Pethylene"), >> 437 "Clad1"); >> 438 >> 439 physiClad1 = new G4PVPlacement(0, >> 440 G4ThreeVector(0.0,0.0,wlsfiberOrigin), >> 441 logicClad1, >> 442 "Clad1", >> 443 logicPlacement, >> 444 false, >> 445 0); >> 446 >> 447 // Place the rough surface only if needed >> 448 if (OpSurface) { >> 449 new G4LogicalBorderSurface("surfaceClad1Out", >> 450 physiClad1, >> 451 physiPlacement, >> 452 OpSurface); >> 453 new G4LogicalBorderSurface("surfaceClad1In", >> 454 physiPlacement, >> 455 physiClad1, >> 456 OpSurface); >> 457 } 326 458 327 logicPlacement = logicClad1; << 459 logicPlacement = logicClad1; 328 physiPlacement = physiClad1; << 460 physiPlacement = physiClad1; 329 [[fallthrough]]; << 330 461 331 default: 462 default: 332 463 333 //-------------------------------------- << 464 //-------------------------------------------------- 334 // WLS Fiber << 465 // WLS Fiber 335 //-------------------------------------- << 466 //-------------------------------------------------- 336 << 467 337 // G4cout << "\nMaterial Properties Tabl << 468 G4VSolid* solidWLSfiber; 338 // pmma->GetMaterialPropertiesTable()->D << 469 339 << 470 if (XYRatio == 1.) 340 G4VSolid* solidWLSfiber; << 471 solidWLSfiber = 341 << 472 new G4Tubs("WLSFiber",0.,wlsfiberRX,wlsfiberZ,0.0*rad,twopi*rad); 342 if (fXYRatio == 1.) { << 473 else 343 solidWLSfiber = new G4Tubs("WLSFiber", << 474 solidWLSfiber = 344 } << 475 new G4EllipticalTube("WLSFiber",wlsfiberRX,wlsfiberRY,wlsfiberZ); 345 else { << 476 346 solidWLSfiber = new G4EllipticalTube(" << 477 G4LogicalVolume* logicWLSfiber = 347 } << 478 new G4LogicalVolume(solidWLSfiber, 348 << 479 FindMaterial("PMMA"), 349 logicWLSfiber = new G4LogicalVolume(soli << 480 "WLSFiber"); 350 << 481 351 logicWLSfiber->SetUserLimits(new G4UserL << 482 logicWLSfiber->SetUserLimits(new G4UserLimits(DBL_MAX,DBL_MAX,10*ms)); 352 << 483 353 G4VPhysicalVolume* physiWLSfiber = << 484 G4VPhysicalVolume* physiWLSfiber = new G4PVPlacement(0, 354 new G4PVPlacement(nullptr, G4ThreeVect << 485 G4ThreeVector(0.0,0.0,wlsfiberOrigin), 355 "WLSFiber", logicPla << 486 logicWLSfiber, 356 << 487 "WLSFiber", 357 // Place the rough surface only if neede << 488 logicPlacement, 358 if (opSurface) { << 489 false, 359 new G4LogicalBorderSurface("surfaceWLS << 490 0); 360 << 491 361 new G4LogicalBorderSurface("surfaceWLS << 492 // Place the rough surface only if needed 362 } << 493 if (OpSurface) { >> 494 new G4LogicalBorderSurface("surfaceWLSOut", >> 495 physiWLSfiber, >> 496 physiPlacement, >> 497 OpSurface); >> 498 new G4LogicalBorderSurface("surfaceWLSIn", >> 499 physiPlacement, >> 500 physiWLSfiber, >> 501 OpSurface); >> 502 } 363 } 503 } 364 504 365 //------------------------------------------ 505 //-------------------------------------------------- 366 // Mirror for reflection at one of the end 506 // Mirror for reflection at one of the end 367 //------------------------------------------ 507 //-------------------------------------------------- 368 508 369 // Place the mirror only if the user wants t 509 // Place the mirror only if the user wants the mirror 370 G4LogicalVolume* logicMirror = nullptr; << 510 if (mirrorToggle) { 371 << 372 auto aluminum = FindMaterial("G4_Al"); << 373 << 374 if (fMirrorToggle) { << 375 G4VSolid* solidMirror = new G4Box("Mirror" << 376 << 377 logicMirror = new G4LogicalVolume(solidMir << 378 511 379 auto mirrorSurface = << 512 G4VSolid* solidMirror = new G4Box("Mirror", 380 new G4OpticalSurface("MirrorSurface", gl << 513 mirrorRmax, >> 514 mirrorRmax, >> 515 mirrorZ); >> 516 >> 517 G4LogicalVolume* logicMirror = new G4LogicalVolume(solidMirror, >> 518 FindMaterial("G4_Al"), >> 519 "Mirror"); >> 520 >> 521 G4OpticalSurface* MirrorSurface = new G4OpticalSurface("MirrorSurface", >> 522 glisur, >> 523 ground, >> 524 dielectric_metal, >> 525 mirrorPolish); >> 526 >> 527 G4MaterialPropertiesTable* MirrorSurfaceProperty = >> 528 new G4MaterialPropertiesTable(); >> 529 >> 530 G4double p_mirror[2] = {2.00*eV, 3.47*eV}; >> 531 G4double refl_mirror[2] = {mirrorReflectivity,mirrorReflectivity}; >> 532 G4double effi_mirror[2] = {0, 0}; >> 533 >> 534 MirrorSurfaceProperty->AddProperty("REFLECTIVITY",p_mirror,refl_mirror,2); >> 535 MirrorSurfaceProperty->AddProperty("EFFICIENCY",p_mirror,effi_mirror,2); >> 536 >> 537 MirrorSurface -> SetMaterialPropertiesTable(MirrorSurfaceProperty); >> 538 >> 539 new G4PVPlacement(0, >> 540 G4ThreeVector(0.0,0.0,mirrorOrigin), >> 541 logicMirror, >> 542 "Mirror", >> 543 logicWorld, >> 544 false, >> 545 0); 381 546 382 auto mirrorSurfaceProperty = new G4Materia << 547 new G4LogicalSkinSurface("MirrorSurface",logicMirror,MirrorSurface); 383 << 384 std::vector<G4double> p_mirror = {2.00 * e << 385 std::vector<G4double> refl_mirror = {fMirr << 386 std::vector<G4double> effi_mirror = {0., 0 << 387 << 388 mirrorSurfaceProperty->AddProperty("REFLEC << 389 mirrorSurfaceProperty->AddProperty("EFFICI << 390 << 391 mirrorSurface->SetMaterialPropertiesTable( << 392 << 393 new G4PVPlacement(nullptr, G4ThreeVector(0 << 394 fLogicWorld, false, 0); << 395 << 396 new G4LogicalSkinSurface("MirrorSurface", << 397 } 548 } 398 549 399 //------------------------------------------ 550 //-------------------------------------------------- 400 // Coupling at the read-out end 551 // Coupling at the read-out end 401 //------------------------------------------ << 552 //-------------------------------------------------- 402 553 403 // Clear Fiber (Coupling Layer) 554 // Clear Fiber (Coupling Layer) 404 G4VSolid* solidCouple = new G4Box("Couple", << 555 G4VSolid* solidCouple = new G4Box("Couple",coupleRX,coupleRY,coupleZ); 405 556 406 auto logicCouple = new G4LogicalVolume(solid << 557 G4LogicalVolume* logicCouple = new G4LogicalVolume(solidCouple, 407 << 558 FindMaterial("G4_AIR"), 408 new G4PVPlacement(nullptr, G4ThreeVector(0., << 559 "Couple"); 409 fLogicWorld, false, 0); << 560 >> 561 new G4PVPlacement(0, >> 562 G4ThreeVector(0.0,0.0,coupleOrigin), >> 563 logicCouple, >> 564 "Couple", >> 565 logicWorld, >> 566 false, >> 567 0); 410 568 411 //------------------------------------------ 569 //-------------------------------------------------- 412 // A logical layer in front of PhotonDet 570 // A logical layer in front of PhotonDet 413 //------------------------------------------ << 571 //-------------------------------------------------- 414 572 415 // Purpose: Preventing direct dielectric to << 573 // Purpose: Preventing direct dielectric to metal contact 416 574 417 // Check for valid placement of PhotonDet 575 // Check for valid placement of PhotonDet 418 if (fMPPCTheta > std::atan(fMPPCDist / fMPPC << 576 if (mppcTheta > std::atan(mppcDist / mppcHalfL)) { 419 fMPPCTheta = 0.; << 420 fMPPCOriginX = std::sin(fMPPCTheta) * (fMP << 421 fMPPCOriginZ = -fCoupleZ + std::cos(fMPPCT << 422 G4ExceptionDescription ed; << 423 ed << "Invalid alignment. Alignment reset << 424 G4Exception("WLSDetectorConstruction", "wl << 425 } << 426 577 >> 578 mppcTheta = 0; >> 579 mppcOriginX = std::sin(mppcTheta) * (mppcDist + clrfiberZ); >> 580 mppcOriginZ = -coupleZ + std::cos(mppcTheta) * (mppcDist + clrfiberZ); >> 581 G4cerr << "Invalid alignment. Alignment Reset to 0" << G4endl; >> 582 } >> 583 427 // Clear Fiber (Coupling Layer) 584 // Clear Fiber (Coupling Layer) 428 G4VSolid* solidClrfiber; 585 G4VSolid* solidClrfiber; >> 586 >> 587 if ( mppcShape == "Square" ) >> 588 solidClrfiber = >> 589 new G4Box("ClearFiber",clrfiberHalfL,clrfiberHalfL,clrfiberZ); >> 590 else >> 591 solidClrfiber = >> 592 new G4Tubs("ClearFiber",0.,clrfiberHalfL,clrfiberZ,0.0*rad,twopi*rad); 429 593 430 if (fMPPCShape == "Square") { << 594 G4LogicalVolume* logicClrfiber = 431 solidClrfiber = new G4Box("ClearFiber", fC << 595 new G4LogicalVolume(solidClrfiber, 432 } << 596 FindMaterial("G4_AIR"), 433 else { << 597 "ClearFiber"); 434 solidClrfiber = new G4Tubs("ClearFiber", 0 << 598 435 } << 599 new G4PVPlacement(new G4RotationMatrix(CLHEP::HepRotationY(-mppcTheta)), 436 << 600 G4ThreeVector(mppcOriginX,0.0,mppcOriginZ), 437 auto logicClrfiber = new G4LogicalVolume(sol << 601 logicClrfiber, 438 << 602 "ClearFiber", 439 new G4PVPlacement(new G4RotationMatrix(CLHEP << 603 logicCouple, 440 G4ThreeVector(fMPPCOriginX << 604 false, 441 logicCouple, false, 0); << 605 0); 442 606 443 //------------------------------------------ 607 //-------------------------------------------------- 444 // PhotonDet (Sensitive Detector) 608 // PhotonDet (Sensitive Detector) 445 //------------------------------------------ << 609 //-------------------------------------------------- 446 610 447 // Physical Construction 611 // Physical Construction 448 G4VSolid* solidPhotonDet = nullptr; << 612 G4VSolid* solidPhotonDet; 449 613 450 if (fMPPCShape == "Square") << 614 if ( mppcShape == "Square" ) 451 solidPhotonDet = new G4Box("PhotonDet", fM << 615 solidPhotonDet = new G4Box("PhotonDet",mppcHalfL,mppcHalfL,mppcZ); 452 else 616 else 453 solidPhotonDet = new G4Tubs("PhotonDet", 0 << 617 solidPhotonDet = 454 << 618 new G4Tubs("PhotonDet",0.,mppcHalfL,mppcZ,0.0*rad,twopi*rad); 455 auto logicPhotonDet = new G4LogicalVolume(so << 456 619 457 new G4PVPlacement(nullptr, G4ThreeVector(0., << 620 G4LogicalVolume* logicPhotonDet = 458 false, 0); << 621 new G4LogicalVolume(solidPhotonDet, >> 622 FindMaterial("G4_Al"), >> 623 "PhotonDet"); >> 624 >> 625 new G4PVPlacement(0, >> 626 G4ThreeVector(0.0,0.0,0.0), >> 627 logicPhotonDet, >> 628 "PhotonDet", >> 629 logicClrfiber, >> 630 false, >> 631 0); 459 632 460 // PhotonDet Surface Properties 633 // PhotonDet Surface Properties 461 auto photonDetSurface = << 634 G4OpticalSurface* PhotonDetSurface = new G4OpticalSurface("PhotonDetSurface", 462 new G4OpticalSurface("PhotonDetSurface", g << 635 glisur, >> 636 ground, >> 637 dielectric_metal, >> 638 mppcPolish); 463 639 464 auto photonDetSurfaceProperty = new G4Materi << 640 G4MaterialPropertiesTable* PhotonDetSurfaceProperty = 465 << 641 new G4MaterialPropertiesTable(); 466 std::vector<G4double> p_mppc = {2.00 * eV, 3 << 467 std::vector<G4double> refl_mppc = {fMPPCRefl << 468 std::vector<G4double> effi_mppc = {1., 1.}; << 469 << 470 photonDetSurfaceProperty->AddProperty("REFLE << 471 photonDetSurfaceProperty->AddProperty("EFFIC << 472 << 473 photonDetSurface->SetMaterialPropertiesTable << 474 << 475 new G4LogicalSkinSurface("PhotonDetSurface", << 476 << 477 // visualization attributes ---------------- << 478 << 479 auto visAttributes = new G4VisAttributes(G4C << 480 visAttributes->SetVisibility(false); << 481 fLogicWorld->SetVisAttributes(visAttributes) << 482 fVisAttributes.push_back(visAttributes); << 483 << 484 visAttributes = new G4VisAttributes(G4Colour << 485 visAttributes->SetVisibility(true); << 486 logicExtrusion->SetVisAttributes(visAttribut << 487 fVisAttributes.push_back(visAttributes); << 488 << 489 visAttributes = new G4VisAttributes(G4Colour << 490 visAttributes->SetVisibility(true); << 491 logicScintillator->SetVisAttributes(visAttri << 492 fVisAttributes.push_back(visAttributes); << 493 << 494 visAttributes = new G4VisAttributes(G4Colour << 495 visAttributes->SetVisibility(true); << 496 logicScintSide->SetVisAttributes(visAttribut << 497 fVisAttributes.push_back(visAttributes); << 498 << 499 visAttributes = new G4VisAttributes(G4Colour << 500 visAttributes->SetVisibility(true); << 501 logicScintCrnr->SetVisAttributes(visAttribut << 502 fVisAttributes.push_back(visAttributes); << 503 << 504 visAttributes = new G4VisAttributes(G4Colour << 505 visAttributes->SetVisibility(true); << 506 fLogicHole->SetVisAttributes(visAttributes); << 507 fVisAttributes.push_back(visAttributes); << 508 << 509 if (logicClad1 != nullptr) { << 510 visAttributes = new G4VisAttributes(G4Colo << 511 visAttributes->SetVisibility(true); << 512 logicClad1->SetVisAttributes(visAttributes << 513 fVisAttributes.push_back(visAttributes); << 514 } << 515 642 516 if (logicClad2 != nullptr) { << 643 G4double p_mppc[2] = {2.00*eV, 3.47*eV}; 517 visAttributes = new G4VisAttributes(G4Colo << 644 G4double refl_mppc[2] = {mppcReflectivity,mppcReflectivity}; 518 visAttributes->SetVisibility(true); << 645 G4double effi_mppc[2] = {1, 1}; 519 logicClad2->SetVisAttributes(visAttributes << 646 520 fVisAttributes.push_back(visAttributes); << 647 PhotonDetSurfaceProperty -> AddProperty("REFLECTIVITY",p_mppc,refl_mppc,2); 521 } << 648 PhotonDetSurfaceProperty -> AddProperty("EFFICIENCY",p_mppc,effi_mppc,2); 522 649 523 visAttributes = new G4VisAttributes(G4Colour << 650 PhotonDetSurface -> SetMaterialPropertiesTable(PhotonDetSurfaceProperty); 524 visAttributes->SetVisibility(true); << 651 525 logicWLSfiber->SetVisAttributes(visAttribute << 652 new G4LogicalSkinSurface("PhotonDetSurface",logicPhotonDet,PhotonDetSurface); 526 fVisAttributes.push_back(visAttributes); << 527 << 528 if (fMirrorToggle == true) { << 529 visAttributes = new G4VisAttributes(G4Colo << 530 visAttributes->SetVisibility(true); << 531 logicMirror->SetVisAttributes(visAttribute << 532 fVisAttributes.push_back(visAttributes); << 533 } << 534 653 535 visAttributes = new G4VisAttributes(G4Colour << 654 if (!mppcSD) { 536 visAttributes->SetVisibility(true); << 655 G4String mppcSDName = "WLS/PhotonDet"; 537 logicCouple->SetVisAttributes(visAttributes) << 656 mppcSD = new WLSPhotonDetSD(mppcSDName); 538 fVisAttributes.push_back(visAttributes); << 539 657 540 visAttributes = new G4VisAttributes(G4Colour << 658 G4SDManager* SDman = G4SDManager::GetSDMpointer(); 541 visAttributes->SetVisibility(true); << 659 SDman->AddNewDetector(mppcSD); 542 logicClrfiber->SetVisAttributes(visAttribute << 660 } 543 fVisAttributes.push_back(visAttributes); << 544 661 545 visAttributes = new G4VisAttributes(G4Colour << 662 // Setting the detector to be sensitive 546 visAttributes->SetVisibility(true); << 663 logicPhotonDet->SetSensitiveDetector(mppcSD); 547 logicPhotonDet->SetVisAttributes(visAttribut << 548 fVisAttributes.push_back(visAttributes); << 549 664 550 return fPhysiWorld; << 551 } 665 } 552 666 553 //....oooOO0OOooo........oooOO0OOooo........oo << 667 void WLSDetectorConstruction::UpdateGeometry() 554 << 555 void WLSDetectorConstruction::ConstructSDandFi << 556 { 668 { 557 if (!fmppcSD.Get()) { << 669 if (!physiWorld) return; 558 G4String mppcSDName = "WLS/PhotonDet"; << 559 auto mppcSD = new WLSPhotonDetSD(mppcSDNam << 560 G4SDManager::GetSDMpointer()->AddNewDetect << 561 fmppcSD.Put(mppcSD); << 562 } << 563 SetSensitiveDetector("PhotonDet_LV", fmppcSD << 564 } << 565 670 566 //....oooOO0OOooo........oooOO0OOooo........oo << 671 // clean-up previous geometry >> 672 G4GeometryManager::GetInstance()->OpenGeometry(); 567 673 568 void WLSDetectorConstruction::UpdateGeometryPa << 674 G4PhysicalVolumeStore::GetInstance()->Clean(); 569 { << 675 G4LogicalVolumeStore::GetInstance()->Clean(); 570 fWLSfiberRX = fXYRatio * fWLSfiberRY; << 676 G4SolidStore::GetInstance()->Clean(); >> 677 G4LogicalSkinSurface::CleanSurfaceTable(); >> 678 G4LogicalBorderSurface::CleanSurfaceTable(); 571 679 572 fClad1RX = fWLSfiberRX + 0.03 * fWLSfiberRX; << 680 //define new one 573 fClad1RY = fWLSfiberRY + 0.03 * fWLSfiberRY; << 681 UpdateGeometryParameters(); 574 fClad1Z = fWLSfiberZ; << 682 >> 683 G4RunManager::GetRunManager()->DefineWorldVolume(ConstructDetector()); 575 684 576 fClad2RX = fClad1RX + 0.03 * fWLSfiberRX; << 685 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 577 fClad2RY = fClad1RY + 0.03 * fWLSfiberRY; << 686 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 578 fClad2Z = fWLSfiberZ; << 579 687 580 fWorldSizeX = fClad2RX + fMPPCDist + fMPPCHa << 688 G4RegionStore::GetInstance()->UpdateMaterialList(physiWorld); 581 fWorldSizeY = fClad2RY + fMPPCDist + fMPPCHa << 689 } 582 fWorldSizeZ = fWLSfiberZ + fMPPCDist + fMPPC << 583 690 584 fCoupleRX = fWorldSizeX; << 691 void WLSDetectorConstruction::UpdateGeometryParameters() 585 fCoupleRY = fWorldSizeY; << 692 { 586 fCoupleZ = (fWorldSizeZ - fWLSfiberZ) / 2.; << 693 wlsfiberRX = XYRatio * wlsfiberRY; 587 694 588 fClrfiberHalfL = fMPPCHalfL; << 695 clad1RX = wlsfiberRX + 0.03*wlsfiberRX; >> 696 clad1RY = wlsfiberRY + 0.03*wlsfiberRY; >> 697 clad1Z = wlsfiberZ; >> 698 >> 699 clad2RX = clad1RX + 0.03*wlsfiberRX; >> 700 clad2RY = clad1RY + 0.03*wlsfiberRY; >> 701 clad2Z = wlsfiberZ; >> 702 >> 703 worldSizeX = clad2RX + mppcDist + mppcHalfL + 1.*cm; >> 704 worldSizeY = clad2RY + mppcDist + mppcHalfL + 1.*cm; >> 705 worldSizeZ = wlsfiberZ + mppcDist + mppcHalfL + 1.*cm; >> 706 >> 707 coupleRX = worldSizeX; >> 708 coupleRY = worldSizeY; >> 709 coupleZ = (worldSizeZ - wlsfiberZ) / 2; >> 710 >> 711 clrfiberHalfL = mppcHalfL; >> 712 >> 713 mirrorRmax = clad2RY; >> 714 >> 715 coupleOrigin = wlsfiberOrigin + wlsfiberZ + coupleZ; >> 716 mirrorOrigin = wlsfiberOrigin - wlsfiberZ - mirrorZ; >> 717 mppcOriginX = std::sin(mppcTheta) * (mppcDist + clrfiberZ); >> 718 mppcOriginZ = -coupleZ + std::cos(mppcTheta) * (mppcDist + clrfiberZ); >> 719 } >> 720 >> 721 G4RotationMatrix >> 722 WLSDetectorConstruction::stringToRotationMatrix(G4String rotation) >> 723 { >> 724 // We apply successive rotations OF THE OBJECT around the FIXED >> 725 // axes of the parent's local coordinates; rotations are applied >> 726 // left-to-right (rotation="r1,r2,r3" => r1 then r2 then r3). >> 727 >> 728 G4RotationMatrix rot; >> 729 >> 730 unsigned int place = 0; >> 731 >> 732 while (place < rotation.size()) { >> 733 >> 734 G4double angle; >> 735 char* p; >> 736 >> 737 angle = strtod(rotation.substr(place+1).c_str(),&p) * deg; >> 738 >> 739 if (!p || (*p != (char)',' && *p != (char)'\0')) { >> 740 G4cerr << "Invalid rotation specification: " << >> 741 rotation.c_str() << G4endl; >> 742 return rot; >> 743 } >> 744 >> 745 G4RotationMatrix thisRotation; >> 746 >> 747 switch(rotation.substr(place,1).c_str()[0]) { >> 748 case 'X': case 'x': >> 749 thisRotation = G4RotationMatrix(CLHEP::HepRotationX(angle)); >> 750 break; >> 751 case 'Y': case 'y': >> 752 thisRotation = G4RotationMatrix(CLHEP::HepRotationY(angle)); >> 753 break; >> 754 case 'Z': case 'z': >> 755 thisRotation = G4RotationMatrix(CLHEP::HepRotationZ(angle)); >> 756 break; >> 757 default: >> 758 G4cerr << " Invalid rotation specification: " >> 759 << rotation << G4endl; >> 760 return rot; >> 761 } >> 762 >> 763 rot = thisRotation * rot; >> 764 place = rotation.find(',',place); >> 765 if (place > rotation.size()) break; >> 766 ++place; >> 767 } 589 768 590 fMirrorRmax = fClad2RY; << 769 return rot; 591 770 592 fCoupleOrigin = fWLSfiberOrigin + fWLSfiberZ << 593 fMirrorOrigin = fWLSfiberOrigin - fWLSfiberZ << 594 fMPPCOriginX = std::sin(fMPPCTheta) * (fMPPC << 595 fMPPCOriginZ = -fCoupleZ + std::cos(fMPPCThe << 596 } 771 } 597 772 598 //....oooOO0OOooo........oooOO0OOooo........oo << 599 << 600 void WLSDetectorConstruction::SetPhotonDetGeom << 601 // Set the Geometry of the PhotonDet detector 773 // Set the Geometry of the PhotonDet detector 602 // Pre: shape must be either "Circle" and "Sq 774 // Pre: shape must be either "Circle" and "Square" >> 775 void WLSDetectorConstruction::SetPhotonDetGeometry (G4String shape) 603 { 776 { 604 if (shape == "Circle" || shape == "Square") << 777 if (shape == "Circle" || shape == "Square" ) mppcShape = shape; 605 G4RunManager::GetRunManager()->GeometryHasBe << 606 } 778 } 607 779 608 //....oooOO0OOooo........oooOO0OOooo........oo << 609 << 610 void WLSDetectorConstruction::SetNumberOfCladd << 611 // Set the number of claddings 780 // Set the number of claddings 612 // Pre: 0 <= num <= 2 781 // Pre: 0 <= num <= 2 >> 782 void WLSDetectorConstruction::SetNumberOfCladding(G4int num) 613 { 783 { 614 fNumOfCladLayers = num; << 784 numOfCladLayers = num; 615 G4RunManager::GetRunManager()->GeometryHasBe << 616 } 785 } 617 786 618 //....oooOO0OOooo........oooOO0OOooo........oo << 619 << 620 void WLSDetectorConstruction::SetWLSLength(G4d << 621 // Set the TOTAL length of the WLS fiber 787 // Set the TOTAL length of the WLS fiber >> 788 void WLSDetectorConstruction::SetWLSLength (G4double length) 622 { 789 { 623 fWLSfiberZ = length; << 790 wlsfiberZ = length; 624 G4RunManager::GetRunManager()->GeometryHasBe << 625 } 791 } 626 792 627 //....oooOO0OOooo........oooOO0OOooo........oo << 628 << 629 void WLSDetectorConstruction::SetWLSRadius(G4d << 630 // Set the Y radius of WLS fiber 793 // Set the Y radius of WLS fiber >> 794 void WLSDetectorConstruction::SetWLSRadius (G4double radius) 631 { 795 { 632 fWLSfiberRY = radius; << 796 wlsfiberRY = radius; 633 G4RunManager::GetRunManager()->GeometryHasBe << 634 } 797 } 635 798 636 //....oooOO0OOooo........oooOO0OOooo........oo << 637 << 638 void WLSDetectorConstruction::SetClad1Radius(G << 639 // Set the Y radius of Cladding 1 799 // Set the Y radius of Cladding 1 >> 800 void WLSDetectorConstruction::SetClad1Radius (G4double radius) 640 { 801 { 641 fClad1RY = radius; << 802 clad1RY = radius; 642 G4RunManager::GetRunManager()->GeometryHasBe << 643 } 803 } 644 804 645 //....oooOO0OOooo........oooOO0OOooo........oo << 646 << 647 void WLSDetectorConstruction::SetClad2Radius(G << 648 // Set the Y radius of Cladding 2 805 // Set the Y radius of Cladding 2 >> 806 void WLSDetectorConstruction::SetClad2Radius (G4double radius) 649 { 807 { 650 fClad2RY = radius; << 808 clad2RY = radius; 651 G4RunManager::GetRunManager()->GeometryHasBe << 652 } 809 } 653 810 654 //....oooOO0OOooo........oooOO0OOooo........oo << 655 << 656 void WLSDetectorConstruction::SetPhotonDetHalf << 657 // Set the half length of the PhotonDet detect 811 // Set the half length of the PhotonDet detector 658 // The half length will be the radius if Photo 812 // The half length will be the radius if PhotonDet is circular >> 813 void WLSDetectorConstruction::SetPhotonDetHalfLength(G4double halfL) 659 { 814 { 660 fMPPCHalfL = halfL; << 815 mppcHalfL = halfL; 661 G4RunManager::GetRunManager()->GeometryHasBe << 662 } 816 } 663 817 664 //....oooOO0OOooo........oooOO0OOooo........oo << 665 << 666 void WLSDetectorConstruction::SetGap(G4double << 667 // Set the distance between fiber end and Phot 818 // Set the distance between fiber end and PhotonDet 668 { << 819 void WLSDetectorConstruction::SetGap (G4double gap) { mppcDist = gap; } 669 fMPPCDist = gap; << 670 G4RunManager::GetRunManager()->GeometryHasBe << 671 } << 672 820 673 //....oooOO0OOooo........oooOO0OOooo........oo << 674 << 675 void WLSDetectorConstruction::SetPhotonDetAlig << 676 // Set the Aligment of PhotonDet with respect 821 // Set the Aligment of PhotonDet with respect to the z axis 677 // If theta is 0 deg, then the detector is per 822 // If theta is 0 deg, then the detector is perfectly aligned 678 // PhotonDet will be deviated by theta from z 823 // PhotonDet will be deviated by theta from z axis 679 // facing towards the center of the fiber 824 // facing towards the center of the fiber >> 825 void WLSDetectorConstruction::SetPhotonDetAlignment(G4double theta) 680 { 826 { 681 fMPPCTheta = theta; << 827 mppcTheta = theta; 682 G4RunManager::GetRunManager()->GeometryHasBe << 683 } 828 } 684 829 685 //....oooOO0OOooo........oooOO0OOooo........oo << 686 << 687 void WLSDetectorConstruction::SetSurfaceRoughn << 688 // Set the Surface Roughness between Cladding 830 // Set the Surface Roughness between Cladding 1 and WLS fiber 689 // Pre: 0 < roughness <= 1 831 // Pre: 0 < roughness <= 1 >> 832 void WLSDetectorConstruction::SetSurfaceRoughness(G4double roughness) 690 { 833 { 691 fSurfaceRoughness = roughness; << 834 surfaceRoughness = roughness; 692 G4RunManager::GetRunManager()->GeometryHasBe << 693 } 835 } 694 836 695 //....oooOO0OOooo........oooOO0OOooo........oo << 696 << 697 void WLSDetectorConstruction::SetMirrorPolish( << 698 // Set the Polish of the mirror, polish of 1 i 837 // Set the Polish of the mirror, polish of 1 is a perfect mirror surface 699 // Pre: 0 < polish <= 1 838 // Pre: 0 < polish <= 1 >> 839 void WLSDetectorConstruction::SetMirrorPolish(G4double polish) 700 { 840 { 701 fMirrorPolish = polish; << 841 mirrorPolish = polish; 702 G4RunManager::GetRunManager()->GeometryHasBe << 703 } 842 } 704 843 705 //....oooOO0OOooo........oooOO0OOooo........oo << 706 << 707 void WLSDetectorConstruction::SetMirrorReflect << 708 // Set the Reflectivity of the mirror, reflect 844 // Set the Reflectivity of the mirror, reflectivity of 1 is a perfect mirror 709 // Pre: 0 < reflectivity <= 1 845 // Pre: 0 < reflectivity <= 1 >> 846 void WLSDetectorConstruction::SetMirrorReflectivity(G4double reflectivity) 710 { 847 { 711 fMirrorReflectivity = reflectivity; << 848 mirrorReflectivity = reflectivity; 712 G4RunManager::GetRunManager()->GeometryHasBe << 713 } 849 } 714 850 715 //....oooOO0OOooo........oooOO0OOooo........oo << 716 << 717 void WLSDetectorConstruction::SetPhotonDetPoli << 718 // Set the Polish of the PhotonDet, polish of 851 // Set the Polish of the PhotonDet, polish of 1 is a perfect mirror surface 719 // Pre: 0 < polish <= 1 852 // Pre: 0 < polish <= 1 >> 853 void WLSDetectorConstruction::SetPhotonDetPolish(G4double polish) 720 { 854 { 721 fMPPCPolish = polish; << 855 mppcPolish = polish; 722 G4RunManager::GetRunManager()->GeometryHasBe << 723 } 856 } 724 857 725 //....oooOO0OOooo........oooOO0OOooo........oo << 726 << 727 void WLSDetectorConstruction::SetPhotonDetRefl << 728 // Set the Reflectivity of the PhotonDet, refl 858 // Set the Reflectivity of the PhotonDet, reflectivity of 1 is a perfect mirror 729 // Pre: 0 < reflectivity <= 1 859 // Pre: 0 < reflectivity <= 1 >> 860 void WLSDetectorConstruction::SetPhotonDetReflectivity(G4double reflectivity) 730 { 861 { 731 fMPPCReflectivity = reflectivity; << 862 mppcReflectivity = reflectivity; 732 G4RunManager::GetRunManager()->GeometryHasBe << 733 } 863 } 734 864 735 //....oooOO0OOooo........oooOO0OOooo........oo << 736 << 737 void WLSDetectorConstruction::SetMirror(G4bool << 738 // Toggle to place the mirror or not at one en 865 // Toggle to place the mirror or not at one end (-z end) of the fiber 739 // True means place the mirror, false means ot 866 // True means place the mirror, false means otherwise 740 { << 867 void WLSDetectorConstruction::SetMirror(G4bool flag) { mirrorToggle = flag; } 741 fMirrorToggle = flag; << 742 G4RunManager::GetRunManager()->GeometryHasBe << 743 } << 744 868 745 //....oooOO0OOooo........oooOO0OOooo........oo << 746 << 747 void WLSDetectorConstruction::SetXYRatio(G4dou << 748 // Set the ratio of the x and y radius of the 869 // Set the ratio of the x and y radius of the ellipse (x/y) 749 // a ratio of 1 would produce a circle 870 // a ratio of 1 would produce a circle 750 { << 871 void WLSDetectorConstruction::SetXYRatio(G4double r) { XYRatio = r; } 751 fXYRatio = r; << 752 G4RunManager::GetRunManager()->GeometryHasBe << 753 } << 754 872 755 //....oooOO0OOooo........oooOO0OOooo........oo << 756 << 757 void WLSDetectorConstruction::SetBarLength(G4d << 758 // Set the length of the scintillator bar 873 // Set the length of the scintillator bar >> 874 void WLSDetectorConstruction::SetBarLength (G4double length) 759 { 875 { 760 fBarLength = length; << 876 barLength = length; 761 G4RunManager::GetRunManager()->GeometryHasBe << 762 } 877 } 763 878 764 //....oooOO0OOooo........oooOO0OOooo........oo << 765 << 766 void WLSDetectorConstruction::SetBarBase(G4dou << 767 // Set the side of the scintillator bar 879 // Set the side of the scintillator bar >> 880 void WLSDetectorConstruction::SetBarBase (G4double side) 768 { 881 { 769 fBarBase = side; << 882 barBase = side; 770 G4RunManager::GetRunManager()->GeometryHasBe << 771 } 883 } 772 884 773 //....oooOO0OOooo........oooOO0OOooo........oo << 774 << 775 void WLSDetectorConstruction::SetHoleRadius(G4 << 776 // Set the radius of the fiber hole 885 // Set the radius of the fiber hole >> 886 void WLSDetectorConstruction::SetHoleRadius (G4double radius) 777 { 887 { 778 fHoleRadius = radius; << 888 holeRadius = radius; 779 G4RunManager::GetRunManager()->GeometryHasBe << 780 } 889 } 781 890 782 //....oooOO0OOooo........oooOO0OOooo........oo << 783 << 784 void WLSDetectorConstruction::SetCoatingThickn << 785 // Set thickness of the coating on the bars 891 // Set thickness of the coating on the bars >> 892 void WLSDetectorConstruction::SetCoatingThickness (G4double thick) 786 { 893 { 787 fCoatingThickness = thick; << 894 coatingThickness = thick; 788 G4RunManager::GetRunManager()->GeometryHasBe << 789 } 895 } 790 896 791 //....oooOO0OOooo........oooOO0OOooo........oo << 792 << 793 void WLSDetectorConstruction::SetCoatingRadius << 794 // Set inner radius of the corner bar coating 897 // Set inner radius of the corner bar coating >> 898 void WLSDetectorConstruction::SetCoatingRadius (G4double radius) 795 { 899 { 796 fCoatingRadius = radius; << 900 coatingRadius = radius; 797 G4RunManager::GetRunManager()->GeometryHasBe << 798 } 901 } 799 902 800 //....oooOO0OOooo........oooOO0OOooo........oo << 903 G4double WLSDetectorConstruction::GetWLSFiberLength() { return wlsfiberZ; } 801 904 802 G4double WLSDetectorConstruction::GetWLSFiberL << 905 G4double WLSDetectorConstruction::GetBarLength() { return barLength; } 803 { << 906 G4double WLSDetectorConstruction::GetBarBase() { return barBase; } 804 return fWLSfiberZ; << 907 G4double WLSDetectorConstruction::GetHoleRadius() { return holeRadius; } 805 } << 908 G4double WLSDetectorConstruction::GetHoleLength() { return holeLength; } 806 << 909 G4double WLSDetectorConstruction::GetFiberRadius() { return GetWLSFiberRMax(); } 807 //....oooOO0OOooo........oooOO0OOooo........oo << 910 G4double WLSDetectorConstruction::GetCoatingThickness() 808 << 911 { return coatingThickness; } 809 G4double WLSDetectorConstruction::GetBarLength << 912 G4double WLSDetectorConstruction::GetCoatingRadius() { return coatingRadius; } 810 { << 811 return fBarLength; << 812 } << 813 << 814 //....oooOO0OOooo........oooOO0OOooo........oo << 815 << 816 G4double WLSDetectorConstruction::GetBarBase() << 817 { << 818 return fBarBase; << 819 } << 820 << 821 //....oooOO0OOooo........oooOO0OOooo........oo << 822 << 823 G4double WLSDetectorConstruction::GetHoleRadiu << 824 { << 825 return fHoleRadius; << 826 } << 827 << 828 //....oooOO0OOooo........oooOO0OOooo........oo << 829 << 830 G4double WLSDetectorConstruction::GetHoleLengt << 831 { << 832 return fHoleLength; << 833 } << 834 << 835 //....oooOO0OOooo........oooOO0OOooo........oo << 836 << 837 G4double WLSDetectorConstruction::GetFiberRadi << 838 { << 839 return GetWLSFiberRMax(); << 840 } << 841 << 842 //....oooOO0OOooo........oooOO0OOooo........oo << 843 << 844 G4double WLSDetectorConstruction::GetCoatingTh << 845 { << 846 return fCoatingThickness; << 847 } << 848 << 849 //....oooOO0OOooo........oooOO0OOooo........oo << 850 << 851 G4double WLSDetectorConstruction::GetCoatingRa << 852 { << 853 return fCoatingRadius; << 854 } << 855 << 856 //....oooOO0OOooo........oooOO0OOooo........oo << 857 913 858 G4double WLSDetectorConstruction::GetWLSFiberE 914 G4double WLSDetectorConstruction::GetWLSFiberEnd() 859 { 915 { 860 return fWLSfiberOrigin + fWLSfiberZ; << 916 return wlsfiberOrigin + wlsfiberZ; 861 } 917 } 862 918 863 //....oooOO0OOooo........oooOO0OOooo........oo << 864 << 865 G4double WLSDetectorConstruction::GetWLSFiberR 919 G4double WLSDetectorConstruction::GetWLSFiberRMax() 866 { 920 { 867 if (fNumOfCladLayers == 2) return fClad2RY; << 921 if (numOfCladLayers == 2) return clad2RY; 868 if (fNumOfCladLayers == 1) return fClad1RY; << 922 if (numOfCladLayers == 1) return clad1RY; 869 return fWLSfiberRY; << 923 return wlsfiberRY; 870 } 924 } 871 925 872 //....oooOO0OOooo........oooOO0OOooo........oo << 873 << 874 G4double WLSDetectorConstruction::GetSurfaceRo 926 G4double WLSDetectorConstruction::GetSurfaceRoughness() 875 { 927 { 876 return fSurfaceRoughness; << 928 return surfaceRoughness; 877 } 929 } 878 930 879 //....oooOO0OOooo........oooOO0OOooo........oo << 880 << 881 // Return True if the fiber construction is id 931 // Return True if the fiber construction is ideal 882 G4bool WLSDetectorConstruction::IsPerfectFiber 932 G4bool WLSDetectorConstruction::IsPerfectFiber() 883 { << 933 { 884 return fSurfaceRoughness == 1. && fXYRatio = << 934 return surfaceRoughness == 1. && XYRatio == 1. 885 && (!fMirrorToggle || (fMirrorPolish << 935 && (!mirrorToggle || >> 936 (mirrorPolish == 1. && mirrorReflectivity == 1.)); 886 } 937 } 887 938 888 //....oooOO0OOooo........oooOO0OOooo........oo << 939 G4Material* WLSDetectorConstruction::FindMaterial(G4String name) { 889 << 940 G4Material* material = G4Material::GetMaterial(name,true); 890 G4Material* WLSDetectorConstruction::FindMater << 941 return material; 891 { << 892 G4Material* material = G4Material::GetMateri << 893 return material; << 894 } 942 } 895 943