Segmentation fault when trying to create histogram

Hi there,
I am hoping some one could help.
I have a very simple setup which consists of a single sensitive silcon detector. I want to generate a histogram which shows the kinetic energy of the Compton scattered photon in the detector vs counts. I’ve tried all sorts of ways trying to generate this histogram but without success.

The quantity I want to histogram is called “m_KinEnergyFinal” which can be found in the “HitCPET04.hh” file (see below). i.e. m_KinEnergyFinal( aStep->GetTrack()->GetVertexKineticEnergy() )

However, when I compile the program I receive the following error message
5933 Segmentation fault (core dumped)
which I do not know how to problem solve.

I am new to geant4. I have used a slide presentation to write the code to generate the histogram but the information provided in these slides are incomplete and I have had to get the rest of the information from the example codes provided by GEANT4.

For your convenience, below I have also copied and pasted my
RunAction .cc and .hh files called (RunActionCPET04.cc and RunActionCPET04.hh)
Hit .cc and .hh files called (HitCPET04.cc HitCPET04.hh)
SD .cc and .hh files called (SensitiveDetectorCPET04.cc and SensitiveDetectorCPET04.hh)
EventAction.hh and .cc files (EventActionCPET04.cc and EventActionCPET04.hh)

Thank you for taking the time to consider my request.

(RunActionCPET04.cc file)
#include “RunActionCPET04.hh”
#include “G4RunManager.hh”
#include “AnalysisCPET04.hh”
#include “G4Run.hh”
#include “G4SystemOfUnits.hh”

void RunActionCPET04::BeginOfRunAction(const G4Run* aRun){
G4cout << “==== Starting of Run =====\n”;
G4cout
<< “Run number "
<< aRun->GetRunID() << " with "
<< aRun->GetNumberOfEventToBeProcessed()
<< " events to be processed.\n”;

// Get analysis manager
G4AnalysisManager* man = G4AnalysisManager::Instance();
// man-> SetFirstNtupleId(1);

man->SetVerboseLevel(1);
man->SetFirstHistoId(1);
// Creating histograms
man->CreateH1("h","Kinetic Energy", 100, 100, 450*keV);
// Open an output file
man->OpenFile("CPET04");

}

void RunActionCPET04::EndOfRunAction(const G4Run* aRun){
G4AnalysisManager* man = G4AnalysisManager::Instance();
man->Write();
man->CloseFile();
G4cout
<< “==== End of Run ====\n”
<< "HCtables = "
<< aRun->GetHCtable()
<< G4endl;
}
RunActionCPET04::~RunActionCPET04(){
delete G4AnalysisManager::Instance();
}


(RunActionCPET04.hh file)
#ifndef RunActionCPET04_h
#define RunActionCPET04_h 1
#include “G4UserRunAction.hh”
class RunActionCPET04 : public G4UserRunAction{
public:
//RunActionCPET04();
void BeginOfRunAction(const G4Run* aRun) override;
void EndOfRunAction(const G4Run* aRun) override;
virtual ~RunActionCPET04();
};
#endif



(HitCPET04.cc file)
#include “HitCPET04.hh”
#include “G4Step.hh”
#include “G4UnitsTable.hh”
#include “G4VVisManager.hh”
#include “G4Circle.hh”
#include “G4Colour.hh”
#include “G4VisAttributes.hh”
#include “iomanip”
// G4ThreadLocal G4Allocator* CPET04HitAllocator = 0;

HitCPET04::HitCPET04(G4Step* aStep) :
m_TrackID( aStep->GetTrack()->GetTrackID() ),
m_VertexPosition( aStep->GetTrack()->GetVertexPosition() ),
m_ParticleName( aStep->GetTrack()->GetParticleDefinition()->GetParticleName() ),
m_KinEnergyFinal( aStep->GetTrack()->GetVertexKineticEnergy() )
{ }

HitCPET04::~HitCPET04() {}

void HitCPET04::Print()
{
G4cout
<< "TrackID: " << m_TrackID << std::setw(20)
<< " Vertex Position: " << m_VertexPosition << std::setw(15)
<< " Scattered Particle: " << m_ParticleName << std::setw(15)
<< " Photon Final Kinetic Energy: " << G4BestUnit(m_KinEnergyFinal,“Energy”)
<< G4endl;
}


(HitCPET04.hh file)
#ifndef HitCPET04_h
#define HitCPET04_h 1
#include “G4VHit.hh”
#include “G4THitsCollection.hh”
#include “G4Step.hh”
#include “G4ThreeVector.hh”

