Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:22:43

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 runAndEvent/RE02/src/RE02DetectorConstruction.cc
0027 /// \brief Implementation of the RE02DetectorConstruction class
0028 //
0029 //
0030 //
0031 
0032 #include "RE02DetectorConstruction.hh"
0033 
0034 #include "RE02NestedPhantomParameterisation.hh"
0035 
0036 #include "G4Box.hh"
0037 #include "G4Colour.hh"
0038 #include "G4LogicalVolume.hh"
0039 #include "G4Material.hh"
0040 #include "G4NistManager.hh"
0041 #include "G4PSCellFlux3D.hh"
0042 #include "G4PSEnergyDeposit3D.hh"
0043 #include "G4PSFlatSurfaceCurrent3D.hh"
0044 #include "G4PSFlatSurfaceFlux3D.hh"
0045 #include "G4PSNofStep3D.hh"
0046 #include "G4PSPassageCellFlux3D.hh"
0047 #include "G4PVParameterised.hh"
0048 #include "G4PVPlacement.hh"
0049 #include "G4SDChargedFilter.hh"
0050 #include "G4SDManager.hh"
0051 #include "G4SDParticleFilter.hh"
0052 #include "G4SDParticleWithEnergyFilter.hh"
0053 #include "G4SystemOfUnits.hh"
0054 #include "G4VisAttributes.hh"
0055 #include "G4ios.hh"
0056 
0057 //=======================================================================
0058 //  RE02DetectorConstruction
0059 //
0060 //  (Description)
0061 //
0062 //     Detector construction for example RE02.
0063 //
0064 //   [Geometry]
0065 //     The world volume is defined as 200 cm x 200 cm x 200 cm box with Air.
0066 //   Water phantom is defined as  200 mm x 200 mm x 400 mm box with Water.
0067 //   The water phantom is divided into 100 segments in x,y plane using
0068 //   replication,
0069 //   and then divided into 200 segments perpendicular to z axis using nested
0070 //   parameterised volume.
0071 //    These values are defined at constructor,
0072 //    e.g. the size of water phantom (fPhantomSize), and number of segmentation
0073 //   of water phantom (fNx, fNy, fNz).
0074 //
0075 //   By default, lead plates are inserted into the position of even order
0076 //   segments.
0077 //   NIST database is used for materials.
0078 //
0079 //
0080 //   [Scorer]
0081 //    Assignment of G4MultiFunctionalDetector and G4PrimitiveScorer
0082 //   is demonstrated in this example.
0083 //       -------------------------------------------------
0084 //       The collection names of defined Primitives are
0085 //        0       PhantomSD/totalEDep
0086 //        1       PhantomSD/protonEDep
0087 //        2       PhantomSD/protonNStep
0088 //        3       PhantomSD/chargedPassCellFlux
0089 //        4       PhantomSD/chargedCellFlux
0090 //        5       PhantomSD/chargedSurfFlux
0091 //        6       PhantomSD/gammaSurfCurr000
0092 //        7       PhantomSD/gammaSurfCurr001
0093 //        9       PhantomSD/gammaSurdCurr002
0094 //       10       PhantomSD/gammaSurdCurr003
0095 //      -------------------------------------------------
0096 //      Please see README for detail description.
0097 //
0098 //=======================================================================
0099 
0100 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0101 RE02DetectorConstruction::RE02DetectorConstruction() : G4VUserDetectorConstruction()
0102 {
0103   // Default size of water phantom,and segmentation.
0104   fPhantomSize.setX(200. * mm);
0105   fPhantomSize.setY(200. * mm);
0106   fPhantomSize.setZ(400. * mm);
0107   fNx = fNy = fNz = 100;
0108   fInsertLead = TRUE;
0109 }
0110 
0111 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0112 RE02DetectorConstruction::~RE02DetectorConstruction()
0113 {
0114   ;
0115 }
0116 
0117 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0118 G4VPhysicalVolume* RE02DetectorConstruction::Construct()
0119 {
0120   //=====================
0121   // Material Definitions
0122   //=====================
0123   //
0124   //-------- NIST Materials ----------------------------------------------------
0125   //  Material Information imported from NIST database.
0126   //
0127   G4NistManager* NISTman = G4NistManager::Instance();
0128   G4Material* air = NISTman->FindOrBuildMaterial("G4_AIR");
0129   G4Material* water = NISTman->FindOrBuildMaterial("G4_WATER");
0130   G4Material* lead = NISTman->FindOrBuildMaterial("G4_Pb");
0131 
0132   //
0133   // Print all the materials defined.
0134   G4cout << G4endl << "The materials defined are : " << G4endl << G4endl;
0135   G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0136 
0137   //============================================================================
0138   //      Definitions of Solids, Logical Volumes, Physical Volumes
0139   //============================================================================
0140 
0141   //-------------
0142   // World Volume
0143   //-------------
0144 
0145   G4ThreeVector worldSize = G4ThreeVector(200 * cm, 200 * cm, 200 * cm);
0146 
0147   G4Box* solidWorld =
0148     new G4Box("world", worldSize.x() / 2., worldSize.y() / 2., worldSize.z() / 2.);
0149   G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWorld, air, "World", 0, 0, 0);
0150 
0151   //
0152   //  Must place the World Physical volume unrotated at (0,0,0).
0153   G4VPhysicalVolume* physiWorld = new G4PVPlacement(0,  // no rotation
0154                                                     G4ThreeVector(),  // at (0,0,0)
0155                                                     logicWorld,  // its logical volume
0156                                                     "World",  // its name
0157                                                     0,  // its mother  volume
0158                                                     false,  // no boolean operations
0159                                                     0);  // copy number
0160 
0161   //---------------
0162   // Water Phantom
0163   //---------------
0164 
0165   //................................
0166   // Mother Volume of Water Phantom
0167   //................................
0168 
0169   //--  Default size of water phantom is defined at constructor.
0170   G4ThreeVector phantomSize = fPhantomSize;
0171 
0172   G4Box* solidPhantom =
0173     new G4Box("phantom", phantomSize.x() / 2., phantomSize.y() / 2., phantomSize.z() / 2.);
0174   G4LogicalVolume* logicPhantom = new G4LogicalVolume(solidPhantom, water, "Phantom", 0, 0, 0);
0175 
0176   G4RotationMatrix* rot = new G4RotationMatrix();
0177   // rot->rotateY(30.*deg);
0178   G4ThreeVector positionPhantom;
0179   // G4VPhysicalVolume * physiPhantom =
0180   new G4PVPlacement(rot,  // no rotation
0181                     positionPhantom,  // at (x,y,z)
0182                     logicPhantom,  // its logical volume
0183                     "Phantom",  // its name
0184                     logicWorld,  // its mother  volume
0185                     false,  // no boolean operations
0186                     0);  // copy number
0187 
0188   //..............................................
0189   // Phantom segmentation using Parameterisation
0190   //..............................................
0191   //
0192   G4cout << "<-- RE02DetectorConstruction::Construct-------" << G4endl;
0193   G4cout << "  Water Phantom Size " << fPhantomSize / mm << G4endl;
0194   G4cout << "  Segmentation  (" << fNx << "," << fNy << "," << fNz << ")" << G4endl;
0195   G4cout << "  Lead plate at even copy # (0-False,1-True): " << IsLeadSegment() << G4endl;
0196   G4cout << "<---------------------------------------------" << G4endl;
0197   // Number of segmentation.
0198   // - Default number of segmentation is defined at constructor.
0199   G4int nxCells = fNx;
0200   G4int nyCells = fNy;
0201   G4int nzCells = fNz;
0202 
0203   G4ThreeVector sensSize;
0204   sensSize.setX(phantomSize.x() / (G4double)nxCells);
0205   sensSize.setY(phantomSize.y() / (G4double)nyCells);
0206   sensSize.setZ(phantomSize.z() / (G4double)nzCells);
0207   // i.e Voxel size will be 2.0 x 2.0 x 2.0 mm3 cube by default.
0208   //
0209 
0210   // Replication of Water Phantom Volume.
0211   // Y Slice
0212   G4String yRepName("RepY");
0213   G4VSolid* solYRep =
0214     new G4Box(yRepName, phantomSize.x() / 2., sensSize.y() / 2., phantomSize.z() / 2.);
0215   G4LogicalVolume* logYRep = new G4LogicalVolume(solYRep, water, yRepName);
0216   // G4PVReplica* yReplica =
0217   new G4PVReplica(yRepName, logYRep, logicPhantom, kYAxis, fNy, sensSize.y());
0218   // X Slice
0219   G4String xRepName("RepX");
0220   G4VSolid* solXRep =
0221     new G4Box(xRepName, sensSize.x() / 2., sensSize.y() / 2., phantomSize.z() / 2.);
0222   G4LogicalVolume* logXRep = new G4LogicalVolume(solXRep, water, xRepName);
0223   // G4PVReplica* xReplica =
0224   new G4PVReplica(xRepName, logXRep, logYRep, kXAxis, fNx, sensSize.x());
0225 
0226   //
0227   //..................................
0228   // Voxel solid and logical volumes
0229   //..................................
0230   // Z Slice
0231   G4String zVoxName("phantomSens");
0232   G4VSolid* solVoxel = new G4Box(zVoxName, sensSize.x() / 2., sensSize.y() / 2., sensSize.z() / 2.);
0233   fLVPhantomSens = new G4LogicalVolume(solVoxel, water, zVoxName);
0234   //
0235   //
0236   std::vector<G4Material*> phantomMat(2, water);
0237   if (IsLeadSegment()) phantomMat[1] = lead;
0238   //
0239   // Parameterisation for transformation of voxels.
0240   //  (voxel size is fixed in this example.
0241   //  e.g. nested parameterisation handles material and transfomation of voxels.)
0242   RE02NestedPhantomParameterisation* paramPhantom =
0243     new RE02NestedPhantomParameterisation(sensSize / 2., nzCells, phantomMat);
0244   // G4VPhysicalVolume * physiPhantomSens =
0245   new G4PVParameterised("PhantomSens",  // their name
0246                         fLVPhantomSens,  // their logical volume
0247                         logXRep,  // Mother logical volume
0248                         kUndefined,  // Are placed along this axis
0249                         nzCells,  // Number of cells
0250                         paramPhantom);  // Parameterisation.
0251   //   Optimization flag is avaiable for,
0252   //    kUndefined, kXAxis, kYAxis, kZAxis.
0253   //
0254 
0255   //===============================
0256   //   Visualization attributes
0257   //===============================
0258 
0259   G4VisAttributes* boxVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
0260   logicWorld->SetVisAttributes(boxVisAtt);
0261   // logicWorld->SetVisAttributes(G4VisAttributes::GetInvisible());
0262 
0263   // Mother volume of WaterPhantom
0264   G4VisAttributes* phantomVisAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 0.0));
0265   logicPhantom->SetVisAttributes(phantomVisAtt);
0266 
0267   // Replica
0268   G4VisAttributes* yRepVisAtt = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0));
0269   logYRep->SetVisAttributes(yRepVisAtt);
0270   G4VisAttributes* xRepVisAtt = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0));
0271   logXRep->SetVisAttributes(xRepVisAtt);
0272 
0273   // Skip the visualization for those voxels.
0274   fLVPhantomSens->SetVisAttributes(G4VisAttributes::GetInvisible());
0275 
0276   return physiWorld;
0277 }
0278 
0279 void RE02DetectorConstruction::ConstructSDandField()
0280 {
0281   //================================================
0282   // Sensitive detectors : MultiFunctionalDetector
0283   //================================================
0284   //
0285   //  Sensitive Detector Manager.
0286   G4SDManager* pSDman = G4SDManager::GetSDMpointer();
0287   //
0288   // Sensitive Detector Name
0289   G4String phantomSDname = "PhantomSD";
0290 
0291   //------------------------
0292   // MultiFunctionalDetector
0293   //------------------------
0294   //
0295   // Define MultiFunctionalDetector with name.
0296   G4MultiFunctionalDetector* mFDet = new G4MultiFunctionalDetector(phantomSDname);
0297   pSDman->AddNewDetector(mFDet);  // Register SD to SDManager.
0298   fLVPhantomSens->SetSensitiveDetector(mFDet);  // Assign SD to the logical volume.
0299 
0300   //---------------------------------------
0301   // SDFilter : Sensitive Detector Filters
0302   //---------------------------------------
0303   //
0304   // Particle Filter for Primitive Scorer with filter name(fltName)
0305   // and particle name(particleName),
0306   // or particle names are given by add("particle name"); method.
0307   //
0308   G4String fltName, particleName;
0309   //
0310   //-- proton filter
0311   G4SDParticleFilter* protonFilter =
0312     new G4SDParticleFilter(fltName = "protonFilter", particleName = "proton");
0313   //
0314   //-- electron filter
0315   G4SDParticleFilter* electronFilter = new G4SDParticleFilter(fltName = "electronFilter");
0316   electronFilter->add(particleName = "e+");  // accept electrons.
0317   electronFilter->add(particleName = "e-");  // accept positorons.
0318   //
0319   //-- charged particle filter
0320   G4SDChargedFilter* chargedFilter = new G4SDChargedFilter(fltName = "chargedFilter");
0321 
0322   //------------------------
0323   // PS : Primitive Scorers
0324   //------------------------
0325   // Primitive Scorers are used with SDFilters according to your purpose.
0326   //
0327   //
0328   //-- Primitive Scorer for Energy Deposit.
0329   //      Total, by protons, by electrons.
0330   G4String psName;
0331   G4PSEnergyDeposit3D* scorer0 = new G4PSEnergyDeposit3D(psName = "totalEDep", fNx, fNy, fNz);
0332   G4PSEnergyDeposit3D* scorer1 = new G4PSEnergyDeposit3D(psName = "protonEDep", fNx, fNy, fNz);
0333   scorer1->SetFilter(protonFilter);
0334 
0335   //
0336   //-- Number of Steps for protons
0337   G4PSNofStep3D* scorer2 = new G4PSNofStep3D(psName = "protonNStep", fNx, fNy, fNz);
0338   scorer2->SetFilter(protonFilter);
0339 
0340   //
0341   //-- CellFlux for charged particles
0342   G4PSPassageCellFlux3D* scorer3 =
0343     new G4PSPassageCellFlux3D(psName = "chargedPassCellFlux", fNx, fNy, fNz);
0344   G4PSCellFlux3D* scorer4 = new G4PSCellFlux3D(psName = "chargedCellFlux", fNx, fNy, fNz);
0345   G4PSFlatSurfaceFlux3D* scorer5 =
0346     new G4PSFlatSurfaceFlux3D(psName = "chargedSurfFlux", fFlux_InOut, fNx, fNy, fNz);
0347   scorer3->SetFilter(chargedFilter);
0348   scorer4->SetFilter(chargedFilter);
0349   scorer5->SetFilter(chargedFilter);
0350 
0351   //
0352   //------------------------------------------------------------
0353   //  Register primitive scorers to MultiFunctionalDetector
0354   //------------------------------------------------------------
0355   mFDet->RegisterPrimitive(scorer0);
0356   mFDet->RegisterPrimitive(scorer1);
0357   mFDet->RegisterPrimitive(scorer2);
0358   mFDet->RegisterPrimitive(scorer3);
0359   mFDet->RegisterPrimitive(scorer4);
0360   mFDet->RegisterPrimitive(scorer5);
0361 
0362   //========================
0363   // More additional Primitive Scoreres
0364   //========================
0365   //
0366   //--- Surface Current for gamma with energy bin.
0367   // This example creates four primitive scorers.
0368   //  4 bins with energy   ---   Primitive Scorer Name
0369   //    1.     to  10 KeV,        gammaSurfCurr000
0370   //   10 keV  to 100 KeV,        gammaSurfCurr001
0371   //  100 keV  to   1 MeV,        gammaSurfCurr002
0372   //    1 MeV  to  10 MeV.        gammaSurfCurr003
0373   //
0374   for (G4int i = 0; i < 4; i++) {
0375     std::ostringstream name;
0376     name << "gammaSurfCurr" << std::setfill('0') << std::setw(3) << i;
0377     G4String psgName = name.str();
0378     G4double kmin = std::pow(10., (G4double)i) * keV;
0379     G4double kmax = std::pow(10., (G4double)(i + 1)) * keV;
0380     //-- Particle with kinetic energy filter.
0381     G4SDParticleWithEnergyFilter* pkinEFilter =
0382       new G4SDParticleWithEnergyFilter(fltName = "gammaE filter", kmin, kmax);
0383     pkinEFilter->add("gamma");  // Accept only gamma.
0384     pkinEFilter->show();  // Show accepting condition to stdout.
0385     //-- Surface Current Scorer which scores  number of tracks in unit area.
0386     G4PSFlatSurfaceCurrent3D* scorer =
0387       new G4PSFlatSurfaceCurrent3D(psgName, fCurrent_InOut, fNx, fNy, fNz);
0388     scorer->SetFilter(pkinEFilter);  // Assign filter.
0389     mFDet->RegisterPrimitive(scorer);  // Register it to MultiFunctionalDetector.
0390   }
0391 }