Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:21:05

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