#include "DetectorConstruction.hh" #include "PhotonHit.hh" #include "OptFileManager.hh" #include "SensitiveDetector.hh" #include "G4LogicalBorderSurface.hh" #include "G4RunManager.hh" #include "G4NistManager.hh" #include "G4Box.hh" #include "G4LogicalVolume.hh" #include "G4PVPlacement.hh" #include "G4SystemOfUnits.hh" #include "G4SDManager.hh" #include "G4VisAttributes.hh" #include "G4SubtractionSolid.hh" #include "G4UnionSolid.hh" #include "G4Tubs.hh" #include // Option to switch on/off checking of volumes overlaps G4bool checkOverlaps = true; DetectorConstruction::DetectorConstruction() : G4VUserDetectorConstruction() {} DetectorConstruction::~DetectorConstruction() {} G4VPhysicalVolume* DetectorConstruction::Construct() { // Define World Volume G4double world_size = 1.0 * m; G4Box* solidWorld = new G4Box("World", 0.5 * world_size, 0.5 * world_size, 0.5 * world_size); G4NistManager* nist = G4NistManager::Instance(); G4Material* world_mat = nist->FindOrBuildMaterial("G4_AIR"); G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWorld, world_mat, "World"); G4VPhysicalVolume* physWorld = new G4PVPlacement(0, G4ThreeVector(), logicWorld, "World", 0, false, 0, checkOverlaps); // Define LYSO material G4Element* Lu = new G4Element("Lutetium", "Lu", 71., 174.97 * g / mole); G4Element* Y = new G4Element("Yttrium", "Y", 39., 88.905 * g / mole); G4Element* Si = new G4Element("Silicon", "Si", 14., 28.085 * g / mole); G4Element* O = new G4Element("Oxygen", "O", 8., 16.00 * g / mole); G4Material* LYSO = new G4Material("LYSO", 7.1 * g / cm3, 4); LYSO->AddElement(Lu, 71.43 * perCent); LYSO->AddElement(Y, 4.03 * perCent); LYSO->AddElement(Si, 6.37 * perCent); LYSO->AddElement(O, 18.17 * perCent); G4Material* scint_mat = LYSO; // Define and Place the Scintillator G4double detector_x = 3 * mm; G4double detector_y = 3 * mm; G4double detector_z = 2 * cm; G4Box* solidDetector = new G4Box("Detector", detector_x / 2, detector_y / 2, detector_z / 2); G4LogicalVolume* logicDetector = new G4LogicalVolume(solidDetector, scint_mat, "Detector"); G4VPhysicalVolume* physDetector = new G4PVPlacement(0, G4ThreeVector(), logicDetector, "Detector", logicWorld, false, 0, checkOverlaps); // Visualization G4VisAttributes* DetectorVis = new G4VisAttributes(G4Colour(0.9, 0.9, 0.9)); DetectorVis->SetVisibility(true); DetectorVis->SetForceSolid(true); logicDetector->SetVisAttributes(DetectorVis); // Define and Place the PMT G4double pmt_radius = 1.5 * mm; G4double pmt_thickness = 1 * mm; G4Material* pmt_mat = nist->FindOrBuildMaterial("G4_Al"); G4Tubs* solidPMT = new G4Tubs("PMT", 0., pmt_radius, pmt_thickness / 2, 0., 360. * deg); G4LogicalVolume* logicPMT = new G4LogicalVolume(solidPMT, pmt_mat, "PMT"); // Position the PMT at the end of the scintillator G4ThreeVector pmt_pos(0, 0, detector_z / 2 + pmt_thickness / 2); G4VPhysicalVolume* physPMT = new G4PVPlacement(0, pmt_pos, logicPMT, "PMT", logicWorld, false, 0, checkOverlaps); // Visualization for PMT G4VisAttributes* PMTVis = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0)); PMTVis->SetVisibility(true); PMTVis->SetForceSolid(true); logicPMT->SetVisAttributes(PMTVis); // Sensitive Detector Setup G4SDManager* SD_manager = G4SDManager::GetSDMpointer(); G4String SDModuleName = "/SensitiveDetector"; // Check if the sensitive detector already exists SensitiveDetector* existingSD = dynamic_cast(SD_manager->FindSensitiveDetector(SDModuleName)); if (existingSD) { delete existingSD; } // Create a new sensitive detector G4String photonHitCollectionName = "PhotonHitCollection"; SensitiveDetector* sensitiveModule = new SensitiveDetector(SDModuleName, "HitCollection", photonHitCollectionName); // Add the new sensitive detector to the SD manager SD_manager->AddNewDetector(sensitiveModule); // Set the sensitive detector to the logical volume of the scintillator logicDetector->SetSensitiveDetector(sensitiveModule); // Set the sensitive detector to the PMT as well logicPMT->SetSensitiveDetector(sensitiveModule); // Return the World Volume return physWorld; }