Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:22:24

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