///////////////////////////////////////////////////////////////////////// // G4Tutorial: // // DetectorReadOutGeometry.cc // ///////////////////////////////////////////////////////////////////////// #include "DetectorReadOutGeometry.hh" #include "SensitiveDetector.hh" #include "AnalysisManager.hh" #include "G4Box.hh" #include "G4VPhysicalVolume.hh" #include "G4LogicalVolume.hh" #include "G4PVPlacement.hh" #include "G4PVReplica.hh" DetectorReadOutGeometry::DetectorReadOutGeometry(G4int bins, G4double len) : numbBins(bins), length(len) { } DetectorReadOutGeometry::~DetectorReadOutGeometry() { } G4VPhysicalVolume* DetectorReadOutGeometry::Build() { // NOTE: Read-out geometries are created in the same manner as detector // geometries, with the exception that any materials assigned to read-out // geometry objects are not considered in the simulation. // The material for the read-out geometry is irrelevant (we choose vacuum // for convenience): G4String nameVacuum = "Dummy"; // The mole mass, atomic number, density and the mean excitation energy: 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* dummy = new G4Material(nameVacuum, ZVacuum, moleMassVacuum, densityVacuum, kStateGas, temperatureVacuum, pressureVacuum); // I. Definition of the world volume for the read-out geometry: // // The world is defined as a cube: G4VSolid* worldVolROSolid = new G4Box("ROWorld", length * 0.5, length * 0.5, length * 0.5); // The next step is to create a logical world volume G4LogicalVolume* worldVolROLogic = new G4LogicalVolume(worldVolROSolid, // geometrical object dummy, // (dummy) material "ROWorld"); // name // 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) G4VPhysicalVolume* worldVolROPhys = new G4PVPlacement(0, // no rotation G4ThreeVector(), // no translation "ROWorld", // name worldVolROLogic, // the logical volume 0, // the world has no mother false, // param. for future use 0); // copy number // II. Setup of the actual read-out geometry (placed within the world // volume): // The read-out geometry consists of thin slices placed consecutively along // the z-axis. // As a first step we need to create a "confinement volume" for these slices // (i.e. this volume will contain all the slices). // Here, this volume has exactly the same shape as the cubiod detector // defined in the DetectorConstruction class: G4VSolid* detVolROSolid = new G4Box("RODetector", length * 0.5, length * 0.5, length * 0.5); // The next step is to create a logical volume: G4LogicalVolume* detVolROLogic = new G4LogicalVolume(detVolROSolid, dummy, "RODetector"); // Then the physical volume is created (the position is chosen accordingly // to the detector position given in the DetectorConstruction class): new G4PVPlacement(0, // no rotation G4ThreeVector(0.0 * cm, 0.0 * cm, length * 0.5), // translation along z-axis "RODetector", // name detVolROLogic, // logical volume worldVolROPhys, // physical volume of the mother false, // param. for future use 0); // copy number // As the next step, we create the actual "slices", each of thickness // given by "binSize": G4double binSize = length / (G4double(numbBins)); AnalysisManager::Instance("energydeposition", numbBins, 0.0, binSize * G4double(numbBins) / mm); // A "slice" is simply a box: G4VSolid* layVolROSolid = new G4Box("ROLayer", length * 0.5, length * 0.5, binSize * 0.5); // Then we create a logical volume: G4LogicalVolume* layVolROLogic = new G4LogicalVolume(layVolROSolid, dummy, "ROLayer"); // G4PVReplica can be used to create a range of physical volumes for a // single logical volume. The physical volumes are arranged in consecutive // manner (this procedure can be applied for different types of coordinate // systems; here we use cartesian coordinates: kZAxis represents the z-axis). // We place "slices" consecutively along the z-axis: new G4PVReplica("ROLayer", // name layVolROLogic, // logical volume detVolROLogic, // log. volume of mother kZAxis, // z-axis numbBins, // number of replicas binSize); // thickness of replicas // (z-dimension) // A sensitive detector must be assigned in order to declare the sensitive // parts of the read-out geometry, but it will not be used (it must be // there but is irrelevant): G4VSensitiveDetector* layVolROSD = new SensitiveDetector("ROLayer"); layVolROLogic -> SetSensitiveDetector(layVolROSD); // The function must return the physical volume of the world return worldVolROPhys; }