ProcessHits is not being called

_Geant4 Version:_geant4-v11.1.1
_Operating System: CentOS 8
_Compiler/Version: gcc 8.5.0
_CMake Version: 3.20.2


I am having a frustrating time trying to resolve this issue.

The SD::Initialize and SD::EndOfEvent methods are both being called, and tracking (verbosity 2) of neutrons are as expected, but the SD::ProcessHits is not being called.

There is only 1 sensitive detector in my coed, there are no logical volume overlaps as far as I know, and the sensitive detector is attached to the logical volume in the Detector Construction.

I am using the multi-threading version of GEANT.

Any advice would be greatly appreciated!

Do you have any filters attached to the Sensitive Detector? The ProcessHits method is only called if certain preconditions are met, see: source/digits_hits/detector/include/G4VSensitiveDetector.hh · v11.1.1 · geant4 / geant4 · GitLab

If you’ve confirmed that the SD is attached to the correct LV, and the above doesn’t apply, then could you post the code for your sensitive detector please?

I appreciate the quick reply. There are no filters used. Here is my code

GdScintSD::GdScintSD(G4String name, DetectorConstruction* GdSD)  
:G4VSensitiveDetector(name),GdDetector(GdSD)
{
    G4String HCname="GdScintCollection";
    collectionName.insert(HCname);
}

GdScintSD::~GdScintSD()
{ ; }

void GdScintSD::Initialize(G4HCofThisEvent*)
{
    GdScintCollection = new GdScintHitsCollection(SensitiveDetectorName, collectionName[0]);
    HitID = -1;
    verboseLevel=2;
}

G4bool GdScintSD::ProcessHits(G4Step* aStep, G4TouchableHistory*)
{
    GdScintHit* aScintHit = new GdScintHit();
    //Get the Scint hit
    G4TouchableHistory* theTouchable = (G4TouchableHistory*)(aStep->GetPreStepPoint()->GetTouchable());
 
    G4VPhysicalVolume* physVol = theTouchable->GetVolume();
    G4int ScintNumber = 0;
    ScintNumber= physVol->GetCopyNo();
G4double id = G4Threading::G4GetThreadId();
G4double edep = aStep->GetTotalEnergyDeposit();

    aScintHit->SetScintPosition(aStep->GetPostStepPoint()->GetPosition());
    aScintHit->SetScintTime(aStep->GetPostStepPoint()->GetGlobalTime());
    aScintHit->SetScintsTime(aStep->GetPreStepPoint()->GetGlobalTime());
    aScintHit->SetScintParticle(aStep->GetTrack()->GetDefinition()->GetParticleName());
    aScintHit->SetScintEnergy(aStep->GetTrack()->GetKineticEnergy());
    aScintHit->SetScintEdep(aStep->GetTotalEnergyDeposit());
    aScintHit->SetScintParticleType(aStep->GetTrack()->GetDefinition()->GetParticleType());
    aScintHit->SetScintTrackLength(aStep->GetStepLength());
    aScintHit->SetScintMomentum(aStep->GetTrack()->GetMomentum());
    aScintHit->SetScintMomentumDir(aStep->GetTrack()->GetMomentumDirection());
    aScintHit->SetScintVertexVolName(aStep->GetTrack()->GetLogicalVolumeAtVertex()->GetName());
    aScintHit->SetScintTrackID(aStep->GetTrack()->GetTrackID());
    aScintHit->SetScintParentID(aStep->GetTrack()->GetParentID());
    aScintHit->SetScintKineticEnergy(aStep->GetTrack()->GetKineticEnergy());
    aScintHit->SetScintCurrentStepNumber(aStep->GetTrack()->GetCurrentStepNumber());
    aScintHit->SetScintVertexPosition(aStep->GetTrack()->GetVertexPosition());
    aScintHit->SetScintVelocity(aStep->GetTrack()->GetVelocity());
    aScintHit->SetScintVertexMomentumDirection(aStep->GetTrack()->GetVertexMomentumDirection());
    aScintHit->SetScintVertexKineticEnergy(aStep->GetTrack()->GetVertexKineticEnergy());
    aScintHit->SetScintMass(aStep->GetTrack()->GetDynamicParticle()->GetMass());
   
    if (aStep->GetTrack()->GetCreatorProcess()) {
        aScintHit->SetScintNuclearProcess(aStep->GetTrack()->GetCreatorProcess()->GetProcessName());
    } else {
        aScintHit->NoProcess();
    }

    // hit is nuclear recoil
    if ( aStep->GetTrack()->GetCreatorProcess() ) {
        G4String part = aStep->GetTrack()->GetDefinition()->GetParticleType();
        G4String proc = aStep->GetTrack()->GetCreatorProcess()->GetProcessName();
       
        if ( proc ) {
            if ( part == "nucleus" ){
                if ( (proc == "pi+Elastic") || (proc == "pi-Elastic") || (proc == "k+Elastic") || (proc == "k-Elastic") || (proc == "k0LElastic") ||(proc == "k0SElastic") || (proc == "protonElastic") || (proc == "neutronElastic") ) {
                    aScintHit->SetRecoil();
                }
            }
        }        
    }

    // hit is inelastic nuclear recoil
    if( aStep->GetTrack()->GetCreatorProcess() ) {
        G4String part = aStep->GetTrack()->GetDefinition()->GetParticleType();
        G4String proc = aStep->GetTrack()->GetCreatorProcess()->GetProcessName();
       
        if( part != "gamma" ) {
            if( (proc == "pi+Inelastic") || (proc == "pi-Inelastic") || (proc == "k+Inelastic") || (proc == "k-Inelastic") || (proc == "k0LInelastic") ||(proc == "k0SInelastic") || (proc == "protonInelastic") || (proc == "neutronInelastic")){
                aScintHit->SetInelasticRecoil();
            }
        }
    }
HitID = GdScintCollection->insert(aScintHit);
 
   return true;
}

void GdScintSD::EndOfEvent(G4HCofThisEvent* HCE)
{
    G4String HCname = collectionName[0];  
    static G4int HCID = -1;
    if(HCID<0) { HCID = G4SDManager::GetSDMpointer()->GetCollectionID(HCname); }
    HCE->AddHitsCollection(HCID,GdScintCollection);

    G4int nHits = GdScintCollection->entries();
    if (verboseLevel>=1) {
        G4cout << "Number of Scint hits: " << nHits << G4endl;
    }
}

Thanks for the code, and apologies for not replying sooner. I can’t spot anything immediately in the code that might be causing the issue. In the verbose tracking output, are you seeing steps happening in the volume that the SD is attached to?

Is it possible for you to share the application code, or at least a minimum reproducible part of it?

I appreciate the reply. In the verbose tracking output, there are steps in the SD volume. It is a small volume, so there are not many, but they are there.

If you could look at the code, that would be great. Here is the GitHub repo:

I am continuing to troubleshoot the issue. I get the following error message after a track is processed:

“NULL returned from G4StackManager. Terminate current event processing.”

I ran the code without a logical volume assigned to the sensitive detector and the issue persisted. The sensitive detector pointer (myGdScintSD) is also initialized as NULL.

Additionally, there is an issue at line 59 of EventAction.cc (see file in my GitHub in previous reply), the CollectionID is NULL.

Help is greatly appreciated.