#include "DetectorSensitiveDetector.hh" #include "HitOutputManager.hh" #include "WireTrackingManager.hh" #include "G4RunManager.hh" #include "G4Step.hh" #include "G4Track.hh" #include "G4TouchableHistory.hh" #include "G4VPhysicalVolume.hh" #include "G4StepPoint.hh" #include #include namespace { std::string ClassifyDetectorType(const std::string& volumeName) { if (volumeName == "PC_A") { return "Anode"; } if (volumeName == "PC_C") { return "Cathode"; } if (volumeName == "QQQ") { return "QQQ"; } if (volumeName.rfind("SX3", 0) == 0) { return "SX3"; } return volumeName; } } DetectorSensitiveDetector::DetectorSensitiveDetector(const G4String& name) : G4VSensitiveDetector(name) {} DetectorSensitiveDetector::~DetectorSensitiveDetector() {} G4bool DetectorSensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory*) { if (step == nullptr) { return false; } G4StepPoint* preStepPoint = step->GetPreStepPoint(); if (preStepPoint == nullptr) { return false; } G4VPhysicalVolume* volume = preStepPoint->GetPhysicalVolume(); if (volume == nullptr) { return false; } const G4double kineticEnergy = preStepPoint->GetKineticEnergy(); const G4double energyDeposit = step->GetTotalEnergyDeposit(); if (kineticEnergy <= 0.0 && energyDeposit <= 0.0) { return false; } const G4Event* currentEvent = G4RunManager::GetRunManager()->GetCurrentEvent(); if (currentEvent == nullptr) { return false; } const std::string particleName = step->GetTrack()->GetParticleDefinition()->GetParticleName(); if (!HitOutputManager::Instance().ShouldRecordParticle(particleName)) { return false; } const std::string volumeName = volume->GetName(); const std::string detectorType = ClassifyDetectorType(volumeName); if (detectorType != "SX3" && detectorType != "QQQ") { return false; } WireCrossingInfo wireInfo; WireTrackingManager::Instance().GetInfo(currentEvent->GetEventID(), step->GetTrack()->GetTrackID(), wireInfo); if (wireInfo.anodeId < 0 || wireInfo.cathodeId < 0) { wireInfo = WireTrackingManager::Instance().InferFromTrackGeometry(step->GetTrack(), preStepPoint); } const G4ThreeVector trackDirection = step->GetTrack()->GetMomentumDirection(); const double sinThetaZ = std::sin(trackDirection.theta()); const double wireDeltaESinTheta = wireInfo.deltaE * sinThetaZ; HitOutputManager::Instance().RecordHit(currentEvent->GetEventID(), particleName, kineticEnergy, energyDeposit, wireDeltaESinTheta, detectorType, volume->GetCopyNo(), wireInfo.anodeId, wireInfo.cathodeId, wireInfo.anodeEnergy, wireInfo.cathodeEnergy, wireInfo.deltaE, volumeName, preStepPoint->GetPosition(), step->GetTrack()->GetVertexPosition()); return true; }