Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:16:09

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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0028 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0029 
0030 #include "DetectorConstruction.hh"
0031 
0032 #include "G4SystemOfUnits.hh"
0033 #include "G4PhysicalConstants.hh"
0034 #include "G4Material.hh"
0035 #include "G4Tubs.hh"
0036 #include "G4Box.hh"
0037 #include "G4LogicalVolume.hh"
0038 #include "G4PVPlacement.hh"
0039 #include "G4PVReplica.hh"
0040 #include "G4Transform3D.hh"
0041 #include "G4RotationMatrix.hh"
0042 
0043 #include "G4GeometryManager.hh"
0044 #include "G4PhysicalVolumeStore.hh"
0045 #include "G4LogicalVolumeStore.hh"
0046 #include "G4SolidStore.hh"
0047 
0048 #include "G4VisAttributes.hh"
0049 
0050 
0051 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0052 
0053 DetectorConstruction::DetectorConstruction()
0054 :fiberMat(0),lvol_fiber(0), absorberMat(0),lvol_layer(0),
0055  moduleMat(0),lvol_module(0), calorimeterMat(0),lvol_calorimeter(0),
0056  worldMat(0),pvol_world(0), defaultMat(0)
0057 {
0058   // materials
0059   DefineMaterials();
0060   
0061   // default parameter values of calorimeter
0062   //
0063   fiberDiameter       = 1.13*mm;    //1.08*mm
0064   nbOfFibers          = 490;        //490
0065   distanceInterFibers = 1.35*mm;    //1.35*mm
0066   layerThickness      = 1.73*mm;    //1.68*mm  
0067   milledLayer         = 1.00*mm;    //1.40*mm ?
0068   nbOfLayers          = 10;         //10
0069   nbOfModules         = 9;          //9
0070      
0071   fiberLength         = (nbOfFibers+0.5)*distanceInterFibers;   //662.175*mm
0072 }
0073 
0074 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0075 
0076 DetectorConstruction::~DetectorConstruction()
0077 { }
0078 
0079 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0080 
0081 G4VPhysicalVolume* DetectorConstruction::Construct()
0082 {
0083   return ConstructCalorimeter();
0084 }
0085 
0086 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0087 
0088 void DetectorConstruction::DefineMaterials()
0089 {
0090   // define Elements
0091   //
0092   G4Element* H  = new G4Element("Hydrogen","H", 1,  1.01*g/mole);
0093   G4Element* C  = new G4Element("Carbon",  "C", 6, 12.01*g/mole);
0094   G4Element* N  = new G4Element("Nitrogen","N", 7, 14.01*g/mole);
0095   G4Element* O  = new G4Element("Oxygen",  "O", 8, 16.00*g/mole);
0096 
0097   G4int natoms, ncomponents;
0098   G4double density, massfraction;                    
0099 
0100   // Lead
0101   //
0102   G4Material* Pb =   
0103   new G4Material("Lead", 82., 207.20*g/mole, density= 0.98*11.20*g/cm3);
0104 
0105   // Scintillator
0106   //
0107   G4Material* Sci = 
0108   new G4Material("Scintillator", density= 1.032*g/cm3, ncomponents=2);
0109   Sci->AddElement(C, natoms=8);
0110   Sci->AddElement(H, natoms=8);
0111   
0112   Sci->GetIonisation()->SetBirksConstant(0.126*mm/MeV);
0113 
0114   // Air
0115   //
0116   G4Material* Air = 
0117   new G4Material("Air", density= 1.290*mg/cm3, ncomponents=2);
0118   Air->AddElement(N, massfraction=70*perCent);
0119   Air->AddElement(O, massfraction=30.*perCent);
0120 
0121   // example of vacuum
0122   //
0123   density     = universe_mean_density;    //from PhysicalConstants.h
0124   G4double pressure    = 3.e-18*pascal;
0125   G4double temperature = 2.73*kelvin;
0126   G4Material* Vacuum =   
0127   new G4Material("Galactic", 1., 1.008*g/mole, density,
0128                              kStateGas,temperature,pressure);
0129 
0130   //attribute materials
0131   //
0132   defaultMat     = Vacuum;  
0133   fiberMat       = Sci;
0134   absorberMat    = Pb;
0135   moduleMat      = defaultMat;
0136   calorimeterMat = defaultMat;
0137   worldMat       = defaultMat;
0138 
0139   // print table
0140   //      
0141   G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0142 }
0143 
0144 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0145 
0146 G4VPhysicalVolume* DetectorConstruction::ConstructCalorimeter()
0147 {
0148   // Cleanup old geometry
0149   //
0150   G4GeometryManager::GetInstance()->OpenGeometry();
0151   G4PhysicalVolumeStore::GetInstance()->Clean();
0152   G4LogicalVolumeStore::GetInstance()->Clean();
0153   G4SolidStore::GetInstance()->Clean();
0154   
0155   // fibers
0156   //
0157   G4Tubs*
0158   svol_fiber = new G4Tubs("fiber",          //name
0159                          0*mm, 0.5*fiberDiameter,   //r1, r2
0160              0.5*fiberLength,       //half-length 
0161              0., twopi);            //theta1, theta2
0162              
0163   lvol_fiber = new G4LogicalVolume(svol_fiber,      //solid
0164                                    fiberMat,        //material
0165                                    "fiber");        //name
0166                    
0167   // layer
0168   //
0169   G4double sizeX = layerThickness;
0170   G4double sizeY = distanceInterFibers*nbOfFibers;
0171   G4double sizeZ = fiberLength;
0172   
0173   G4Box*      
0174   svol_layer = new G4Box("layer",           //name
0175                   0.5*sizeX, 0.5*sizeY, 0.5*sizeZ); //size
0176 
0177 
0178   lvol_layer = new G4LogicalVolume(svol_layer,      //solid
0179                                    absorberMat,     //material
0180                                    "layer");        //name
0181 
0182   // put fibers within layer
0183   //
0184   G4double Xcenter = 0.;
0185   G4double Ycenter = -0.5*(sizeY + distanceInterFibers);
0186   
0187   for (G4int k=0; k<nbOfFibers; k++) {
0188     Ycenter += distanceInterFibers;
0189     new G4PVPlacement(0,                //no rotation
0190               G4ThreeVector(Xcenter,Ycenter,0.),    //position
0191                       lvol_fiber,               //logical volume    
0192                       "fiber",              //name
0193                       lvol_layer,               //mother
0194                       false,                    //no boulean operat
0195                       k+1);                     //copy number
0196 
0197   }
0198                    
0199   // modules
0200   //
0201   moduleThickness = layerThickness*nbOfLayers + milledLayer;       
0202   sizeX = moduleThickness;
0203   sizeY = fiberLength;
0204   sizeZ = fiberLength;
0205   
0206   G4Box*      
0207   svol_module = new G4Box("module",         //name
0208                   0.5*sizeX, 0.5*sizeY, 0.5*sizeZ); //size
0209 
0210   lvol_module = new G4LogicalVolume(svol_module,    //solid
0211                                    absorberMat,     //material
0212                                    "module");       //name
0213 
0214   // put layers within module
0215   //
0216   Xcenter = -0.5*(nbOfLayers+1)*layerThickness;
0217   Ycenter =  0.25*distanceInterFibers;
0218   
0219   for (G4int k=0; k<nbOfLayers; k++) {
0220     Xcenter += layerThickness;
0221     Ycenter  = - Ycenter;
0222     new G4PVPlacement(0,                //no rotation
0223               G4ThreeVector(Xcenter,Ycenter,0.),    //position
0224                       lvol_layer,               //logical volume    
0225                       "layer",              //name
0226                       lvol_module,              //mother
0227                       false,                    //no boulean operat
0228                       k+1);                     //copy number
0229 
0230   }                                
0231 
0232   // calorimeter
0233   //
0234   calorThickness = moduleThickness*nbOfModules;
0235   sizeX = calorThickness;
0236   sizeY = fiberLength;
0237   sizeZ = fiberLength;
0238   
0239   G4Box*      
0240   svol_calorimeter = new G4Box("calorimeter",       //name
0241                   0.5*sizeX, 0.5*sizeY, 0.5*sizeZ); //size
0242 
0243 
0244   lvol_calorimeter = new G4LogicalVolume(svol_calorimeter,  //solid
0245                                    calorimeterMat,      //material
0246                                    "calorimeter");      //name  
0247 
0248   // put modules inside calorimeter
0249   //  
0250   Xcenter = -0.5*(calorThickness + moduleThickness);
0251   
0252 
0253   for (G4int k=0; k<nbOfModules; k++) {
0254     Xcenter += moduleThickness;       
0255     G4RotationMatrix rotm;                    //rotation matrix to place modules    
0256     if ((k+1)%2 == 0) rotm.rotateX(90*deg);
0257     G4Transform3D transform(rotm, G4ThreeVector(Xcenter,0.,0.));    
0258     new G4PVPlacement(transform,                //rotation+position
0259                       lvol_module,              //logical volume    
0260                       "module",                 //name
0261                       lvol_calorimeter,         //mother
0262                       false,                    //no boulean operat
0263                       k+1);                     //copy number
0264   }
0265 
0266   // world
0267   //
0268   sizeX = 1.2*calorThickness;
0269   sizeY = 1.2*fiberLength;
0270   sizeZ = 1.2*fiberLength;
0271   
0272   worldSizeX = sizeX;
0273   
0274   G4Box*      
0275   svol_world = new G4Box("world",           //name
0276                   0.5*sizeX, 0.5*sizeY, 0.5*sizeZ); //size
0277 
0278   lvol_world = new G4LogicalVolume(svol_world,      //solid
0279                                    worldMat,        //material
0280                                    "world");        //name 
0281                     
0282   pvol_world = new G4PVPlacement(0,         //no rotation
0283                  G4ThreeVector(),   //at (0,0,0)
0284                                  lvol_world,        //logical volume
0285                                  "world",       //name
0286                                  0,         //mother  volume
0287                                  false,         //no boolean operation
0288                                  0);            //copy number
0289 
0290   //put calorimeter in world
0291   //  
0292   new G4PVPlacement(0,              //no rotation
0293                     G4ThreeVector(),        //at (0,0,0)
0294                     lvol_calorimeter,       //logical volume
0295                     "calorimeter",      //name
0296                     lvol_world,         //mother  volume
0297                     false,          //no boolean operation
0298                     0);             //copy number
0299                              
0300   PrintCalorParameters();
0301   
0302   // Visualization attributes
0303   //
0304   lvol_fiber->SetVisAttributes (G4VisAttributes::GetInvisible());  
0305   lvol_layer->SetVisAttributes (G4VisAttributes::GetInvisible());
0306   lvol_world->SetVisAttributes (G4VisAttributes::GetInvisible());
0307     
0308   //always return the physical World
0309   //
0310   return pvol_world;
0311 }
0312 
0313 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0314 
0315 #include "G4UnitsTable.hh"
0316 
0317 void DetectorConstruction::PrintCalorParameters()
0318 {
0319   G4cout << "\n-------------------------------------------------------------"
0320      << "\n ---> The calorimeter is " << nbOfModules << " Modules"
0321      << "\n ---> A Module is " << nbOfLayers << " Layers + 1 milled Layer";
0322      
0323   G4cout  
0324      << "\n ---> A Layer is " << G4BestUnit(layerThickness,"Length")  
0325      << " thickness of " << absorberMat->GetName();    
0326      
0327   G4cout 
0328      << "\n ---> A Layer includes " << nbOfFibers << " fibers of " 
0329      << fiberMat->GetName();
0330      
0331   G4cout 
0332      << "\n      ---> diameter : " << G4BestUnit(fiberDiameter,"Length")
0333      << "\n      ---> length   : " << G4BestUnit(fiberLength,"Length")
0334      << "\n      ---> distance : " << G4BestUnit(distanceInterFibers,"Length");
0335      
0336   G4cout  
0337      << "\n ---> The milled Layer is " << G4BestUnit(milledLayer,"Length")  
0338      << " thickness of " << absorberMat->GetName();
0339      
0340   G4cout 
0341    << "\n\n ---> Module thickness " << G4BestUnit(moduleThickness,"Length");
0342   
0343   G4cout 
0344    << "\n\n ---> Total calor thickness " << G4BestUnit(calorThickness,"Length")
0345    <<   "\n      Tranverse size        " << G4BestUnit(fiberLength,"Length");
0346 
0347   G4cout << "\n-------------------------------------------------------------\n";
0348   G4cout << G4endl;
0349 }
0350 
0351 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0352 
0353 #include "G4GlobalMagFieldMessenger.hh"
0354 #include "G4AutoDelete.hh"
0355 
0356 void DetectorConstruction::ConstructSDandField()
0357 {
0358     if ( fFieldMessenger.Get() == 0 ) {
0359         // Create global magnetic field messenger.
0360         // Uniform magnetic field is then created automatically if
0361         // the field value is not zero.
0362         G4ThreeVector fieldValue = G4ThreeVector();
0363         G4GlobalMagFieldMessenger* msg =
0364         new G4GlobalMagFieldMessenger(fieldValue);
0365         //msg->SetVerboseLevel(1);
0366         G4AutoDelete::Register(msg);
0367         fFieldMessenger.Put( msg );
0368         
0369     }
0370 }
0371 
0372 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......