Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:17: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 //
0028 // Author: Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
0029 //
0030 // History:
0031 // -----------
0032 // 08 Sep 2003 Alfonso Mantero Created
0033 // -------------------------------------------------------------------
0034 
0035 #include "XrayFluoMercuryDetectorConstruction.hh"
0036 #include "XrayFluoMercuryDetectorMessenger.hh"
0037 #include "XrayFluoSD.hh"
0038 #include "XrayFluoNistMaterials.hh"
0039 #include "G4PhysicalConstants.hh"
0040 #include "G4SystemOfUnits.hh"
0041 #include "G4Material.hh"
0042 #include "G4ThreeVector.hh"
0043 #include "G4Box.hh"
0044 #include "G4Sphere.hh"
0045 #include "G4Tubs.hh"
0046 #include "G4LogicalVolume.hh"
0047 #include "G4PVPlacement.hh"
0048 #include "G4TransportationManager.hh"
0049 #include "G4SDManager.hh"
0050 #include "G4RunManager.hh"
0051 #include "G4VisAttributes.hh"
0052 #include "G4Colour.hh"
0053 #include "G4ios.hh"
0054 #include "G4PVReplica.hh"
0055 #include "G4UserLimits.hh"
0056 #include "G4GeometryManager.hh"
0057 #include "G4PhysicalVolumeStore.hh"
0058 #include "G4LogicalVolumeStore.hh"
0059 #include "G4SolidStore.hh"
0060 #include "G4SDManager.hh"
0061 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0062 
0063 
0064 XrayFluoMercuryDetectorConstruction::XrayFluoMercuryDetectorConstruction()
0065   : detectorType(0),mercuryGranularity(false), DeviceSizeX(0),
0066     DeviceSizeY(0),DeviceThickness(0),
0067     solidWorld(0),logicWorld(0),physiWorld(0),
0068     solidHPGe(0),logicHPGe(0),physiHPGe(0),
0069     solidScreen(0),logicScreen(0),physiScreen(0),
0070     solidMercury (0),logicMercury(0),physiMercury (0),
0071     solidOhmicPos(0),logicOhmicPos(0), physiOhmicPos(0),
0072     solidOhmicNeg(0),logicOhmicNeg(0), physiOhmicNeg(0),
0073     solidPixel(0),logicPixel(0), physiPixel(0),
0074     screenMaterial(0),OhmicPosMaterial(0), OhmicNegMaterial(0),
0075     pixelMaterial(0),mercuryMaterial(0),
0076     defaultMaterial(0),HPGeSD(0)
0077   
0078 { 
0079   materials = XrayFluoNistMaterials::GetInstance();
0080 
0081   DefineDefaultMaterials();
0082 
0083   NbOfPixelRows     =  1; // should be 1
0084   NbOfPixelColumns  =  1; // should be 1
0085   NbOfPixels        =  NbOfPixelRows*NbOfPixelColumns;
0086   PixelSizeXY       = std::sqrt(40.) * mm *0.5e6; // should be std::sqrt(40) * mm
0087   PixelThickness = 3.5 * mm * 1e6; //should be 3.5 mm
0088   
0089   G4cout << "PixelThickness(mm): "<< PixelThickness/mm << G4endl;
0090   G4cout << "PixelSizeXY(cm): "<< PixelSizeXY/cm << G4endl;
0091   
0092   ContactSizeXY  = std::sqrt(40.) * mm * 0.5e6; //should be the same as PixelSize or lower 
0093 
0094   mercuryDia = 2 * 4880 * km ;
0095   sunDia =  1390000 * km ;
0096   mercurySunDistance = 57910000 * km ;
0097 
0098   
0099   OhmicNegThickness = 0.005*mm *0.5e6 ;
0100   OhmicPosThickness = 0.005*mm *0.5e6 ;
0101   
0102   screenThickness = 5 * mm *0.5e6;
0103   
0104   ThetaHPGe = 135. * deg ;
0105   PhiHPGe = 225. * deg  ;
0106   
0107   
0108   distDe = (mercuryDia/2 + 400 * km);
0109   
0110   distScreen = distDe + (screenThickness+PixelThickness)/2+OhmicPosThickness ;
0111 
0112   distOptic = distDe - 1.*m * 1e5;//!!!
0113   
0114   opticThickness = 1.* cm *0.5e6;
0115   opticDia = 21. * cm *0.5e6;  
0116   opticAperture = 1. * deg;
0117 
0118   PixelCopyNb=0;
0119   grainCopyNb=0;
0120   G4String defaultDetectorType = "sili";
0121   ComputeApparateParameters();
0122   SetDetectorType(defaultDetectorType);
0123   
0124   // create commands for interactive definition of the apparate
0125   
0126   detectorMessenger = new XrayFluoMercuryDetectorMessenger(this);
0127   G4cout << "XrayFluoMercuryDetectorConstruction created" << G4endl;
0128 }
0129 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0130 
0131 
0132 XrayFluoMercuryDetectorConstruction* XrayFluoMercuryDetectorConstruction::instance = 0;
0133 
0134 XrayFluoMercuryDetectorConstruction* XrayFluoMercuryDetectorConstruction::GetInstance()
0135 {
0136   if (instance == 0)
0137     {
0138       instance = new XrayFluoMercuryDetectorConstruction;
0139       
0140     }
0141   return instance;
0142 }
0143 
0144 void XrayFluoMercuryDetectorConstruction::SetDetectorType(G4String type)
0145 {
0146   
0147   if (type=="sili")
0148     {
0149       detectorType = XrayFluoSiLiDetectorType::GetInstance();
0150     }
0151   else if (type=="hpge")
0152     {
0153       detectorType = XrayFluoHPGeDetectorType::GetInstance();
0154     }
0155   else 
0156     {
0157       G4ExceptionDescription execp;
0158       execp <<  type + "detector type unknown";
0159       G4Exception("XrayFluoMercuryDetectorConstruction::SetDetectorType()","example-xray_fluorescence05",
0160       FatalException, execp);
0161     }
0162 }
0163 
0164 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0165 
0166 XrayFluoVDetectorType* XrayFluoMercuryDetectorConstruction::GetDetectorType() const
0167 {
0168   return detectorType;
0169 }
0170 
0171 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0172 
0173 XrayFluoMercuryDetectorConstruction::~XrayFluoMercuryDetectorConstruction()
0174   
0175 { 
0176   delete detectorMessenger;
0177   delete detectorType;
0178   G4cout << "XrayFluoMercuryDetectorConstruction deleted" << G4endl;
0179 }
0180 
0181 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0182 
0183 G4VPhysicalVolume* XrayFluoMercuryDetectorConstruction::Construct()
0184 {
0185   return ConstructApparate();
0186 }
0187 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0188 
0189 void XrayFluoMercuryDetectorConstruction::DefineDefaultMaterials()
0190 {
0191   
0192   
0193   //define materials of the apparate
0194   
0195   mercuryMaterial = materials->GetMaterial("Anorthosite");
0196   screenMaterial = materials->GetMaterial("G4_Pb");
0197   pixelMaterial = materials->GetMaterial("G4_Si");
0198   OhmicPosMaterial = materials->GetMaterial("G4_Cu");
0199   OhmicNegMaterial = materials->GetMaterial("G4_Pb");
0200   defaultMaterial = materials->GetMaterial("G4_Galactic");
0201   
0202   
0203 }
0204 
0205 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 
0206 
0207 G4VPhysicalVolume* XrayFluoMercuryDetectorConstruction::ConstructApparate()
0208 {
0209   // complete the apparate parameters definition 
0210   
0211   ComputeApparateParameters();
0212   
0213   //world
0214   
0215   solidWorld = new G4Box("World",                       //its name
0216              WorldSizeXY/2,WorldSizeXY/2,WorldSizeZ/2); //its size
0217   
0218   logicWorld = new G4LogicalVolume(solidWorld,      //its solid
0219                                    defaultMaterial, //its material
0220                                    "World");        //its name
0221   physiWorld = new G4PVPlacement(0,         //no rotation
0222                  G4ThreeVector(),   //at (0,0,0)
0223                  "World",       //its name
0224                  logicWorld,        //its logical volume
0225                  0,         //its mother  volume
0226                  false,         //no boolean operation
0227                  0);            //copy number
0228   
0229   //detector
0230   
0231   solidHPGe = 0;  physiHPGe = 0;  logicHPGe=0;
0232   solidPixel=0; logicPixel=0; physiPixel=0;
0233   
0234   if (DeviceThickness > 0.)  
0235     {
0236       solidHPGe = new G4Box("HPGeDetector",     //its name
0237                 DeviceSizeX/2,DeviceSizeY/2,DeviceThickness/2);//size
0238       
0239       
0240       logicHPGe = new G4LogicalVolume(solidHPGe,    //its solid
0241                       defaultMaterial,  //its material 
0242                       "HPGeDetector");  //its name
0243       
0244       zRotPhiHPGe.rotateX(PhiHPGe);
0245       G4double x,y,z;
0246       
0247       z = distDe * std::cos(ThetaHPGe);
0248       y = distScreen * std::sin(ThetaHPGe);
0249       x = 0.*cm;
0250       
0251       physiHPGe = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 
0252                     "HPGeDetector", //its name
0253                     logicHPGe,  //its logical volume
0254                     physiWorld, //its mother  volume
0255                     false,      //no boolean operation
0256                     0);     //copy number
0257     }
0258   // Pixel
0259   
0260   
0261   
0262   
0263   for ( G4int j=0; j < NbOfPixelColumns ; j++ )
0264     { for ( G4int i=0; i < NbOfPixelRows ; i++ )
0265       { 
0266     solidPixel=0; logicPixel=0;   physiPixel=0;
0267     if (PixelThickness > 0.)
0268       solidPixel = new G4Box("Pixel",           
0269                  PixelSizeXY/2,PixelSizeXY/2, PixelThickness/2);
0270     
0271     logicPixel = new G4LogicalVolume(solidPixel,    
0272                      pixelMaterial, //its material
0273                      "Pixel");          //its name
0274     
0275     /*
0276       zRotPhiHPGe.rotateX(PhiHPGe);
0277       G4double x,y,z;
0278       z = distDe * std::cos(ThetaHPGe);
0279       y =distDe * std::sin(ThetaHPGe);
0280       x = 0.*cm;*/ 
0281     physiPixel = new G4PVPlacement(0,          
0282                        G4ThreeVector(0,
0283                              i*PixelSizeXY, 
0284                              j*PixelSizeXY ),
0285                        "Pixel",  
0286                        logicPixel,   //its logical volume
0287                        physiHPGe, //its mother  volume
0288                        false,    //no boolean operation
0289                        PixelCopyNb);//copy number
0290     
0291     
0292     
0293     
0294     
0295     
0296     // OhmicNeg
0297     
0298     solidOhmicNeg=0; logicOhmicNeg=0; physiOhmicNeg=0;  
0299     
0300     if (OhmicNegThickness > 0.) 
0301       { solidOhmicNeg = new G4Box("OhmicNeg",       //its name
0302                       PixelSizeXY/2,PixelSizeXY/2,OhmicNegThickness/2); 
0303       
0304       logicOhmicNeg = new G4LogicalVolume(solidOhmicNeg,    //its solid
0305                           OhmicNegMaterial, //its material
0306                           "OhmicNeg");      //its name
0307       
0308       physiOhmicNeg = new G4PVPlacement(0,
0309                         G4ThreeVector
0310                         (0.,
0311                          0.,
0312                          (PixelThickness+OhmicNegThickness)/2),
0313                         "OhmicNeg",        //its name
0314                         logicOhmicNeg,     //its logical volume
0315                         physiHPGe,        //its mother
0316                         false,             //no boulean operat
0317                         PixelCopyNb);                //copy number
0318       
0319       }
0320     // OhmicPos
0321     solidOhmicPos=0; logicOhmicPos=0; physiOhmicPos=0;  
0322     
0323     if (OhmicPosThickness > 0.) 
0324       { solidOhmicPos = new G4Box("OhmicPos",       //its name
0325                       PixelSizeXY/2,PixelSizeXY/2,OhmicPosThickness/2); 
0326       
0327       logicOhmicPos = new G4LogicalVolume(solidOhmicPos,    //its solid
0328                           OhmicPosMaterial, //its material
0329                           "OhmicPos");      //its name
0330       
0331       physiOhmicPos = new G4PVPlacement(0,  
0332                         G4ThreeVector(0.,
0333                               0.,
0334                               (-PixelThickness-OhmicPosThickness)/2),  
0335                         "OhmicPos",  
0336                         logicOhmicPos,
0337                         physiHPGe,  
0338                         false,     
0339                         PixelCopyNb); 
0340       
0341       }
0342     
0343     PixelCopyNb += PixelCopyNb; 
0344     G4cout << "PixelCopyNb: " << PixelCopyNb << G4endl;
0345       }
0346     
0347     }
0348   
0349   // Optics
0350 
0351   if (DeviceThickness > 0.)  
0352     {
0353       solidOptic = new G4Tubs("DetectorOptic",      //its name
0354                   0.,opticDia/2, opticThickness, 0.,2.*pi);//size
0355       
0356       
0357       logicOptic = new G4LogicalVolume(solidOptic,  //its solid
0358                        defaultMaterial, //its material 
0359                        "DetectorOptic");    //its name
0360       
0361       //zRotPhiHPGe.rotateX(PhiHPGe);
0362       G4double x,y,z;
0363       z = distOptic * std::cos(ThetaHPGe);
0364       y = distOptic * std::sin(ThetaHPGe);
0365       x = 0.*cm;
0366       physiOptic = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 
0367                       "DetectorOptic",  //its name
0368                       logicOptic,   //its logical volume
0369                       physiWorld,   //its mother  volume
0370                       false,        //no boolean operation
0371                       0);       //copy number
0372     }
0373   
0374 
0375   // Screen
0376   
0377   if (DeviceThickness > 0.)  
0378     {
0379       solidScreen = new G4Box("DetectorScreen",     //its name
0380                   screenSizeXY/2,screenSizeXY/2,screenThickness/2);//size
0381       
0382       
0383       logicScreen = new G4LogicalVolume(solidScreen,    //its solid
0384                     defaultMaterial,    //its material 
0385                     "DetectorScreen");  //its name
0386       
0387       //zRotPhiHPGe.rotateX(PhiHPGe);
0388       G4double x,y,z;
0389       G4cout << "distScreen: "<< distScreen/m <<G4endl;
0390       z = distScreen * std::cos(ThetaHPGe);
0391       y = distScreen * std::sin(ThetaHPGe);
0392       x = 0.*cm;
0393       physiScreen = new G4PVPlacement(G4Transform3D(zRotPhiHPGe,G4ThreeVector(x,y,z)), 
0394                       "DetectorScreen", //its name
0395                       logicScreen,  //its logical volume
0396                       physiWorld,   //its mother  volume
0397                       false,        //no boolean operation
0398                       0);       //copy number
0399     }
0400   
0401   //Mercury
0402   
0403   
0404   solidMercury=0;  logicMercury=0;  physiMercury=0;
0405   if (mercuryDia > 0.)  
0406     {
0407 
0408 
0409         
0410 
0411 
0412 
0413       solidMercury = new G4Sphere("Mercury",0.,mercuryDia/2., 0., twopi, 0., pi);
0414             
0415       logicMercury= new G4LogicalVolume(solidMercury,   //its solid
0416                     mercuryMaterial,    //its material
0417                     "Mercury"); //its name
0418       
0419       physiMercury = new G4PVPlacement(0,           //no rotation
0420                        G4ThreeVector(), //at (0,0,0)
0421                        "Mercury",   //its name
0422                        logicMercury,    //its logical volume
0423                        physiWorld,  //its mother  volume
0424                        false,       //no boolean operation
0425                        0);      //copy number
0426       
0427     }  
0428   
0429    
0430   // Visualization attributes
0431   
0432 
0433   logicWorld->SetVisAttributes (G4VisAttributes::GetInvisible());
0434   G4VisAttributes* simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
0435   G4VisAttributes * yellow= new G4VisAttributes( G4Colour(255/255. ,255/255. ,51/255. ));
0436   G4VisAttributes * red= new G4VisAttributes( G4Colour(255/255. , 0/255. , 0/255. ));
0437   G4VisAttributes * blue= new G4VisAttributes( G4Colour(0/255. , 0/255. ,  255/255. ));
0438   G4VisAttributes * grayc= new G4VisAttributes( G4Colour(128/255. , 128/255. ,  128/255. ));
0439   G4VisAttributes * darkGray= new G4VisAttributes( G4Colour(95/255. , 95/255. ,  95/255. ));
0440   //G4VisAttributes * green= new G4VisAttributes( G4Colour(25/255. , 255/255. ,  25/255. ));
0441   yellow->SetVisibility(true);
0442   yellow->SetForceSolid(true);
0443   red->SetVisibility(true);
0444   red->SetForceSolid(true);
0445   blue->SetVisibility(true);
0446   grayc->SetVisibility(true);
0447   grayc->SetForceSolid(true);
0448   simpleBoxVisAtt->SetVisibility(true);
0449 
0450   //logicWorld->SetVisAttributes (simpleBoxVisAtt);
0451   
0452   logicPixel->SetVisAttributes(red);
0453   logicHPGe->SetVisAttributes(G4VisAttributes::GetInvisible());
0454   
0455   logicMercury->SetVisAttributes(darkGray);
0456   
0457 
0458   logicScreen->SetVisAttributes(red);
0459   logicOhmicNeg->SetVisAttributes(yellow);
0460   logicOhmicPos->SetVisAttributes(yellow);
0461   logicOptic->SetVisAttributes(grayc);
0462 
0463 
0464   if (mercuryGranularity)  logicGrain->SetVisAttributes(grayc);
0465 
0466   //always return the physical World
0467     
0468   PrintApparateParameters();
0469 
0470   return physiWorld;
0471 }
0472 
0473 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0474 
0475 void XrayFluoMercuryDetectorConstruction::ConstructSDandField()
0476 {
0477    //                               
0478   // Sensitive Detectors 
0479   //
0480   if (HPGeSD.Get() == 0) 
0481     {    
0482       XrayFluoSD* SD = new XrayFluoSD ("HPGeSD",this);
0483       HPGeSD.Put( SD );
0484     }
0485   G4SDManager::GetSDMpointer()->AddNewDetector(HPGeSD.Get());
0486   if (logicPixel)    
0487     SetSensitiveDetector(logicPixel,HPGeSD.Get());
0488 }
0489 
0490 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0491 
0492 void XrayFluoMercuryDetectorConstruction::PrintApparateParameters()
0493 {
0494   G4cout << "-----------------------------------------------------------------------"
0495      << G4endl
0496      << "The mercury is a sphere whose diamter is: "
0497      << G4endl      
0498      << mercuryDia/km
0499      << " Km "
0500      << G4endl
0501      <<" Material: " << logicMercury->GetMaterial()->GetName() 
0502      <<G4endl
0503      <<"The Detector is a slice  " << DeviceThickness/(1.e-6*m) 
0504      << " micron thick of " << pixelMaterial->GetName()<<G4endl
0505      <<"-------------------------------------------------------------------------"
0506      << G4endl;
0507 }
0508 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0509 
0510 void XrayFluoMercuryDetectorConstruction::UpdateGeometry()
0511 {
0512 
0513   G4GeometryManager::GetInstance()->OpenGeometry();
0514   G4PhysicalVolumeStore::Clean();
0515   G4LogicalVolumeStore::Clean();
0516   G4SolidStore::Clean();
0517 
0518   zRotPhiHPGe.rotateX(-1.*PhiHPGe);
0519   ComputeApparateParameters();  
0520 
0521   //Triggers a new call of Construct() and of all the geometry resets.
0522   G4RunManager::GetRunManager()->ReinitializeGeometry();
0523 
0524 }
0525 
0526 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0527 
0528 void XrayFluoMercuryDetectorConstruction::SetMercuryMaterial(G4String newMaterial)
0529 {
0530   G4cout << "New Mercury Material: " << newMaterial << G4endl;
0531   logicMercury->SetMaterial(materials->GetMaterial(newMaterial));
0532   PrintApparateParameters();
0533    //GeometryHasBeenModified is called by the messenger
0534 }
0535 
0536 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
0537 
0538 
0539 
0540 
0541 
0542 
0543 
0544 
0545 
0546 
0547