Back to home page

EIC code displayed by LXR

 
 

    


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

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 #include "Par03DetectorConstruction.hh"
0027 
0028 #include "Par03DetectorMessenger.hh"
0029 #include "Par03EMShowerModel.hh"
0030 #include "Par03SensitiveDetector.hh"
0031 
0032 #include "G4Box.hh"
0033 #include "G4LogicalVolume.hh"
0034 #include "G4Material.hh"
0035 #include "G4NistManager.hh"
0036 #include "G4PVPlacement.hh"
0037 #include "G4PVReplica.hh"
0038 #include "G4Region.hh"
0039 #include "G4RegionStore.hh"
0040 #include "G4RunManager.hh"
0041 #include "G4SDManager.hh"
0042 #include "G4Tubs.hh"
0043 #include "G4UnitsTable.hh"
0044 #include "G4VisAttributes.hh"
0045 
0046 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0047 
0048 Par03DetectorConstruction::Par03DetectorConstruction() : G4VUserDetectorConstruction()
0049 {
0050   fDetectorMessenger = new Par03DetectorMessenger(this);
0051 
0052   G4NistManager* nistManager = G4NistManager::Instance();
0053   fDetectorMaterial = nistManager->FindOrBuildMaterial("G4_Fe");
0054 }
0055 
0056 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0057 
0058 Par03DetectorConstruction::~Par03DetectorConstruction() = default;
0059 
0060 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0061 
0062 G4VPhysicalVolume* Par03DetectorConstruction::Construct()
0063 {
0064   //--------- Material definition ---------
0065   G4NistManager* nistManager = G4NistManager::Instance();
0066   G4Material* air = nistManager->FindOrBuildMaterial("G4_AIR");
0067 
0068   //--------- Derived dimensions ---------
0069   G4double full2Pi = 2. * CLHEP::pi * rad;
0070   G4double layerThickness = fDetectorLength / fNbOfLayers;
0071   G4double cellPhi = full2Pi / fNbOfPhiCells;
0072   G4double cellDR = fDetectorRadius / fNbOfRhoCells;
0073 
0074   //--------- World ---------
0075   auto fSolidWorld = new G4Box("World",  // name
0076                                fWorldSize / 2.,  // half-width in X
0077                                fWorldSize / 2.,  // half-width in Y
0078                                fWorldSize / 2.);  // half-width in Z
0079   auto fLogicWorld = new G4LogicalVolume(fSolidWorld,  // solid
0080                                          air,  // material
0081                                          "World");  // name
0082   auto fPhysicWorld = new G4PVPlacement(0,  // no rotation
0083                                         G4ThreeVector(),  // at (0,0,0)
0084                                         fLogicWorld,  // logical volume
0085                                         "World",  // name
0086                                         0,  // mother volume
0087                                         false,  // not used
0088                                         999,  // copy number
0089                                         true);  // copy number
0090 
0091   //--------- Detector envelope ---------
0092   auto fSolidDetector = new G4Tubs("Detector",  // name
0093                                    0,  // inner radius
0094                                    fDetectorRadius,  // outer radius
0095                                    fDetectorLength / 2.,  // half-width in Z
0096                                    0,  // start angle
0097                                    full2Pi);  // delta angle
0098   auto fLogicDetector = new G4LogicalVolume(fSolidDetector,  // solid
0099                                             fDetectorMaterial,  // material
0100                                             "Detector");  // name
0101   new G4PVPlacement(0,  // no rotation
0102                     G4ThreeVector(0, 0,
0103                                   fDetectorLength / 2),  // detector face starts at (0,0,0)
0104                     fLogicDetector,  // logical volume
0105                     "Detector",  // name
0106                     fLogicWorld,  // mother volume
0107                     false,  // not used
0108                     99,  // copy number
0109                     true);  // check overlaps
0110 
0111   // Region for fast simulation
0112   auto detectorRegion = new G4Region("DetectorRegion");
0113   detectorRegion->AddRootLogicalVolume(fLogicDetector);
0114 
0115   //--------- Readout geometry ---------
0116   // Layers (along z)
0117   auto fSolidLayer = new G4Tubs("Layer",  // name
0118                                 0,  // inner radius
0119                                 fDetectorRadius,  // outer radius
0120                                 layerThickness / 2.,  // half-width in Z
0121                                 0,  // start angle
0122                                 full2Pi);  // delta angle
0123   auto fLogicLayer = new G4LogicalVolume(fSolidLayer,  // solid
0124                                          air,  // material
0125                                          "Layer");  // name
0126   if (fNbOfLayers > 1)
0127     new G4PVReplica("Layer",  // name
0128                     fLogicLayer,  // logical volume
0129                     fLogicDetector,  // mother volume
0130                     kZAxis,  // axis of replication
0131                     fNbOfLayers,  // number of replicas
0132                     layerThickness);  // width of single replica
0133   else
0134     new G4PVPlacement(0,  // no rotation
0135                       G4ThreeVector(),  // place at centre of mother volume
0136                       fLogicLayer,  // logical volume
0137                       "Layer",  // name
0138                       fLogicDetector,  // mother volume
0139                       false,  // not used
0140                       0,  // copy number
0141                       true);  // check overlaps
0142 
0143   // Layer segment (division in phi)
0144   auto fSolidRow = new G4Tubs("Row",  // name
0145                               0,  // inner radius
0146                               fDetectorRadius,  // outer radius
0147                               layerThickness / 2.,  // half-width in Z
0148                               0,  // start angle
0149                               cellPhi);  // delta angle
0150 
0151   auto fLogicRow = new G4LogicalVolume(fSolidRow,  // solid
0152                                        air,  // material
0153                                        "Segment");  // name
0154   if (fNbOfPhiCells > 1)
0155     new G4PVReplica("Segment",  // name
0156                     fLogicRow,  // logical volume
0157                     fLogicLayer,  // mother volume
0158                     kPhi,  // axis of replication
0159                     fNbOfPhiCells,  // number of replicas
0160                     cellPhi);  // width of single replica
0161   else
0162     new G4PVPlacement(0,  // no rotation
0163                       G4ThreeVector(),  // place at centre of mother volume
0164                       fLogicRow,  // logical volume
0165                       "Row",  // name
0166                       fLogicLayer,  // mother volume
0167                       false,  // not used
0168                       0,  // copy number
0169                       true);  // check overlaps
0170 
0171   // Final cells (segment slices in radius)
0172   // No volume can be placed inside a radial replication
0173   auto fSolidCell = new G4Tubs("Cell",  // name
0174                                0,  // inner radius
0175                                cellDR,  // outer radius
0176                                layerThickness / 2.,  // half-width in Z
0177                                0,  // start angle
0178                                cellPhi);  // delta angle
0179 
0180   fLogicCell = new G4LogicalVolume(fSolidCell,  // solid
0181                                    fDetectorMaterial,  // material
0182                                    "Cell");  // name
0183   if (fNbOfRhoCells > 1)
0184     new G4PVReplica("Cell",  // name
0185                     fLogicCell,  // logical volume
0186                     fLogicRow,  // mother volume
0187                     kRho,  // axis of replication
0188                     fNbOfRhoCells,  // number of replicas
0189                     cellDR);  // width of single replica
0190   else
0191     new G4PVPlacement(0,  // no rotation
0192                       G4ThreeVector(),  // place at centre of mother volume
0193                       fLogicCell,  // logical volume
0194                       "Cell",  // name
0195                       fLogicRow,  // mother volume
0196                       false,  // not used
0197                       0,  // copy number
0198                       true);  // check overlaps
0199 
0200   //--------- Visualisation settings ---------
0201   fLogicWorld->SetVisAttributes(G4VisAttributes::GetInvisible());
0202   fLogicLayer->SetVisAttributes(G4VisAttributes::GetInvisible());
0203   fLogicRow->SetVisAttributes(G4VisAttributes::GetInvisible());
0204   G4VisAttributes attribs;
0205   attribs.SetColour(G4Colour(0, 0, 1, 0.3));
0206   attribs.SetForceSolid(true);
0207   fLogicCell->SetVisAttributes(attribs);
0208 
0209   Print();
0210   return fPhysicWorld;
0211 }
0212 
0213 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0214 
0215 void Par03DetectorConstruction::ConstructSDandField()
0216 {
0217   Par03SensitiveDetector* caloSD =
0218     new Par03SensitiveDetector("sensitiveDetector", fNbOfLayers, fNbOfPhiCells, fNbOfRhoCells);
0219   G4SDManager::GetSDMpointer()->AddNewDetector(caloSD);
0220   SetSensitiveDetector(fLogicCell, caloSD);
0221 
0222   auto detectorRegion = G4RegionStore::GetInstance()->GetRegion("DetectorRegion");
0223   new Par03EMShowerModel("model", detectorRegion);
0224 }
0225 
0226 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0227 
0228 void Par03DetectorConstruction::Print() const
0229 {
0230   G4cout << "\n------------------------------------------------------"
0231          << "\n--- Detector material:\t" << fDetectorMaterial->GetName()
0232          << "\n--- Detector length:\t" << G4BestUnit(fDetectorLength, "Length")
0233          << "\n--- Detector radius:\t" << G4BestUnit(fDetectorRadius, "Length")
0234          << "\n--- Number of layers:\t" << fNbOfLayers << "\n--- Number of R-cells:\t"
0235          << fNbOfRhoCells << "\n--- Number of phi-cells:\t" << fNbOfPhiCells << G4endl;
0236   G4cout << "-----------------------------------------------------" << G4endl;
0237 }
0238 
0239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0240 
0241 void Par03DetectorConstruction::SetMaterial(const G4String& aName)
0242 {
0243   // search material by its name
0244   G4Material* material = G4NistManager::Instance()->FindOrBuildMaterial(aName);
0245   if (material)
0246     fDetectorMaterial = material;
0247   else
0248     G4Exception("Par03DetectorConstruction::SetMaterial()", "InvalidSetup", FatalException,
0249                 ("Unknown material name: " + aName).c_str());
0250   G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0251 }
0252 
0253 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0254 
0255 void Par03DetectorConstruction::SetRadius(G4double aRadius)
0256 {
0257   // check if fits within world volume
0258   if (aRadius >= fWorldSize / 2.)
0259     G4Exception("Par03DetectorConstruction::SetRadius()", "InvalidSetup", FatalException,
0260                 ("Detector radius cannot be larger than the world size ("
0261                  + G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")")
0262                   .c_str());
0263   fDetectorRadius = aRadius;
0264 }
0265 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0266 
0267 void Par03DetectorConstruction::SetLength(G4double aLength)
0268 {
0269   // check if fits within world volume
0270   if (aLength >= fWorldSize / 2.)
0271     G4Exception("Par03DetectorConstruction::SetLength()", "InvalidSetup", FatalException,
0272                 ("Detector length cannot be larger than the world size ("
0273                  + G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")")
0274                   .c_str());
0275   fDetectorLength = aLength;
0276 }