Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-05 07:50:47

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 ExP01DetectorConstruction.cc
0027 /// \brief Implementation of the ExP01DetectorConstruction class
0028 
0029 #include "ExP01DetectorConstruction.hh"
0030 
0031 #include "ExP01ChamberParameterisation.hh"
0032 #include "ExP01DetectorMessenger.hh"
0033 #include "ExP01MagneticField.hh"
0034 #include "ExP01TrackerSD.hh"
0035 
0036 #include "G4Box.hh"
0037 #include "G4Colour.hh"
0038 #include "G4LogicalVolume.hh"
0039 #include "G4Material.hh"
0040 #include "G4PVParameterised.hh"
0041 #include "G4PVPlacement.hh"
0042 #include "G4SDManager.hh"
0043 #include "G4SystemOfUnits.hh"
0044 #include "G4UserLimits.hh"
0045 #include "G4VisAttributes.hh"
0046 #include "G4ios.hh"
0047 
0048 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0049 
0050 ExP01DetectorConstruction::ExP01DetectorConstruction()
0051   : G4VUserDetectorConstruction(),
0052     fSolidWorld(0),
0053     fLogicWorld(0),
0054     fPhysiWorld(0),
0055     fSolidTarget(0),
0056     fLogicTarget(0),
0057     fPhysiTarget(0),
0058     fSolidTracker(0),
0059     fLogicTracker(0),
0060     fPhysiTracker(0),
0061     fSolidChamber(0),
0062     fLogicChamber(0),
0063     fPhysiChamber(0),
0064     fTargetMater(0),
0065     fChamberMater(0),
0066     fPMagField(0),
0067     fDetectorMessenger(0),
0068     fWorldLength(0.),
0069     fTargetLength(0.),
0070     fTrackerLength(0.),
0071     fNbOfChambers(0),
0072     fChamberWidth(0.),
0073     fChamberSpacing(0.)
0074 {
0075   fPMagField = new ExP01MagneticField();
0076   fDetectorMessenger = new ExP01DetectorMessenger(this);
0077 }
0078 
0079 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0080 
0081 ExP01DetectorConstruction::~ExP01DetectorConstruction()
0082 {
0083   delete fPMagField;
0084   delete fDetectorMessenger;
0085 }
0086 
0087 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0088 
0089 G4VPhysicalVolume* ExP01DetectorConstruction::Construct()
0090 {
0091   //--------- Material definition ---------
0092 
0093   G4double a, z;
0094   G4double density, temperature, pressure;
0095   G4int nel;
0096 
0097   // Air
0098   G4Element* N = new G4Element("Nitrogen", "N", z = 7., a = 14.01 * g / mole);
0099   G4Element* O = new G4Element("Oxygen", "O", z = 8., a = 16.00 * g / mole);
0100 
0101   G4Material* Air = new G4Material("Air", density = 1.29 * mg / cm3, nel = 2);
0102   Air->AddElement(N, 70 * perCent);
0103   Air->AddElement(O, 30 * perCent);
0104 
0105   // Lead
0106   G4Material* Pb =
0107     new G4Material("Lead", z = 82., a = 207.19 * g / mole, density = 11.35 * g / cm3);
0108 
0109   // Xenon gas
0110   G4Material* Xenon =
0111     new G4Material("XenonGas", z = 54., a = 131.29 * g / mole, density = 5.458 * mg / cm3,
0112                    kStateGas, temperature = 293.15 * kelvin, pressure = 1 * atmosphere);
0113 
0114   // Print all the materials defined.
0115   //
0116   G4cout << G4endl << "The materials defined are : " << G4endl << G4endl;
0117   G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0118 
0119   //--------- Sizes of the principal geometrical components (solids)  ---------
0120 
0121   fNbOfChambers = 5;
0122   fChamberWidth = 20 * cm;
0123   fChamberSpacing = 80 * cm;
0124 
0125   fTrackerLength = (fNbOfChambers + 1) * fChamberSpacing;  // Full length of Tracker
0126   fTargetLength = 5.0 * cm;  // Full length of Target
0127 
0128   fTargetMater = Pb;
0129   fChamberMater = Xenon;
0130 
0131   fWorldLength = 1.2 * (fTargetLength + fTrackerLength);
0132 
0133   G4double targetSize = 0.5 * fTargetLength;  // Half length of the Target
0134   G4double trackerSize = 0.5 * fTrackerLength;  // Half length of the Tracker
0135 
0136   //--------- Definitions of Solids, Logical Volumes, Physical Volumes ---------
0137 
0138   //------------------------------
0139   // World
0140   //------------------------------
0141 
0142   G4double HalfWorldLength = 0.5 * fWorldLength;
0143 
0144   fSolidWorld = new G4Box("world", HalfWorldLength, HalfWorldLength, HalfWorldLength);
0145   fLogicWorld = new G4LogicalVolume(fSolidWorld, Air, "World", 0, 0, 0);
0146 
0147   //  Must place the World Physical volume unrotated at (0,0,0).
0148   //
0149   fPhysiWorld = new G4PVPlacement(0,  // no rotation
0150                                   G4ThreeVector(),  // at (0,0,0)
0151                                   fLogicWorld,  // its logical volume
0152                                   "World",  // its name
0153                                   0,  // its mother  volume
0154                                   false,  // no boolean operations
0155                                   0);  // copy number
0156 
0157   //------------------------------
0158   // Target
0159   //------------------------------
0160 
0161   G4ThreeVector positionTarget = G4ThreeVector(0, 0, -(targetSize + trackerSize));
0162 
0163   fSolidTarget = new G4Box("target", targetSize, targetSize, targetSize);
0164   fLogicTarget = new G4LogicalVolume(fSolidTarget, fTargetMater, "Target", 0, 0, 0);
0165   fPhysiTarget = new G4PVPlacement(0,  // no rotation
0166                                    positionTarget,  // at (x,y,z)
0167                                    fLogicTarget,  // its logical volume
0168                                    "Target",  // its name
0169                                    fLogicWorld,  // its mother  volume
0170                                    false,  // no boolean operations
0171                                    0);  // copy number
0172 
0173   G4cout << "Target is " << fTargetLength / cm << " cm of " << fTargetMater->GetName() << G4endl;
0174 
0175   //------------------------------
0176   // Tracker
0177   //------------------------------
0178 
0179   G4ThreeVector positionTracker = G4ThreeVector(0, 0, 0);
0180 
0181   fSolidTracker = new G4Box("tracker", trackerSize, trackerSize, trackerSize);
0182   fLogicTracker = new G4LogicalVolume(fSolidTracker, Air, "Tracker", 0, 0, 0);
0183   fPhysiTracker = new G4PVPlacement(0,  // no rotation
0184                                     positionTracker,  // at (x,y,z)
0185                                     fLogicTracker,  // its logical volume
0186                                     "Tracker",  // its name
0187                                     fLogicWorld,  // its mother  volume
0188                                     false,  // no boolean operations
0189                                     0);  // copy number
0190 
0191   //------------------------------
0192   // Tracker segments
0193   //------------------------------
0194   //
0195   // An example of Parameterised volumes
0196   // dummy values for G4Box -- modified by parameterised volume
0197 
0198   fSolidChamber = new G4Box("chamber", 100 * cm, 100 * cm, 10 * cm);
0199   fLogicChamber = new G4LogicalVolume(fSolidChamber, fChamberMater, "Chamber", 0, 0, 0);
0200 
0201   G4double firstPosition = -trackerSize + 0.5 * fChamberWidth;
0202   G4double firstLength = fTrackerLength / 10;
0203   G4double lastLength = fTrackerLength;
0204 
0205   G4VPVParameterisation* chamberParam =
0206     new ExP01ChamberParameterisation(fNbOfChambers,  // NoChambers
0207                                      firstPosition,  // Z of center of first
0208                                      fChamberSpacing,  // Z spacing of centers
0209                                      fChamberWidth,  // Width Chamber
0210                                      firstLength,  // lengthInitial
0211                                      lastLength);  // lengthFinal
0212 
0213   // dummy value : kZAxis -- modified by parameterised volume
0214   //
0215   fPhysiChamber = new G4PVParameterised("Chamber",  // their name
0216                                         fLogicChamber,  // their logical volume
0217                                         fLogicTracker,  // Mother logical volume
0218                                         kZAxis,  // Are placed along this axis
0219                                         fNbOfChambers,  // Number of chambers
0220                                         chamberParam);  // The parametrisation
0221 
0222   G4cout << "There are " << fNbOfChambers << " chambers in the tracker region. "
0223          << "The chambers are " << fChamberWidth / mm << " mm of " << fChamberMater->GetName()
0224          << "\n The distance between chamber is " << fChamberSpacing / cm << " cm" << G4endl;
0225 
0226   //------------------------------------------------
0227   // Sensitive detectors
0228   //------------------------------------------------
0229 
0230   G4SDManager* SDman = G4SDManager::GetSDMpointer();
0231 
0232   G4String trackerChamberSDname = "ExP01/TrackerChamberSD";
0233   ExP01TrackerSD* aTrackerSD = new ExP01TrackerSD(trackerChamberSDname);
0234   SDman->AddNewDetector(aTrackerSD);
0235   fLogicChamber->SetSensitiveDetector(aTrackerSD);
0236 
0237   //--------- Visualization attributes -------------------------------
0238 
0239   G4VisAttributes* BoxVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
0240   fLogicWorld->SetVisAttributes(BoxVisAtt);
0241   fLogicTarget->SetVisAttributes(BoxVisAtt);
0242   fLogicTracker->SetVisAttributes(BoxVisAtt);
0243 
0244   G4VisAttributes* ChamberVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 0.0));
0245   fLogicChamber->SetVisAttributes(ChamberVisAtt);
0246 
0247   //--------- example of User Limits -------------------------------
0248 
0249   // below is an example of how to set tracking constraints in a given
0250   // logical volume(see also in N02PhysicsList how to setup the processes
0251   // G4StepLimiter or G4UserSpecialCuts).
0252 
0253   // Sets a max Step length in the tracker region, with G4StepLimiter
0254   //
0255   G4double maxStep = 0.5 * fChamberWidth;
0256   fLogicTracker->SetUserLimits(new G4UserLimits(maxStep));
0257 
0258   // Set additional contraints on the track, with G4UserSpecialCuts
0259   //
0260   // G4double maxLength = 2*fTrackerLength, maxTime = 0.1*ns, minEkin = 10*MeV;
0261   // logicTracker->SetUserLimits(new G4UserLimits(maxStep,maxLength,maxTime,
0262   //                                               minEkin));
0263 
0264   return fPhysiWorld;
0265 }
0266 
0267 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0268 
0269 void ExP01DetectorConstruction::SetTargetMaterial(G4String materialName)
0270 {
0271   // search the material by its name
0272   G4Material* pttoMaterial = G4Material::GetMaterial(materialName);
0273   if (pttoMaterial) {
0274     fTargetMater = pttoMaterial;
0275     fLogicTarget->SetMaterial(pttoMaterial);
0276     G4cout << "\n----> The target is " << fTargetLength / cm << " cm of " << materialName << G4endl;
0277   }
0278 }
0279 
0280 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0281 
0282 void ExP01DetectorConstruction::SetChamberMaterial(G4String materialName)
0283 {
0284   // search the material by its name
0285   G4Material* pttoMaterial = G4Material::GetMaterial(materialName);
0286   if (pttoMaterial) {
0287     fChamberMater = pttoMaterial;
0288     fLogicChamber->SetMaterial(pttoMaterial);
0289     G4cout << "\n----> The chambers are " << fChamberWidth / cm << " cm of " << materialName
0290            << G4endl;
0291   }
0292 }
0293 
0294 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0295 
0296 void ExP01DetectorConstruction::SetMagField(G4double fieldValue)
0297 {
0298   fPMagField->SetFieldValue(fieldValue);
0299 }
0300 
0301 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......