class HitCPET04: public G4VHit{
public:
HitCPET04( G4Step* aStep );
virtual ~HitCPET04();
/* // operators
inline void* operator new(size_t);
inline void operator delete(void*); */

// methods from base class
virtual void Draw() {}
void Print() override;

inline G4int GetTrackID() { return m_TrackID; }
inline G4ThreeVector GetVertexPosition() { return m_VertexPosition; }
inline G4String GetParticleName() { return m_ParticleName; }
inline G4double GetKineticEnergy() { return m_KinEnergyFinal; }

private:
G4int m_TrackID;
G4ThreeVector m_VertexPosition;
G4String m_ParticleName;
G4double m_KinEnergyFinal;
};
using HitsCollectionCPET04 = G4THitsCollection;
#endif



(SensitiveDetectorCPET04.cc file)
#include “SensitiveDetectorCPET04.hh”
#include “HitCPET04.hh”

#include “G4Step.hh”
#include “G4ThreeVector.hh”
#include “G4SDManager.hh”
#include “G4ios.hh”
#include “G4UnitsTable.hh”
SensitiveDetectorCPET04::SensitiveDetectorCPET04(const G4String &name)
: G4VSensitiveDetector(name),
collectionID(-1)
{
collectionName.insert(“collection_name”);
}
SensitiveDetectorCPET04::~SensitiveDetectorCPET04()
{ }
void SensitiveDetectorCPET04::Initialize(G4HCofThisEvent* HCE)
{
if(collectionID<0)
collectionID = GetCollectionID(0);
hitsCollection = new HitsCollectionCPET04(SensitiveDetectorName, collectionName[0]);
HCE->AddHitsCollection(collectionID,hitsCollection);
}
G4bool SensitiveDetectorCPET04::ProcessHits(G4Step* aStep, G4TouchableHistory* ROhist){
// This line used to silence error about ‘thist not used’
G4cout << "ROhist = "<< ROhist << G4endl;

if(    aStep->GetTrack()->GetVertexKineticEnergy() < 0.511
    && aStep->GetTrack()->GetTrackID()>1
    && (aStep->GetTrack()->GetParticleDefinition()->GetParticleName()=="e-"
    || aStep->GetTrack()->GetParticleDefinition()->GetParticleName()=="gamma"))
{
   auto hit = new HitCPET04(0);
    //G4double kineticEnergy = aStep->GetTrack()->GetVertexKineticEnergy();
    hitsCollection->insert(hit);
    hit->Print();
    delete hit;   
};
 return true;

}
void SensitiveDetectorCPET04::EndOfEvent(G4HCofThisEvent* HCE)
{}


(SensitiveDetectorCPET04.hh file)
#ifndef SensitiveDetectorCPET04_h
#define SensitiveDetectorCPET04_h 1

#include “G4VSensitiveDetector.hh”
#include “HitCPET04.hh”
#include
class G4Step;
class G4HCofThisEvent;
class SensitiveDetectorCPET04: public G4VSensitiveDetector
{
public:
SensitiveDetectorCPET04(const G4String &name);
virtual ~SensitiveDetectorCPET04();

// methods from base class
virtual void Initialize(G4HCofThisEvent* HCE);
virtual G4bool ProcessHits(G4Step* aStep, G4TouchableHistory* ROhist) override;
virtual void EndOfEvent(G4HCofThisEvent* HCE);

private:
HitsCollectionCPET04* hitsCollection;
G4int collectionID;
};
#endif



(EventActionCPET04.cc file)

#include “EventActionCPET04.hh”
#include “SensitiveDetectorCPET04.hh”
#include “HitCPET04.hh”
#include “AnalysisCPET04.hh”

#include “G4RunManager.hh”
// #include “G4Run.hh”
#include “G4Event.hh”
#include “G4EventManager.hh”
#include “G4HCofThisEvent.hh”
#include “G4VHitsCollection.hh”
#include “G4SDManager.hh”
#include “G4SystemOfUnits.hh”
#include “G4ios.hh”
// #include “Randomize.hh”
using std::array;
using std::vector;
#include

