Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-22 08:09:42

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file WLSDetectorConstruction.cc
0027 /// \brief Implementation of the WLSDetectorConstruction class
0028 
0029 #include "WLSDetectorConstruction.hh"
0030 
0031 #include "WLSDetectorMessenger.hh"
0032 #include "WLSMaterials.hh"
0033 #include "WLSPhotonDetSD.hh"
0034 
0035 #include "G4Box.hh"
0036 #include "G4Colour.hh"
0037 #include "G4EllipticalTube.hh"
0038 #include "G4GeometryManager.hh"
0039 #include "G4LogicalBorderSurface.hh"
0040 #include "G4LogicalSkinSurface.hh"
0041 #include "G4LogicalVolume.hh"
0042 #include "G4LogicalVolumeStore.hh"
0043 #include "G4Material.hh"
0044 #include "G4NistManager.hh"
0045 #include "G4OpticalSurface.hh"
0046 #include "G4PVPlacement.hh"
0047 #include "G4PhysicalConstants.hh"
0048 #include "G4PhysicalVolumeStore.hh"
0049 #include "G4RunManager.hh"
0050 #include "G4SDManager.hh"
0051 #include "G4SolidStore.hh"
0052 #include "G4SystemOfUnits.hh"
0053 #include "G4Tubs.hh"
0054 #include "G4UserLimits.hh"
0055 #include "G4VisAttributes.hh"
0056 #include "G4ios.hh"
0057 #include "globals.hh"
0058 
0059 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0060 
0061 WLSDetectorConstruction::WLSDetectorConstruction() : fVisAttributes()
0062 {
0063   fDetectorMessenger = new WLSDetectorMessenger(this);
0064 
0065   fMPPCHalfL = fWLSfiberRY;
0066   fClrfiberZ = fMPPCZ + 10. * nm;
0067   fHoleLength = fBarLength;
0068 }
0069 
0070 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0071 
0072 WLSDetectorConstruction::~WLSDetectorConstruction()
0073 {
0074   delete fDetectorMessenger;
0075   delete fMaterials;
0076   for (auto visAttributes : fVisAttributes) {
0077     delete visAttributes;
0078   }
0079 }
0080 
0081 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0082 
0083 G4VPhysicalVolume* WLSDetectorConstruction::Construct()
0084 {
0085   if (fPhysiWorld) {
0086     G4GeometryManager::GetInstance()->OpenGeometry();
0087     G4PhysicalVolumeStore::GetInstance()->Clean();
0088     G4LogicalVolumeStore::GetInstance()->Clean();
0089     G4SolidStore::GetInstance()->Clean();
0090     G4LogicalSkinSurface::CleanSurfaceTable();
0091     G4LogicalBorderSurface::CleanSurfaceTable();
0092   }
0093 
0094   fMaterials = WLSMaterials::GetInstance();
0095   UpdateGeometryParameters();
0096 
0097   return ConstructDetector();
0098 }
0099 
0100 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0101 
0102 G4VPhysicalVolume* WLSDetectorConstruction::ConstructDetector()
0103 {
0104   auto air = FindMaterial("G4_AIR");
0105   // G4cout << "\nMaterial Properties Table for G4_AIR:" << G4endl;
0106   // air->GetMaterialPropertiesTable()->DumpTable();
0107 
0108   //--------------------------------------------------
0109   // World
0110   //--------------------------------------------------
0111 
0112   G4VSolid* solidWorld = new G4Box("World", fWorldSizeX, fWorldSizeY, fWorldSizeZ);
0113 
0114   fLogicWorld = new G4LogicalVolume(solidWorld, air, "World");
0115 
0116   fPhysiWorld =
0117     new G4PVPlacement(nullptr, G4ThreeVector(), fLogicWorld, "World", nullptr, false, 0);
0118 
0119   //--------------------------------------------------
0120   // Extrusion
0121   //--------------------------------------------------
0122 
0123   auto coating = FindMaterial("Coating");
0124 
0125   G4VSolid* solidExtrusion =
0126     new G4Box("Extrusion", GetBarBase() / 2., GetBarBase() / 2., GetBarLength() / 2.);
0127 
0128   auto logicExtrusion = new G4LogicalVolume(solidExtrusion, coating, "Extrusion");
0129 
0130   auto TiO2Surface =
0131     new G4OpticalSurface("TiO2Surface", glisur, ground, dielectric_metal, fExtrusionPolish);
0132 
0133   auto TiO2SurfaceProperty = new G4MaterialPropertiesTable();
0134 
0135   std::vector<G4double> p_TiO2 = {2.00 * eV, 3.47 * eV};
0136 
0137   std::vector<G4double> refl_TiO2 = {fExtrusionReflectivity, fExtrusionReflectivity};
0138   std::vector<G4double> effi_TiO2 = {0., 0.};
0139 
0140   TiO2SurfaceProperty->AddProperty("REFLECTIVITY", p_TiO2, refl_TiO2);
0141   TiO2SurfaceProperty->AddProperty("EFFICIENCY", p_TiO2, effi_TiO2);
0142 
0143   TiO2Surface->SetMaterialPropertiesTable(TiO2SurfaceProperty);
0144 
0145   new G4PVPlacement(nullptr, G4ThreeVector(), logicExtrusion, "Extrusion", fLogicWorld, false, 0);
0146 
0147   new G4LogicalSkinSurface("TiO2Surface", logicExtrusion, TiO2Surface);
0148 
0149   //--------------------------------------------------
0150   // Scintillator
0151   //--------------------------------------------------
0152 
0153   auto polystyrene = FindMaterial("Polystyrene");
0154   // G4cout << "\nMaterial Properties Table for Polystyrene:" << G4endl;
0155   // polystyrene->GetMaterialPropertiesTable()->DumpTable();
0156 
0157   G4VSolid* solidScintillator =
0158     new G4Box("Scintillator", GetBarBase() / 2. - GetCoatingThickness() - GetCoatingRadius(),
0159               GetBarBase() / 2. - GetCoatingThickness() - GetCoatingRadius(), GetBarLength() / 2.);
0160 
0161   auto logicScintillator = new G4LogicalVolume(solidScintillator, polystyrene, "Scintillator");
0162 
0163   new G4PVPlacement(nullptr, G4ThreeVector(), logicScintillator, "Scintillator", logicExtrusion,
0164                     false, 0);
0165 
0166   G4LogicalVolume* logicScintSide = nullptr;
0167   G4LogicalVolume* logicScintCrnr = nullptr;
0168   if (GetCoatingRadius() > 0.) {
0169     G4VSolid* solidScintside =
0170       new G4Box("SideOfBar", GetBarBase() / 2. - GetCoatingThickness() - GetCoatingRadius(),
0171                 GetCoatingRadius() / 2., GetBarLength() / 2.);
0172 
0173     G4VSolid* solidScintcrnr = new G4Tubs("CrnrOfBar", 0.0 * cm, GetCoatingRadius(),
0174                                           GetBarLength() / 2., 0. * deg, 90. * deg);
0175 
0176     logicScintSide = new G4LogicalVolume(solidScintside, polystyrene, "SideOfBar");
0177 
0178     logicScintCrnr = new G4LogicalVolume(solidScintcrnr, polystyrene, "CrnrOfBar");
0179 
0180     G4double pos = GetBarBase() / 2. - GetCoatingThickness() - GetCoatingRadius() / 2.;
0181 
0182     new G4PVPlacement(nullptr, G4ThreeVector(0., -pos, 0.), logicScintSide, "SideOfBar",
0183                       logicExtrusion, false, 0);
0184 
0185     new G4PVPlacement(nullptr, G4ThreeVector(0., pos, 0.), logicScintSide, "SideOfBar",
0186                       logicExtrusion, false, 1);
0187 
0188     auto rot1 = new G4RotationMatrix();
0189     rot1->rotateZ(-90. * deg);
0190 
0191     new G4PVPlacement(rot1, G4ThreeVector(pos, 0., 0.), logicScintSide, "SideOfBar", logicExtrusion,
0192                       false, 2);
0193 
0194     new G4PVPlacement(rot1, G4ThreeVector(-pos, 0., 0.), logicScintSide, "SideOfBar",
0195                       logicExtrusion, false, 3);
0196 
0197     pos = GetBarBase() / 2. - GetCoatingThickness() - GetCoatingRadius();
0198 
0199     new G4PVPlacement(nullptr, G4ThreeVector(pos, pos, 0.), logicScintCrnr, "CrnrOfBar",
0200                       logicExtrusion, false, 0);
0201 
0202     new G4PVPlacement(rot1, G4ThreeVector(-pos, pos, 0.), logicScintCrnr, "CrnrOfBar",
0203                       logicExtrusion, false, 1);
0204 
0205     auto rot2 = new G4RotationMatrix();
0206     rot2->rotateZ(-180. * deg);
0207 
0208     new G4PVPlacement(rot2, G4ThreeVector(-pos, -pos, 0.), logicScintCrnr, "CrnrOfBar",
0209                       logicExtrusion, false, 2);
0210 
0211     auto rot3 = new G4RotationMatrix();
0212     rot3->rotateZ(-270. * deg);
0213 
0214     new G4PVPlacement(rot3, G4ThreeVector(pos, -pos, 0.), logicScintCrnr, "CrnrOfBar",
0215                       logicExtrusion, false, 3);
0216   }
0217 
0218   if (GetFiberRadius() < GetHoleRadius()) {
0219     G4VSolid* solidHole =
0220       new G4Tubs("Hole", 0., GetHoleRadius(), GetHoleLength() / 2., 0. * deg, 360. * deg);
0221 
0222     fLogicHole = new G4LogicalVolume(solidHole, air, "Hole");
0223 
0224     fPhysiHole =
0225       new G4PVPlacement(nullptr, G4ThreeVector(), fLogicHole, "Hole", logicScintillator, false, 0);
0226   }
0227 
0228   //--------------------------------------------------
0229   // Fiber
0230   //--------------------------------------------------
0231 
0232   if (!(fLogicHole) || !(fPhysiHole)) {
0233     G4ExceptionDescription ed;
0234     ed << "The Fiber Hole has not been constructed";
0235     G4Exception("WLSDetectorConstruction", "wls001", FatalException, ed);
0236   }
0237 
0238   // Pointers to the most recently constructed volume
0239   G4LogicalVolume* logicPlacement = fLogicHole;
0240   G4VPhysicalVolume* physiPlacement = fPhysiHole;
0241 
0242   //--------------------------------------------------
0243   // Fiber Construction
0244   //--------------------------------------------------
0245 
0246   // Boundary Surface Properties
0247   G4OpticalSurface* opSurface = nullptr;
0248 
0249   if (fSurfaceRoughness < 1.)
0250     opSurface = new G4OpticalSurface("RoughSurface", glisur, ground, dielectric_dielectric,
0251                                      fSurfaceRoughness);
0252 
0253   G4LogicalVolume* logicWLSfiber = nullptr;
0254   G4LogicalVolume* logicClad1 = nullptr;
0255   G4LogicalVolume* logicClad2 = nullptr;
0256   G4VPhysicalVolume* physiClad1 = nullptr;
0257   G4VPhysicalVolume* physiClad2 = nullptr;
0258 
0259   auto fpethylene = FindMaterial("FPethylene");
0260   auto pethylene = FindMaterial("Pethylene");
0261   auto pmma = FindMaterial("PMMA");
0262 
0263   // Determine the number of cladding layers to be built
0264   switch (fNumOfCladLayers) {
0265     case 2:
0266 
0267       //--------------------------------------------------
0268       // Cladding 2
0269       //--------------------------------------------------
0270 
0271       // G4cout << "\nMaterial Properties Table for fPethylene:" << G4endl;
0272       // fpethylene->GetMaterialPropertiesTable()->DumpTable();
0273 
0274       G4VSolid* solidClad2;
0275 
0276       if (fXYRatio == 1.)
0277         solidClad2 = new G4Tubs("Clad2", 0., fClad2RX, fClad2Z, 0., twopi);
0278       else
0279         solidClad2 = new G4EllipticalTube("Clad2", fClad2RX, fClad2RY, fClad2Z);
0280 
0281       logicClad2 = new G4LogicalVolume(solidClad2, fpethylene, "Clad2");
0282 
0283       physiClad2 = new G4PVPlacement(nullptr, G4ThreeVector(0.0, 0.0, fWLSfiberOrigin), logicClad2,
0284                                      "Clad2", logicPlacement, false, 0);
0285 
0286       // Place the rough surface only if needed
0287       if (opSurface) {
0288         new G4LogicalBorderSurface("surfaceClad2Out", physiClad2, physiPlacement, opSurface);
0289         new G4LogicalBorderSurface("surfaceClad2In", physiPlacement, physiClad2, opSurface);
0290       }
0291 
0292       logicPlacement = logicClad2;
0293       physiPlacement = physiClad2;
0294       [[fallthrough]];
0295 
0296     case 1:
0297 
0298       //--------------------------------------------------
0299       // Cladding 1
0300       //--------------------------------------------------
0301 
0302       // G4cout << "\nMaterial Properties Table for Pethylene:" << G4endl;
0303       // pethylene->GetMaterialPropertiesTable()->DumpTable();
0304 
0305       G4VSolid* solidClad1;
0306 
0307       if (fXYRatio == 1.)
0308         solidClad1 = new G4Tubs("Clad1", 0., fClad1RX, fClad1Z, 0., twopi);
0309       else
0310         solidClad1 = new G4EllipticalTube("Clad1", fClad1RX, fClad1RY, fClad1Z);
0311 
0312       logicClad1 = new G4LogicalVolume(solidClad1, pethylene, "Clad1");
0313 
0314       physiClad1 = new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fWLSfiberOrigin), logicClad1,
0315                                      "Clad1", logicPlacement, false, 0);
0316 
0317       // Place the rough surface only if needed
0318       if (opSurface) {
0319         new G4LogicalBorderSurface("surfaceClad1Out", physiClad1, physiPlacement, opSurface);
0320 
0321         new G4LogicalBorderSurface("surfaceClad1In", physiPlacement, physiClad1, opSurface);
0322       }
0323 
0324       logicPlacement = logicClad1;
0325       physiPlacement = physiClad1;
0326       [[fallthrough]];
0327 
0328     default:
0329 
0330       //--------------------------------------------------
0331       // WLS Fiber
0332       //--------------------------------------------------
0333 
0334       // G4cout << "\nMaterial Properties Table for PMMA:" << G4endl;
0335       // pmma->GetMaterialPropertiesTable()->DumpTable();
0336 
0337       G4VSolid* solidWLSfiber;
0338 
0339       if (fXYRatio == 1.) {
0340         solidWLSfiber = new G4Tubs("WLSFiber", 0., fWLSfiberRX, fWLSfiberZ, 0., twopi);
0341       }
0342       else {
0343         solidWLSfiber = new G4EllipticalTube("WLSFiber", fWLSfiberRX, fWLSfiberRY, fWLSfiberZ);
0344       }
0345 
0346       logicWLSfiber = new G4LogicalVolume(solidWLSfiber, pmma, "WLSFiber");
0347 
0348       logicWLSfiber->SetUserLimits(new G4UserLimits(DBL_MAX, DBL_MAX, 10. * ms));
0349 
0350       G4VPhysicalVolume* physiWLSfiber =
0351         new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fWLSfiberOrigin), logicWLSfiber,
0352                           "WLSFiber", logicPlacement, false, 0);
0353 
0354       // Place the rough surface only if needed
0355       if (opSurface) {
0356         new G4LogicalBorderSurface("surfaceWLSOut", physiWLSfiber, physiPlacement, opSurface);
0357 
0358         new G4LogicalBorderSurface("surfaceWLSIn", physiPlacement, physiWLSfiber, opSurface);
0359       }
0360   }
0361 
0362   //--------------------------------------------------
0363   // Mirror for reflection at one of the end
0364   //--------------------------------------------------
0365 
0366   // Place the mirror only if the user wants the mirror
0367   G4LogicalVolume* logicMirror = nullptr;
0368 
0369   auto aluminum = FindMaterial("G4_Al");
0370 
0371   if (fMirrorToggle) {
0372     G4VSolid* solidMirror = new G4Box("Mirror", fMirrorRmax, fMirrorRmax, fMirrorZ);
0373 
0374     logicMirror = new G4LogicalVolume(solidMirror, aluminum, "Mirror");
0375 
0376     auto mirrorSurface =
0377       new G4OpticalSurface("MirrorSurface", glisur, ground, dielectric_metal, fMirrorPolish);
0378 
0379     auto mirrorSurfaceProperty = new G4MaterialPropertiesTable();
0380 
0381     std::vector<G4double> p_mirror = {2.00 * eV, 3.47 * eV};
0382     std::vector<G4double> refl_mirror = {fMirrorReflectivity, fMirrorReflectivity};
0383     std::vector<G4double> effi_mirror = {0., 0.};
0384 
0385     mirrorSurfaceProperty->AddProperty("REFLECTIVITY", p_mirror, refl_mirror);
0386     mirrorSurfaceProperty->AddProperty("EFFICIENCY", p_mirror, effi_mirror);
0387 
0388     mirrorSurface->SetMaterialPropertiesTable(mirrorSurfaceProperty);
0389 
0390     new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fMirrorOrigin), logicMirror, "Mirror",
0391                       fLogicWorld, false, 0);
0392 
0393     new G4LogicalSkinSurface("MirrorSurface", logicMirror, mirrorSurface);
0394   }
0395 
0396   //--------------------------------------------------
0397   // Coupling at the read-out end
0398   //--------------------------------------------------
0399 
0400   // Clear Fiber (Coupling Layer)
0401   G4VSolid* solidCouple = new G4Box("Couple", fCoupleRX, fCoupleRY, fCoupleZ);
0402 
0403   auto logicCouple = new G4LogicalVolume(solidCouple, air, "Couple");
0404 
0405   new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fCoupleOrigin), logicCouple, "Couple",
0406                     fLogicWorld, false, 0);
0407 
0408   //--------------------------------------------------
0409   // A logical layer in front of PhotonDet
0410   //--------------------------------------------------
0411 
0412   // Purpose: Preventing direct dielectric to metal contact
0413 
0414   // Check for valid placement of PhotonDet
0415   if (fMPPCTheta > std::atan(fMPPCDist / fMPPCHalfL)) {
0416     fMPPCTheta = 0.;
0417     fMPPCOriginX = std::sin(fMPPCTheta) * (fMPPCDist + fClrfiberZ);
0418     fMPPCOriginZ = -fCoupleZ + std::cos(fMPPCTheta) * (fMPPCDist + fClrfiberZ);
0419     G4ExceptionDescription ed;
0420     ed << "Invalid alignment.  Alignment reset to 0.";
0421     G4Exception("WLSDetectorConstruction", "wls002", JustWarning, ed);
0422   }
0423 
0424   // Clear Fiber (Coupling Layer)
0425   G4VSolid* solidClrfiber;
0426 
0427   if (fMPPCShape == "Square") {
0428     solidClrfiber = new G4Box("ClearFiber", fClrfiberHalfL, fClrfiberHalfL, fClrfiberZ);
0429   }
0430   else {
0431     solidClrfiber = new G4Tubs("ClearFiber", 0., fClrfiberHalfL, fClrfiberZ, 0., twopi);
0432   }
0433 
0434   auto logicClrfiber = new G4LogicalVolume(solidClrfiber, air, "ClearFiber");
0435 
0436   new G4PVPlacement(new G4RotationMatrix(CLHEP::HepRotationY(-fMPPCTheta)),
0437                     G4ThreeVector(fMPPCOriginX, 0.0, fMPPCOriginZ), logicClrfiber, "ClearFiber",
0438                     logicCouple, false, 0);
0439 
0440   //--------------------------------------------------
0441   // PhotonDet (Sensitive Detector)
0442   //--------------------------------------------------
0443 
0444   // Physical Construction
0445   G4VSolid* solidPhotonDet = nullptr;
0446 
0447   if (fMPPCShape == "Square")
0448     solidPhotonDet = new G4Box("PhotonDet", fMPPCHalfL, fMPPCHalfL, fMPPCZ);
0449   else
0450     solidPhotonDet = new G4Tubs("PhotonDet", 0., fMPPCHalfL, fMPPCZ, 0., twopi);
0451 
0452   auto logicPhotonDet = new G4LogicalVolume(solidPhotonDet, aluminum, "PhotonDet_LV");
0453 
0454   new G4PVPlacement(nullptr, G4ThreeVector(0., 0., 0.), logicPhotonDet, "PhotonDet", logicClrfiber,
0455                     false, 0);
0456 
0457   // PhotonDet Surface Properties
0458   auto photonDetSurface =
0459     new G4OpticalSurface("PhotonDetSurface", glisur, ground, dielectric_metal, fMPPCPolish);
0460 
0461   auto photonDetSurfaceProperty = new G4MaterialPropertiesTable();
0462 
0463   std::vector<G4double> p_mppc = {2.00 * eV, 3.47 * eV};
0464   std::vector<G4double> refl_mppc = {fMPPCReflectivity, fMPPCReflectivity};
0465   std::vector<G4double> effi_mppc = {1., 1.};
0466 
0467   photonDetSurfaceProperty->AddProperty("REFLECTIVITY", p_mppc, refl_mppc);
0468   photonDetSurfaceProperty->AddProperty("EFFICIENCY", p_mppc, effi_mppc);
0469 
0470   photonDetSurface->SetMaterialPropertiesTable(photonDetSurfaceProperty);
0471 
0472   new G4LogicalSkinSurface("PhotonDetSurface", logicPhotonDet, photonDetSurface);
0473 
0474   // visualization attributes -------------------------------------------------
0475 
0476   auto visAttributes = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
0477   visAttributes->SetVisibility(false);
0478   fLogicWorld->SetVisAttributes(visAttributes);
0479   fVisAttributes.push_back(visAttributes);
0480 
0481   visAttributes = new G4VisAttributes(G4Colour(0.2, 0.2, 0.2, 0.5));
0482   visAttributes->SetVisibility(true);
0483   logicExtrusion->SetVisAttributes(visAttributes);
0484   fVisAttributes.push_back(visAttributes);
0485 
0486   visAttributes = new G4VisAttributes(G4Colour(0.0, 0.0, 1.0, 0.9));
0487   visAttributes->SetVisibility(true);
0488   logicScintillator->SetVisAttributes(visAttributes);
0489   fVisAttributes.push_back(visAttributes);
0490 
0491   visAttributes = new G4VisAttributes(G4Colour(0.0, 0.8, 0.2, 0.2));
0492   visAttributes->SetVisibility(true);
0493   logicScintSide->SetVisAttributes(visAttributes);
0494   fVisAttributes.push_back(visAttributes);
0495 
0496   visAttributes = new G4VisAttributes(G4Colour(0.0, 0.8, 0.2, 0.2));
0497   visAttributes->SetVisibility(true);
0498   logicScintCrnr->SetVisAttributes(visAttributes);
0499   fVisAttributes.push_back(visAttributes);
0500 
0501   visAttributes = new G4VisAttributes(G4Colour(0.4, 0.0, 0.0, 0.5));
0502   visAttributes->SetVisibility(true);
0503   fLogicHole->SetVisAttributes(visAttributes);
0504   fVisAttributes.push_back(visAttributes);
0505 
0506   if (logicClad1 != nullptr) {
0507     visAttributes = new G4VisAttributes(G4Colour(0.0, 0.8, 0.5, 0.5));
0508     visAttributes->SetVisibility(true);
0509     logicClad1->SetVisAttributes(visAttributes);
0510     fVisAttributes.push_back(visAttributes);
0511   }
0512 
0513   if (logicClad2 != nullptr) {
0514     visAttributes = new G4VisAttributes(G4Colour(0.0, 0.5, 0.8, 0.5));
0515     visAttributes->SetVisibility(true);
0516     logicClad2->SetVisAttributes(visAttributes);
0517     fVisAttributes.push_back(visAttributes);
0518   }
0519 
0520   visAttributes = new G4VisAttributes(G4Colour(0.8, 0.8, 1.0));
0521   visAttributes->SetVisibility(true);
0522   logicWLSfiber->SetVisAttributes(visAttributes);
0523   fVisAttributes.push_back(visAttributes);
0524 
0525   if (fMirrorToggle == true) {
0526     visAttributes = new G4VisAttributes(G4Colour(0.3, 0.3, 1.0, 0.3));
0527     visAttributes->SetVisibility(true);
0528     logicMirror->SetVisAttributes(visAttributes);
0529     fVisAttributes.push_back(visAttributes);
0530   }
0531 
0532   visAttributes = new G4VisAttributes(G4Colour(0.0, 0.0, 0.5, 0.5));
0533   visAttributes->SetVisibility(true);
0534   logicCouple->SetVisAttributes(visAttributes);
0535   fVisAttributes.push_back(visAttributes);
0536 
0537   visAttributes = new G4VisAttributes(G4Colour(0.3, 0.3, 0.3, 0.5));
0538   visAttributes->SetVisibility(true);
0539   logicClrfiber->SetVisAttributes(visAttributes);
0540   fVisAttributes.push_back(visAttributes);
0541 
0542   visAttributes = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0, 0.8));
0543   visAttributes->SetVisibility(true);
0544   logicPhotonDet->SetVisAttributes(visAttributes);
0545   fVisAttributes.push_back(visAttributes);
0546 
0547   return fPhysiWorld;
0548 }
0549 
0550 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0551 
0552 void WLSDetectorConstruction::ConstructSDandField()
0553 {
0554   if (!fmppcSD.Get()) {
0555     G4String mppcSDName = "WLS/PhotonDet";
0556     auto mppcSD = new WLSPhotonDetSD(mppcSDName);
0557     G4SDManager::GetSDMpointer()->AddNewDetector(mppcSD);
0558     fmppcSD.Put(mppcSD);
0559   }
0560   SetSensitiveDetector("PhotonDet_LV", fmppcSD.Get(), true);
0561 }
0562 
0563 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0564 
0565 void WLSDetectorConstruction::UpdateGeometryParameters()
0566 {
0567   fWLSfiberRX = fXYRatio * fWLSfiberRY;
0568 
0569   fClad1RX = fWLSfiberRX + 0.03 * fWLSfiberRX;
0570   fClad1RY = fWLSfiberRY + 0.03 * fWLSfiberRY;
0571   fClad1Z = fWLSfiberZ;
0572 
0573   fClad2RX = fClad1RX + 0.03 * fWLSfiberRX;
0574   fClad2RY = fClad1RY + 0.03 * fWLSfiberRY;
0575   fClad2Z = fWLSfiberZ;
0576 
0577   fWorldSizeX = fClad2RX + fMPPCDist + fMPPCHalfL + 1. * cm;
0578   fWorldSizeY = fClad2RY + fMPPCDist + fMPPCHalfL + 1. * cm;
0579   fWorldSizeZ = fWLSfiberZ + fMPPCDist + fMPPCHalfL + 1. * cm;
0580 
0581   fCoupleRX = fWorldSizeX;
0582   fCoupleRY = fWorldSizeY;
0583   fCoupleZ = (fWorldSizeZ - fWLSfiberZ) / 2.;
0584 
0585   fClrfiberHalfL = fMPPCHalfL;
0586 
0587   fMirrorRmax = fClad2RY;
0588 
0589   fCoupleOrigin = fWLSfiberOrigin + fWLSfiberZ + fCoupleZ;
0590   fMirrorOrigin = fWLSfiberOrigin - fWLSfiberZ - fMirrorZ;
0591   fMPPCOriginX = std::sin(fMPPCTheta) * (fMPPCDist + fClrfiberZ);
0592   fMPPCOriginZ = -fCoupleZ + std::cos(fMPPCTheta) * (fMPPCDist + fClrfiberZ);
0593 }
0594 
0595 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0596 
0597 void WLSDetectorConstruction::SetPhotonDetGeometry(G4String shape)
0598 // Set the Geometry of the PhotonDet detector
0599 // Pre:  shape must be either "Circle" and "Square"
0600 {
0601   if (shape == "Circle" || shape == "Square") fMPPCShape = shape;
0602   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0603 }
0604 
0605 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0606 
0607 void WLSDetectorConstruction::SetNumberOfCladding(G4int num)
0608 // Set the number of claddings
0609 // Pre: 0 <= num <= 2
0610 {
0611   fNumOfCladLayers = num;
0612   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0613 }
0614 
0615 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0616 
0617 void WLSDetectorConstruction::SetWLSLength(G4double length)
0618 // Set the TOTAL length of the WLS fiber
0619 {
0620   fWLSfiberZ = length;
0621   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0622 }
0623 
0624 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0625 
0626 void WLSDetectorConstruction::SetWLSRadius(G4double radius)
0627 // Set the Y radius of WLS fiber
0628 {
0629   fWLSfiberRY = radius;
0630   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0631 }
0632 
0633 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0634 
0635 void WLSDetectorConstruction::SetClad1Radius(G4double radius)
0636 // Set the Y radius of Cladding 1
0637 {
0638   fClad1RY = radius;
0639   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0640 }
0641 
0642 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0643 
0644 void WLSDetectorConstruction::SetClad2Radius(G4double radius)
0645 // Set the Y radius of Cladding 2
0646 {
0647   fClad2RY = radius;
0648   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0649 }
0650 
0651 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0652 
0653 void WLSDetectorConstruction::SetPhotonDetHalfLength(G4double halfL)
0654 // Set the half length of the PhotonDet detector
0655 // The half length will be the radius if PhotonDet is circular
0656 {
0657   fMPPCHalfL = halfL;
0658   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0659 }
0660 
0661 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0662 
0663 void WLSDetectorConstruction::SetGap(G4double gap)
0664 // Set the distance between fiber end and PhotonDet
0665 {
0666   fMPPCDist = gap;
0667   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0668 }
0669 
0670 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0671 
0672 void WLSDetectorConstruction::SetPhotonDetAlignment(G4double theta)
0673 // Set the Aligment of PhotonDet with respect to the z axis
0674 // If theta is 0 deg, then the detector is perfectly aligned
0675 // PhotonDet will be deviated by theta from z axis
0676 // facing towards the center of the fiber
0677 {
0678   fMPPCTheta = theta;
0679   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0680 }
0681 
0682 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0683 
0684 void WLSDetectorConstruction::SetSurfaceRoughness(G4double roughness)
0685 // Set the Surface Roughness between Cladding 1 and WLS fiber
0686 // Pre: 0 < roughness <= 1
0687 {
0688   fSurfaceRoughness = roughness;
0689   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0690 }
0691 
0692 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0693 
0694 void WLSDetectorConstruction::SetMirrorPolish(G4double polish)
0695 // Set the Polish of the mirror, polish of 1 is a perfect mirror surface
0696 // Pre: 0 < polish <= 1
0697 {
0698   fMirrorPolish = polish;
0699   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0700 }
0701 
0702 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0703 
0704 void WLSDetectorConstruction::SetMirrorReflectivity(G4double reflectivity)
0705 // Set the Reflectivity of the mirror, reflectivity of 1 is a perfect mirror
0706 // Pre: 0 < reflectivity <= 1
0707 {
0708   fMirrorReflectivity = reflectivity;
0709   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0710 }
0711 
0712 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0713 
0714 void WLSDetectorConstruction::SetPhotonDetPolish(G4double polish)
0715 // Set the Polish of the PhotonDet, polish of 1 is a perfect mirror surface
0716 // Pre: 0 < polish <= 1
0717 {
0718   fMPPCPolish = polish;
0719   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0720 }
0721 
0722 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0723 
0724 void WLSDetectorConstruction::SetPhotonDetReflectivity(G4double reflectivity)
0725 // Set the Reflectivity of the PhotonDet, reflectivity of 1 is a perfect mirror
0726 // Pre: 0 < reflectivity <= 1
0727 {
0728   fMPPCReflectivity = reflectivity;
0729   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0730 }
0731 
0732 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0733 
0734 void WLSDetectorConstruction::SetMirror(G4bool flag)
0735 // Toggle to place the mirror or not at one end (-z end) of the fiber
0736 // True means place the mirror, false means otherwise
0737 {
0738   fMirrorToggle = flag;
0739   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0740 }
0741 
0742 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0743 
0744 void WLSDetectorConstruction::SetXYRatio(G4double r)
0745 // Set the ratio of the x and y radius of the ellipse (x/y)
0746 // a ratio of 1 would produce a circle
0747 {
0748   fXYRatio = r;
0749   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0750 }
0751 
0752 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0753 
0754 void WLSDetectorConstruction::SetBarLength(G4double length)
0755 // Set the length of the scintillator bar
0756 {
0757   fBarLength = length;
0758   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0759 }
0760 
0761 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0762 
0763 void WLSDetectorConstruction::SetBarBase(G4double side)
0764 // Set the side of the scintillator bar
0765 {
0766   fBarBase = side;
0767   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0768 }
0769 
0770 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0771 
0772 void WLSDetectorConstruction::SetHoleRadius(G4double radius)
0773 // Set the radius of the fiber hole
0774 {
0775   fHoleRadius = radius;
0776   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0777 }
0778 
0779 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0780 
0781 void WLSDetectorConstruction::SetCoatingThickness(G4double thick)
0782 // Set thickness of the coating on the bars
0783 {
0784   fCoatingThickness = thick;
0785   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0786 }
0787 
0788 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0789 
0790 void WLSDetectorConstruction::SetCoatingRadius(G4double radius)
0791 // Set inner radius of the corner bar coating
0792 {
0793   fCoatingRadius = radius;
0794   G4RunManager::GetRunManager()->GeometryHasBeenModified();
0795 }
0796 
0797 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0798 
0799 G4double WLSDetectorConstruction::GetWLSFiberLength()
0800 {
0801   return fWLSfiberZ;
0802 }
0803 
0804 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0805 
0806 G4double WLSDetectorConstruction::GetBarLength()
0807 {
0808   return fBarLength;
0809 }
0810 
0811 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0812 
0813 G4double WLSDetectorConstruction::GetBarBase()
0814 {
0815   return fBarBase;
0816 }
0817 
0818 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0819 
0820 G4double WLSDetectorConstruction::GetHoleRadius()
0821 {
0822   return fHoleRadius;
0823 }
0824 
0825 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0826 
0827 G4double WLSDetectorConstruction::GetHoleLength()
0828 {
0829   return fHoleLength;
0830 }
0831 
0832 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0833 
0834 G4double WLSDetectorConstruction::GetFiberRadius()
0835 {
0836   return GetWLSFiberRMax();
0837 }
0838 
0839 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0840 
0841 G4double WLSDetectorConstruction::GetCoatingThickness()
0842 {
0843   return fCoatingThickness;
0844 }
0845 
0846 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0847 
0848 G4double WLSDetectorConstruction::GetCoatingRadius()
0849 {
0850   return fCoatingRadius;
0851 }
0852 
0853 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0854 
0855 G4double WLSDetectorConstruction::GetWLSFiberEnd()
0856 {
0857   return fWLSfiberOrigin + fWLSfiberZ;
0858 }
0859 
0860 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0861 
0862 G4double WLSDetectorConstruction::GetWLSFiberRMax()
0863 {
0864   if (fNumOfCladLayers == 2) return fClad2RY;
0865   if (fNumOfCladLayers == 1) return fClad1RY;
0866   return fWLSfiberRY;
0867 }
0868 
0869 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0870 
0871 G4double WLSDetectorConstruction::GetSurfaceRoughness()
0872 {
0873   return fSurfaceRoughness;
0874 }
0875 
0876 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0877 
0878 // Return True if the fiber construction is ideal
0879 G4bool WLSDetectorConstruction::IsPerfectFiber()
0880 {
0881   return fSurfaceRoughness == 1. && fXYRatio == 1.
0882          && (!fMirrorToggle || (fMirrorPolish == 1. && fMirrorReflectivity == 1.));
0883 }
0884 
0885 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0886 
0887 G4Material* WLSDetectorConstruction::FindMaterial(G4String name)
0888 {
0889   G4Material* material = G4Material::GetMaterial(name, true);
0890   return material;
0891 }