Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-15 08:28:27

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 DetectorConstruction.cc
0027 /// \brief Implementation of the DetectorConstruction class
0028 
0029 /////////////////////////////////////////////////////////////////////////
0030 //
0031 // TestEm9: Crystal calorimeter
0032 //
0033 // Created: 31.01.03 V.Ivanchenko
0034 //
0035 // Modified:
0036 //
0037 ////////////////////////////////////////////////////////////////////////
0038 //
0039 
0040 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0041 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0042 
0043 #include "DetectorConstruction.hh"
0044 
0045 #include "DetectorMessenger.hh"
0046 
0047 #include "G4Box.hh"
0048 #include "G4Colour.hh"
0049 #include "G4GeometryManager.hh"
0050 #include "G4LogicalVolume.hh"
0051 #include "G4LogicalVolumeStore.hh"
0052 #include "G4NistManager.hh"
0053 #include "G4PVPlacement.hh"
0054 #include "G4PVReplica.hh"
0055 #include "G4PhysicalVolumeStore.hh"
0056 #include "G4ProductionCuts.hh"
0057 #include "G4Region.hh"
0058 #include "G4RegionStore.hh"
0059 #include "G4RunManager.hh"
0060 #include "G4SolidStore.hh"
0061 #include "G4SystemOfUnits.hh"
0062 #include "G4TransportationManager.hh"
0063 #include "G4UnitsTable.hh"
0064 #include "G4VisAttributes.hh"
0065 #include "G4ios.hh"
0066 
0067 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0068 
0069 DetectorConstruction::DetectorConstruction()
0070   : G4VUserDetectorConstruction(),
0071     fCalMaterial(0),
0072     fVertMaterial(0),
0073     fAbsMaterial(0),
0074     fWorldMaterial(0),
0075     fYorkMaterial(0),
0076     fLogicWorld(0),
0077     fLogicCal(0),
0078     fLogicA1(0),
0079     fLogicA2(0),
0080     fLogicA3(0),
0081     fLogicA4(0),
0082     fVertexRegion(0),
0083     fMuonRegion(0),
0084     fVertexDetectorCuts(0),
0085     fMuonDetectorCuts(0),
0086     fDetectorMessenger(0)
0087 {
0088   fDetectorMessenger = new DetectorMessenger(this);
0089 
0090   fEcalLength = 36. * cm;
0091   fEcalWidth = 6. * cm;
0092   fVertexLength = 3. * cm;
0093   fPadLength = 0.1 * mm;
0094   fPadWidth = 0.02 * mm;
0095   fAbsLength = 2. * mm;
0096   fWorldZ = 0.0;
0097   fLogicWorld = 0;
0098   fLogicCal = 0;
0099   fLogicA1 = 0;
0100   fLogicA2 = 0;
0101   fLogicA3 = 0;
0102   fLogicA4 = 0;
0103   fVertexRegion = 0;
0104   fMuonRegion = 0;
0105 
0106   DefineMaterials();
0107   fVertexDetectorCuts = new G4ProductionCuts();
0108   fMuonDetectorCuts = new G4ProductionCuts();
0109 }
0110 
0111 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0112 
0113 DetectorConstruction::~DetectorConstruction()
0114 {
0115   delete fDetectorMessenger;
0116   delete fVertexDetectorCuts;
0117   delete fMuonDetectorCuts;
0118 }
0119 
0120 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0121 
0122 G4VPhysicalVolume* DetectorConstruction::Construct()
0123 {
0124   return ConstructVolumes();
0125 }
0126 
0127 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0128 
0129 void DetectorConstruction::DefineMaterials()
0130 {
0131   // Default materials
0132 
0133   G4NistManager* man = G4NistManager::Instance();
0134   //  man->SetVerbose(1);
0135   fWorldMaterial = man->FindOrBuildMaterial("G4_AIR");
0136   fAbsMaterial = man->FindOrBuildMaterial("G4_Al");
0137   fVertMaterial = man->FindOrBuildMaterial("G4_Si");
0138   fYorkMaterial = man->FindOrBuildMaterial("G4_Fe");
0139   fCalMaterial = man->FindOrBuildMaterial("G4_CESIUM_IODIDE");
0140 }
0141 
0142 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0143 
0144 G4VPhysicalVolume* DetectorConstruction::ConstructVolumes()
0145 {
0146   // Cleanup old geometry
0147 
0148   G4GeometryManager::GetInstance()->OpenGeometry();
0149 
0150   if (G4NistManager::Instance()->GetVerbose() > 0)
0151     G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0152 
0153   if (fVertexRegion) {
0154     delete fVertexRegion;
0155     delete fMuonRegion;
0156   }
0157   fVertexRegion = new G4Region("VertexDetector");
0158   fVertexRegion->SetProductionCuts(fVertexDetectorCuts);
0159 
0160   fMuonRegion = new G4Region("MuonDetector");
0161   fMuonRegion->SetProductionCuts(fMuonDetectorCuts);
0162 
0163   G4SolidStore::GetInstance()->Clean();
0164   G4LogicalVolumeStore::GetInstance()->Clean();
0165   G4PhysicalVolumeStore::GetInstance()->Clean();
0166 
0167   if (fVertexLength < fPadLength * 5.0) fVertexLength = fPadLength * 5.0;
0168   G4double gap = 0.01 * mm;
0169   G4double biggap = 2. * cm;
0170   G4double york = 10. * cm;
0171 
0172   fWorldZ = 2. * fVertexLength + 3. * fAbsLength + 0.5 * (fEcalLength + york) + biggap * 2.;
0173 
0174   G4double worldX = fEcalWidth * 3.0;
0175   G4double vertexZ = -fWorldZ + fVertexLength * 2.0 + fAbsLength + biggap;
0176   G4double absZ2 = -fWorldZ + fVertexLength * 4.0 + fAbsLength * 3.5 + biggap;
0177   G4double ecalZ =
0178     -fWorldZ + fVertexLength * 4.0 + fAbsLength * 4.0 + fEcalLength * 0.5 + 2. * biggap;
0179   G4double yorkZ =
0180     -fWorldZ + fVertexLength * 4.0 + fAbsLength * 5.0 + fEcalLength + york * 0.5 + 3. * biggap;
0181 
0182   //
0183   // World
0184   //
0185   G4Box* solidW = new G4Box("World", worldX, worldX, fWorldZ);
0186   fLogicWorld = new G4LogicalVolume(solidW, fWorldMaterial, "World");
0187   G4VPhysicalVolume* world =
0188     new G4PVPlacement(0, G4ThreeVector(), "World", fLogicWorld, 0, false, 0);
0189 
0190   //
0191   // Ecal
0192   //
0193   G4Box* solidE = new G4Box("VolE", worldX, worldX, fEcalLength * 0.5 + gap);
0194   G4LogicalVolume* logicECal = new G4LogicalVolume(solidE, fWorldMaterial, "VolE");
0195   G4VPhysicalVolume* physE =
0196     new G4PVPlacement(0, G4ThreeVector(0., 0., ecalZ), "VolE", logicECal, world, false, 0);
0197 
0198   G4Box* solidC = new G4Box("Ecal", fEcalWidth * 0.5, fEcalWidth * 0.5, fEcalLength * 0.5);
0199   fLogicCal = new G4LogicalVolume(solidC, fCalMaterial, "Ecal");
0200 
0201   G4cout << "Ecal is " << G4BestUnit(fEcalLength, "Length") << " of " << fCalMaterial->GetName()
0202          << G4endl;
0203 
0204   // Crystals
0205 
0206   G4double x0 = -(fEcalWidth + gap) * 2.0;
0207   G4double y = x0;
0208   G4double x;
0209   G4int k = 0;
0210   G4int i, j;
0211 
0212   for (i = 0; i < 5; i++) {
0213     x = x0;
0214     for (j = 0; j < 5; j++) {
0215       new G4PVPlacement(0, G4ThreeVector(x, y, 0.), "Ecal", fLogicCal, physE, false, k);
0216       k++;
0217       x += fEcalWidth + gap;
0218     }
0219     y += fEcalWidth + gap;
0220   }
0221 
0222   // Absorber
0223 
0224   G4Box* solidA = new G4Box("Abso", worldX, worldX, fAbsLength * 0.5);
0225   fLogicA2 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs2");
0226   new G4PVPlacement(0, G4ThreeVector(0., 0., absZ2), "Abs2", fLogicA2, world, false, 0);
0227 
0228   G4cout << "Absorber is " << G4BestUnit(fAbsLength, "Length") << " of " << fAbsMaterial->GetName()
0229          << G4endl;
0230 
0231   // York
0232 
0233   G4Box* solidYV = new G4Box("VolY", worldX, worldX, york * 0.5 + fAbsLength);
0234   G4LogicalVolume* logicYV = new G4LogicalVolume(solidYV, fYorkMaterial, "VolY");
0235   G4VPhysicalVolume* physYV =
0236     new G4PVPlacement(0, G4ThreeVector(0., 0., yorkZ), "VolY", logicYV, world, false, 0);
0237 
0238   G4Box* solidY = new G4Box("York", worldX, worldX, york * 0.5);
0239   G4LogicalVolume* logicY = new G4LogicalVolume(solidY, fYorkMaterial, "York");
0240   new G4PVPlacement(0, G4ThreeVector(), "York", logicY, physYV, false, 0);
0241 
0242   fLogicA3 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs3");
0243   fLogicA4 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs4");
0244 
0245   new G4PVPlacement(0, G4ThreeVector(0., 0., -(york + fAbsLength) * 0.5), "Abs3", fLogicA3, physYV,
0246                     false, 0);
0247   new G4PVPlacement(0, G4ThreeVector(0., 0., (york + fAbsLength) * 0.5), "Abs4", fLogicA4, physYV,
0248                     false, 0);
0249 
0250   // Vertex volume
0251   G4Box* solidVV = new G4Box("VolV", worldX, worldX, fVertexLength * 2. + fAbsLength + gap);
0252   G4LogicalVolume* logicVV = new G4LogicalVolume(solidVV, fWorldMaterial, "VolV");
0253   G4VPhysicalVolume* physVV =
0254     new G4PVPlacement(0, G4ThreeVector(0., 0., vertexZ), "VolV", logicVV, world, false, 0);
0255 
0256   // Absorber
0257   fLogicA1 = new G4LogicalVolume(solidA, fAbsMaterial, "Abs1");
0258   new G4PVPlacement(0, G4ThreeVector(0., 0., fVertexLength * 2. - fAbsLength * 0.5), "Abs1",
0259                     fLogicA1, physVV, false, 0);
0260 
0261   // Vertex
0262   G4double vertWidth = fEcalWidth / 5.;
0263   G4int npads = (G4int)(vertWidth / fPadWidth);
0264   // G4cout << " vertWidth= " << vertWidth << " padWidth= " << padWidth
0265   //          << " npads= " << npads << G4endl;
0266   //  insure beam to hit a middle of central pad
0267   npads = (npads / 2) * 2 + 1;
0268   x0 = -0.5 * (fPadWidth + vertWidth);
0269   G4double x1 = 0.5 * vertWidth + gap;
0270   G4double z = -(fVertexLength + fAbsLength);
0271 
0272   G4Box* solidVD = new G4Box("VertDet", x1, fEcalWidth * 0.5 + gap, fPadLength * 0.5);
0273   G4LogicalVolume* logicVD = new G4LogicalVolume(solidVD, fVertMaterial, "VertDet");
0274   logicVD->SetSolid(solidVD);
0275 
0276   G4Box* solidV = new G4Box("Vert", fPadWidth * 0.5, fEcalWidth * 0.5, fPadLength * 0.5);
0277   G4LogicalVolume* logicV = new G4LogicalVolume(solidV, fVertMaterial, "Vert");
0278 
0279   for (i = 0; i < 3; i++) {
0280     new G4PVPlacement(0, G4ThreeVector(0., 0., z), "VertDet", logicVD, physVV, false, i);
0281     z += fVertexLength;
0282   }
0283   x = x0;
0284 
0285   for (j = 0; j < npads; j++) {
0286     new G4PVPlacement(0, G4ThreeVector(x, 0., 0.), logicV, "Vert", logicVD, false, k);
0287     x += fPadWidth;
0288   }
0289 
0290   G4cout << "Vertex is " << G4BestUnit(fVertexLength, "Length") << " of 3 layers of Si of "
0291          << G4BestUnit(fPadLength, "Length") << " npads= " << npads << G4endl;
0292 
0293   // Define region for the vertex detector
0294   fVertexRegion->AddRootLogicalVolume(logicVV);
0295   fVertexRegion->AddRootLogicalVolume(fLogicA3);
0296 
0297   // Define region for the muon detector
0298   fMuonRegion->AddRootLogicalVolume(logicYV);
0299 
0300   // color regions
0301   logicVV->SetVisAttributes(G4VisAttributes::GetInvisible());
0302   logicV->SetVisAttributes(G4VisAttributes::GetInvisible());
0303   logicECal->SetVisAttributes(G4VisAttributes::GetInvisible());
0304   logicYV->SetVisAttributes(G4VisAttributes::GetInvisible());
0305 
0306   G4VisAttributes* regWcolor = new G4VisAttributes(G4Colour(0.3, 0.3, 0.3));
0307   fLogicWorld->SetVisAttributes(regWcolor);
0308 
0309   G4VisAttributes* regVcolor = new G4VisAttributes(G4Colour(0., 0.3, 0.7));
0310   logicVD->SetVisAttributes(regVcolor);
0311 
0312   G4VisAttributes* regCcolor = new G4VisAttributes(G4Colour(0., 0.7, 0.3));
0313   fLogicCal->SetVisAttributes(regCcolor);
0314 
0315   G4VisAttributes* regAcolor = new G4VisAttributes(G4Colour(1., 0.5, 0.5));
0316   fLogicA1->SetVisAttributes(regAcolor);
0317   fLogicA2->SetVisAttributes(regAcolor);
0318   fLogicA3->SetVisAttributes(regAcolor);
0319   fLogicA4->SetVisAttributes(regAcolor);
0320 
0321   G4VisAttributes* regMcolor = new G4VisAttributes(G4Colour(1., 1., 0.));
0322   logicY->SetVisAttributes(regMcolor);
0323 
0324   // always return world
0325   G4cout << "### New geometry is constructed" << G4endl;
0326 
0327   return world;
0328 }
0329 
0330 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0331 
0332 void DetectorConstruction::SetEcalMaterial(const G4String& mat)
0333 {
0334   // search the material by its name
0335   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(mat);
0336   if (pttoMaterial && pttoMaterial != fCalMaterial) {
0337     fCalMaterial = pttoMaterial;
0338     if (fLogicCal) {
0339       fLogicCal->SetMaterial(fCalMaterial);
0340       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0341     }
0342   }
0343 }
0344 
0345 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0346 
0347 void DetectorConstruction::SetAbsMaterial(const G4String& mat)
0348 {
0349   // search the material by its name
0350   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(mat);
0351   if (pttoMaterial && pttoMaterial != fAbsMaterial) {
0352     fAbsMaterial = pttoMaterial;
0353     if (fLogicA1) {
0354       fLogicA1->SetMaterial(fAbsMaterial);
0355       fLogicA2->SetMaterial(fAbsMaterial);
0356       fLogicA3->SetMaterial(fAbsMaterial);
0357       fLogicA4->SetMaterial(fAbsMaterial);
0358       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0359     }
0360   }
0361 }
0362 
0363 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0364 
0365 void DetectorConstruction::UpdateGeometry()
0366 {
0367   G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0368   G4RunManager::GetRunManager()->DefineWorldVolume(ConstructVolumes());
0369 }
0370 
0371 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0372 
0373 void DetectorConstruction::SetEcalLength(G4double val)
0374 {
0375   if (val > 0.0) {
0376     fEcalLength = val;
0377     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0378   }
0379 }
0380 
0381 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0382 
0383 void DetectorConstruction::SetEcalWidth(G4double val)
0384 {
0385   if (val > 0.0) {
0386     fEcalWidth = val;
0387     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0388   }
0389 }
0390 
0391 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0392 
0393 void DetectorConstruction::SetVertexLength(G4double val)
0394 {
0395   if (val > 0.0) {
0396     fVertexLength = val;
0397     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0398   }
0399 }
0400 
0401 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0402 
0403 void DetectorConstruction::SetPadLength(G4double val)
0404 {
0405   if (val > 0.0) {
0406     fPadLength = val;
0407     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0408   }
0409 }
0410 
0411 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0412 
0413 void DetectorConstruction::SetPadWidth(G4double val)
0414 {
0415   if (val > 0.0) {
0416     fPadWidth = val;
0417     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0418   }
0419 }
0420 
0421 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0422 
0423 void DetectorConstruction::SetAbsLength(G4double val)
0424 {
0425   if (val > 0.0) {
0426     fAbsLength = val;
0427     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0428   }
0429 }
0430 
0431 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......