void EventActionCPET04::BeginOfEventAction(const G4Event* anEvent){
G4cout << "\t Starting Event " << anEvent->GetEventID() << G4endl;
}
void EventActionCPET04::EndOfEventAction(const G4Event* anEvent){
// Get analysis manager
auto man = G4AnalysisManager::Instance();
if(SiHCID<0) SiHCID =
G4SDManager::GetSDMpointer()->GetCollectionID(“SiliconHitsCollection”);
G4HCofThisEvent* HCE = anEvent->GetHCofThisEvent();

HitsCollectionCPET04* hitsColl = 0;
if(HCE) hitsColl = (HitsCollectionCPET04*) (HCE->GetHC(SiHCID));
if(hitsColl)
{
    G4int numberOfHits = hitsColl->entries();        
    for(G4int il = 0; il<numberOfHits; il++)
    {
        HitCPET04* hit = (*hitsColl)[il];
        G4double kineticEnergy = hit->GetKineticEnergy();
        man->FillNtupleDColumn(1, 0,kineticEnergy);
    }
}
G4cout << "\t End of Event " << anEvent->GetNumberOfPrimaryVertex() << G4endl;

}


(EventActionCPET04.hh file)
#ifndef EventActionCPET04_h
#define EventActionCPET04_h 1
#include “G4UserEventAction.hh”
#include “globals.hh”
class EventActionCPET04 : public G4UserEventAction{
public:
void BeginOfEventAction(const G4Event* anEvent) override;
void EndOfEventAction(const G4Event* anEvent) override;
private:
// data members
G4int SiHCID;
};
#endif


Please have a look at the documentation on the analysis:
http://geant4-userdoc.web.cern.ch/geant4-userdoc/UsersGuides/ForApplicationDeveloper/html/Analysis/managers.html#histograms
It looks like you are creating a histogram in the run action, but in the event action you attempt to fill an ntuple, not a histogram:
http://geant4-userdoc.web.cern.ch/geant4-userdoc/UsersGuides/ForApplicationDeveloper/html/Analysis/managers.html#ntuples

Dear Anna,

Thank you for the tips. I have solved this issue by making the following changes to my code.


In my RunAction.cc files I wrote

RunActionCPET03::RunActionCPET03() : G4UserRunAction()
{
// book histograms, ntuple
// create analysis manager the choice of analysis technology is done
// via selection of a namespace in Analysis.hh
G4cout << "##### Create analysis manager " << " " << this << G4endl;
auto analysisManager = G4AnalysisManager::Instance();
analysisManager->SetNtupleMerging(true);
G4cout << “Using " << analysisManager->GetType()
<< " analysis manager” << G4endl;
// create directories
analysisManager->SetVerboseLevel(1);
// Create ntuples.
// Ntuples ids are generated automatically starting from 0.
// The start value can be changed by:
// analysisManager->SetFirstMtupleId(1);

// Create 1st ntuple (id = 0)
analysisManager->CreateNtuple("Ntuple", "Kinetic Energy and Scattering Angle");
analysisManager->CreateNtupleDColumn("KineticEnergy");    // column Id = 0
analysisManager->CreateNtupleDColumn("Theta");            // column Id = 1
analysisManager->CreateNtupleDColumn("trackID");          // column Id = 2
analysisManager->CreateNtupleDColumn("nbHits");           // column Id = 3
//
// (These Ntuples are filled in SensitiveDetectorCPET03.cc)
//
analysisManager->FinishNtuple();                          

}


In my SensitiveDetector.cc I wrote
G4bool SensitiveDetectorCPET03::ProcessHits(G4Step* aStep, G4TouchableHistory*)
{
G4double TrackID = aStep->GetTrack()->GetTrackID();
G4String ParticleName = aStep->GetTrack()->GetParticleDefinition()->GetParticleName();
G4double KineticEnergy = aStep->GetPostStepPoint()->GetKineticEnergy();
G4ThreeVector pos = aStep->GetPostStepPoint()->GetPosition();
if (KineticEnergy == 0.511) return false;
HitCPET03* newHit = new HitCPET03();

if( KineticEnergy < 0.511 && TrackID == 2)
// if( KineticEnergy < 0.511)
    {
        fHitsCollection->insert( newHit );
        // get analysis manager
        auto analysisManager = G4AnalysisManager::Instance();

        G4double En = KineticEnergy/keV;
        G4double theta = acos( 2- 511/En );        
        // fill ntuple
        analysisManager->FillNtupleDColumn(0, KineticEnergy/keV); 
        analysisManager->FillNtupleDColumn(1, theta/deg); 
        analysisManager->FillNtupleDColumn(2, TrackID);

        analysisManager->AddNtupleRow(0); 
    } 
          
return true;

}

void SensitiveDetectorCPET03::EndOfEvent(G4HCofThisEvent*)
{
G4int nofHits = fHitsCollection->entries();
// get analysis manager
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();

analysisManager->FillNtupleDColumn(3, nofHits);

}

And this seems to produce the Ntuples which I can then analysis.

Best regards
Peter