#include "G4Material.hh" #include "G4Box.hh" #include "G4LogicalVolume.hh" #include "G4PVPlacement.hh" #include "G4NistManager.hh" #include "G4SystemOfUnits.hh" #include "G4VisAttributes.hh" #include "G4VUserDetectorConstruction.hh" #include "G4SDManager.hh" #include "G4MultiFunctionalDetector.hh" #include "G4PSEnergyDeposit.hh" #include "G4PSPassageTrackLength.hh" #include namespace B4c { class DetectorConstruction : public G4VUserDetectorConstruction { public: DetectorConstruction(); virtual ~DetectorConstruction(); virtual G4VPhysicalVolume* Construct(); virtual void ConstructSDandField(); private: G4LogicalVolume* logicSilicon; // Make logicSilicon a member variable G4LogicalVolume* logicVacuum; // Make logicVacuum a member variable }; DetectorConstruction::DetectorConstruction() : logicSilicon(nullptr), logicVacuum(nullptr) {} DetectorConstruction::~DetectorConstruction() {} G4VPhysicalVolume* DetectorConstruction::Construct() { // Get materials from NIST manager G4NistManager* nist = G4NistManager::Instance(); G4Material* silicon = nist->FindOrBuildMaterial("G4_Si"); G4Material* vacuum = nist->FindOrBuildMaterial("G4_Galactic"); // World volume G4double world_sizeXYZ = 1.0 * m; G4Material* world_mat = nist->FindOrBuildMaterial("G4_AIR"); G4Box* solidWorld = new G4Box("World", 0.5 * world_sizeXYZ, 0.5 * world_sizeXYZ, 0.5 * world_sizeXYZ); G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWorld, world_mat, "World"); G4VPhysicalVolume* physWorld = new G4PVPlacement(0, G4ThreeVector(), logicWorld, "World", 0, false, 0, true); // Define Silicon Box (Absorber) (placed to the left of the origin) G4double siliconBoxX = 10.0 * mm; G4double siliconBoxY = 10.0 * mm; G4double siliconBoxZ = 0.3 * mm; G4Box* solidSilicon = new G4Box("SiliconBox", 0.5 * siliconBoxX, 0.5 * siliconBoxY, 0.5 * siliconBoxZ); logicSilicon = new G4LogicalVolume(solidSilicon, silicon, "SiliconBox"); new G4PVPlacement(0, G4ThreeVector(0, 0, -10 * mm), logicSilicon, "SiliconBox", logicWorld, false, 0, true); // Define Vacuum Box (Gap) (placed to the right of the origin) G4Box* solidVacuum = new G4Box("VacuumBox", 0.5 * siliconBoxX, 0.5 * siliconBoxY, 0.5 * siliconBoxZ); logicVacuum = new G4LogicalVolume(solidVacuum, vacuum, "VacuumBox"); new G4PVPlacement(0, G4ThreeVector(0, 0, 10 * mm), logicVacuum, "VacuumBox", logicWorld, false, 0, true); // Visualization attributes G4VisAttributes* siliconVisAttr = new G4VisAttributes(G4Colour(1.0, 0.0, 0.0)); // Red logicSilicon->SetVisAttributes(siliconVisAttr); G4VisAttributes* vacuumVisAttr = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0)); // Green logicVacuum->SetVisAttributes(vacuumVisAttr); // Construct sensitive detectors and fields (centralized initialization) std::cout << "Calling ConstructSDandField() from Construct()" << std::endl; ConstructSDandField(); return physWorld; } void DetectorConstruction::ConstructSDandField() { std::cout << "ConstructSDandField() called" << std::endl; // Sensitive Detector for Silicon Box (AbsorberHitsCollection) G4SDManager* sdManager = G4SDManager::GetSDMpointer(); G4String absorberSDName = "AbsorberHitsCollection"; G4MultiFunctionalDetector* absorberDetector = new G4MultiFunctionalDetector(absorberSDName); sdManager->AddNewDetector(absorberDetector); if (logicSilicon) { logicSilicon->SetSensitiveDetector(absorberDetector); std::cout << "Sensitive detector for Silicon attached successfully." << std::endl; } else { std::cerr << "Error: logicSilicon is null, cannot attach sensitive detector." << std::endl; } // Energy Deposit and Track Length Scorers for Absorber G4PSEnergyDeposit* energyDeposit = new G4PSEnergyDeposit("Edep"); absorberDetector->RegisterPrimitive(energyDeposit); std::cout << "Energy deposit primitive registered for Absorber." << std::endl; G4PSPassageTrackLength* trackLength = new G4PSPassageTrackLength("TrackLength"); absorberDetector->RegisterPrimitive(trackLength); std::cout << "Track length primitive registered for Absorber." << std::endl; } } // namespace B4c