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