ANASEN_analysis/Armory/AnasenG4/src/DetectorSensitiveDetector.cc
2026-07-17 16:10:00 -04:00

106 lines
3.3 KiB
C++

#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 <cmath>
#include <string>
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;
}