///////////////////////////////////////////////////////////////////////// // G4Tutorial: // // DetectorConstruction.cc // ///////////////////////////////////////////////////////////////////////// #include "DetectorConstruction.hh" #include "DetectorMessenger.hh" #include "SensitiveDetector.hh" #include "DetectorReadOutGeometry.hh" #include "G4RunManager.hh" #include "G4RegionStore.hh" #include "G4SDManager.hh" #include "G4Box.hh" #include "G4Material.hh" #include "G4VPhysicalVolume.hh" #include "G4LogicalVolume.hh" #include "G4PVPlacement.hh" #include "G4UserLimits.hh" #include "G4VisAttributes.hh" #include "G4Colour.hh" DetectorConstruction::DetectorConstruction(G4String detectorRegionName) : messenger(0), worldVolPhys(0), detVolPhys(0), detVolLogic(0), detVolSolid(0), detVolUserLimits(0), detVolVisAtt(0), detRegionName(detectorRegionName) { // Instantiation of messenger messenger = new DetectorMessenger(this); } DetectorConstruction::~DetectorConstruction() { // Deleting detector messenger instance delete messenger; } G4VPhysicalVolume* DetectorConstruction::Construct() { // I. Setup of the world volume: // // The world is defined as a cube (dimension: 100 x 100 x 100 cm) G4VSolid* worldVolSolid = new G4Box("World", 50 * cm, 50 * cm, 50 * cm); // The world "material" is vacuum. Parameters used for the definition of // the material "vacuum" are: // The material name: G4String nameVacuum = "Vacuum"; // The mole mass, density: G4double densityVacuum = universe_mean_density; G4double moleMassVacuum = 1.01 * g/mole; // The temperature, pressure and atomic number: G4double pressureVacuum = 3.e-18 * pascal; G4double temperatureVacuum = 2.73 * kelvin; G4double ZVacuum = 1.; // Constructing vacuum: G4Material* vacuum = new G4Material(nameVacuum, ZVacuum, moleMassVacuum, densityVacuum, kStateGas, temperatureVacuum, pressureVacuum); // // Exercize 2.3 // // define liquid nitrogen G4String name,symbol; G4double abundance,density,fractionmass; G4int nIsotopes,natoms; G4double A,Z; G4double temperature,pressure; G4Material* liquidNitrogen = new G4Material(name="LiquidNitrogen",Z=7.,A=14.01*g/mole, density=0.808*g/cm3,kStateLiquid, temperature=77*kelvin); // // define elemental nitrogen and oxygen G4Element* elNitrogen = new G4Element(name="Nitrogen",symbol="N",Z=7.,A=14.01*g/mole); G4Element* elOxygen = new G4Element(name="Oxygen",symbol="O",Z=8.,A=15.9994*g/mole); // define air G4Material* air = new G4Material(name="air",density=1.29*mg/cm3,2,kStateGas,temperature=300*kelvin, pressure=1*atmosphere); air->AddElement(elNitrogen,fractionmass=80.0*perCent); air->AddElement(elOxygen,fractionmass=20.0*perCent); //end of exercise 2.3 // The next step is to create a logical world volume (By creating a logical // volume, a material or special properties can be assigned to the // geometrical object) G4LogicalVolume* worldVolLogic = new G4LogicalVolume(worldVolSolid, // geometrical object vacuum, // material "World"); // name // Visualization: The world should be invisible worldVolLogic -> SetVisAttributes(G4VisAttributes::Invisible); // Finally a physical object of the world must be created (By creating a // physical volume, logical volumes are placed within the coordinate system // and a volume hierarchy can be established) worldVolPhys = new G4PVPlacement(0, // no rotation G4ThreeVector(), // no translation "World", // name worldVolLogic, // the logical volume 0, // the world has no mother false, // param. for future use 0); // copy number //Define isotopes G4Isotope* Ge72 = new G4Isotope(name="Ge72", 32, 72, 71.92*g/mole); G4Isotope* Ge73 = new G4Isotope(name="Ge73", 32, 73, 73.0*g/mole); G4Isotope* Ge74 = new G4Isotope(name="Ge74", 32, 74, 74.0*g/mole); G4Isotope* Ge76 = new G4Isotope(name="Ge76", 32, 76, 76.0*g/mole); //Define element from isotopes G4Element* elGeEnr = new G4Element(name="enrichedGermanium", symbol="GeEnr",nIsotopes=4); elGeEnr->AddIsotope(Ge72,abundance= 0.1*perCent); elGeEnr->AddIsotope(Ge73,abundance= 0.2*perCent); elGeEnr->AddIsotope(Ge74,abundance= 13.1*perCent); elGeEnr->AddIsotope(Ge76,abundance= 86.6*perCent); //Define material G4Material* enrGe = new G4Material(name="EnrichedGe", density=5,32*g/cm3,1); enrGe->AddElement(elGeEnr,natoms=1); // II. Setup of the detector volume (placed within the world volume): // // The detector is defined as a cube (dimension: 4 x 4 x 4 cm) G4double boxLength = 4.0 * cm; detVolSolid = new G4Box("Detector", boxLength * 0.5, boxLength * 0.5, boxLength * 0.5); // The detector material is silicon. Parameters for constructing silicon: G4String nameSilicon = "Silicon"; // The mole mass, atomic number, density and the mean excitation energy: G4double moleMassSilicon = 28.085 * g/mole; G4double ZSilicon = 14; G4double densitySilicon = 2.33 *g/cm3; G4double ISilicon = 173.0 * eV; G4Material* silicon = new G4Material(nameSilicon, ZSilicon, moleMassSilicon, densitySilicon); silicon -> GetIonisation() -> SetMeanExcitationEnergy(ISilicon); // Definition of the logical volume of the detector detVolLogic = new G4LogicalVolume(detVolSolid, // geometrical object silicon, // material "Detector"); // name // Visulization: The detector should be visible (colour: yellow). To achieve // this, a G4VisAttributes object must be instantiated and assigned to the // logical volume detVolVisAtt = new G4VisAttributes(true, // visibility: true G4Colour::Yellow()); // colour: yellow detVolLogic -> SetVisAttributes(detVolVisAtt); // The maximum step size of particles in the detector should be limited. For // this purpose a G4UserLimits object must be instantiated and assigned to // the logical volume (The max. step size is set to 0.001 mm). detVolUserLimits = new G4UserLimits(0.001 * mm); detVolLogic -> SetUserLimits(detVolUserLimits); // Definition of the physical volume of the detector detVolPhys = new G4PVPlacement(0, // no rotation G4ThreeVector(0, 0, boxLength * 0.5), // translation "Detector", // name detVolLogic, // logical volume of the detector worldVolPhys, // physical volume of mother volume false, // param. for future use 0); // copy number // The detector is defined as a Geant4 region G4Region* detectorRegion = new G4Region(detRegionName); detectorRegion -> AddRootLogicalVolume(detVolLogic); // A read-out geometry is created and built (The read-out geometry is // defined in the class DetectorReadOutGeometry. See // DetectorReadOutGeometry.hh/.cc for details) G4VReadOutGeometry* detVolRO = new DetectorReadOutGeometry(200, // # of bins in z-dir. boxLength); // box dimension detVolRO -> BuildROGeometry(); // So far, the detector created above is not yet a real detector: It is just // a geometrical object (with some attributes) placed within the world // volume. // To make the volume a detector, which can record e.g. hits, one must // define a sensitive volume associated with it (see // DetectorSensitiveVolume.hh/.cc for details on the definition of a // sensitive detector). // For this purpose, a DetectorSensitiveVolume object is instantiated G4VSensitiveDetector* detVolSD = new SensitiveDetector("Detector"); // The above defined read-out geometry is assigned to this sensitive volume detVolSD -> SetROgeometry(detVolRO); // The sensitive volume is then assigned to the detector detVolLogic -> SetSensitiveDetector(detVolSD); // Finally, the sensitive detector manager must be informed about this new // sensitive detector G4SDManager::GetSDMpointer() -> AddNewDetector(detVolSD); // The function must return the physical volume of the world return worldVolPhys; } void DetectorConstruction::SetBoxMaxStepSize(G4double max) { if(max > 0.0 * mm) { detVolUserLimits -> SetMaxAllowedStep(max); G4RunManager::GetRunManager() -> DefineWorldVolume(worldVolPhys); } } void DetectorConstruction::SetBoxColour(G4String colour) { G4Colour col; if(G4Colour::GetColour(colour,col)) { detVolVisAtt -> SetColour(col); G4RunManager::GetRunManager() -> DefineWorldVolume(worldVolPhys); } }