Compare commits

...

3 commits

Author SHA1 Message Date
Ava
f003c1697a clean detectorname 2025-12-01 13:00:40 +01:00
Ava
22a080911f sort outfile 2025-12-01 12:54:53 +01:00
Ava
f193790483 external filename 2025-12-01 12:19:23 +01:00
11 changed files with 201 additions and 121 deletions

View file

@ -5,15 +5,19 @@ project(Tutorial)
find_package(Geant4 REQUIRED ui_all vis_all)
include(${Geant4_USE_FILE})
include_directories(${PROJECT_SOURCE_DIR}/include)
# Sammle alle .cc Dateien
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
# Entferne unerwünschte Dateien
list(REMOVE_ITEM sources ${PROJECT_SOURCE_DIR}/src/ADetectorConstructionv2.cc)
list(REMOVE_ITEM sources ${PROJECT_SOURCE_DIR}/src/ASensitiveDetectorv2.cc)
list(REMOVE_ITEM sources ${PROJECT_SOURCE_DIR}/src/ARunMessenger.cc)
list(REMOVE_ITEM sources ${PROJECT_SOURCE_DIR}/src/ARunActionv2.cc)
file(GLOB MACRO_FILES "macros/*.mac")
file(COPY ${MACRO_FILES} DESTINATION ${CMAKE_BINARY_DIR}/)
add_executable(sim sim.cc ${sources})
target_link_libraries(sim ${Geant4_LIBRARIES})
add_custom_target(Tutorial DEPENDS sim)

View file

@ -1,18 +1,16 @@
#ifndef AACTIONINITIALIZATION_HH
#define AACTIONINITIALIZATION_HH
#ifndef AACTIONINITIALIZATION_H
#define AACTIONINITIALIZATION_H
#include "G4VUserActionInitialization.hh"
#include "APrimaryGenerator.hh"
#include "ARunAction.hh"
class AActionInitialization : public G4VUserActionInitialization
{
public:
AActionInitialization();
~AActionInitialization();
virtual void BuildForMaster() const;
virtual void Build() const;
virtual ~AActionInitialization();
virtual void Build() const override;
virtual void BuildForMaster() const override;
};
#endif
#endif

View file

@ -3,7 +3,6 @@
#include "G4VUserDetectorConstruction.hh"
#include "G4UImessenger.hh"
#include "G4Cache.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
@ -20,30 +19,24 @@
#include "G4SDManager.hh"
#include "ASensitiveDetector.hh"
#include "G4UImessenger.hh"
#include "G4Cache.hh"
#include "G4UImessenger.hh"
#include "G4Cache.hh"
#include "AMessenger.hh"
#include <vector>
//#include "G4GDMLParser.hh"
class ADetectorConstruction : public G4VUserDetectorConstruction, public G4UImessenger
class ADetectorConstruction : public G4VUserDetectorConstruction
{
public:
ADetectorConstruction();
virtual ~ADetectorConstruction();
virtual G4VPhysicalVolume *Construct();
virtual G4VPhysicalVolume* Construct();
void ConstructSDandField();
private:
std::vector<G4LogicalVolume*> detectorVolumes;
// Hier fSD als Member speichern
ASensitiveDetector* fSD;
};
#endif

22
include/AMessenger.hh Normal file
View file

@ -0,0 +1,22 @@
#ifndef AMESSENGER_HH
#define AMESSENGER_HH
#include "G4UImessenger.hh"
#include "G4UIcmdWithAString.hh"
class ASensitiveDetector;
class AMessenger : public G4UImessenger
{
public:
AMessenger(ASensitiveDetector* sd);
~AMessenger();
virtual void SetNewValue(G4UIcommand* cmd, G4String value) override;
private:
ASensitiveDetector* fSD;
G4UIcmdWithAString* fOutputFileCmd;
};
#endif

View file

@ -8,10 +8,14 @@
#include "G4Track.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
#include "G4UImessenger.hh"
#include "G4UIcmdWithAString.hh"
#include <unordered_map>
#include <fstream>
class AMessenger;
class ASensitiveDetector : public G4VSensitiveDetector
{
public:
@ -21,8 +25,17 @@ public:
virtual void Initialize(G4HCofThisEvent* hce) override;
virtual void EndOfEvent(G4HCofThisEvent* hce) override;
virtual G4bool ProcessHits(G4Step* step, G4TouchableHistory* touchHist) override;
//Filename
void SetOutputFilename(const G4String& name) { fOutputFilename = name; }
void SetMessenger(AMessenger* messenger) { fMessenger = messenger; }
void RegisterVolumeName(G4LogicalVolume* lv, const std::string& cleanName) {
fCleanNames[lv] = cleanName;}
private:
AMessenger* fMessenger = nullptr; // jetzt optional
G4String fOutputFilename = "outfiles/shower_setup.txt";
G4int fCurrentEventID = -1; // speichert die aktuelle Event-ID
struct HitInfo {
G4int eventID;
G4int trackID;
@ -33,13 +46,16 @@ private:
G4double primaryEnergy;
G4double energyDeposited;
G4String detectorName;
G4String cleanDetectorName;
HitInfo()
: trackID(-1), parentID(-1), particleEnergy(0.), primaryEnergy(0.), energyDeposited(0.) {}
};
G4String fDetectorName;
std::unordered_map<G4LogicalVolume*, std::string> fCleanNames;
std::unordered_map<G4int, HitInfo> fTrackHitMap; // TrackID → HitInfo
};
#endif

66
sim.cc
View file

@ -1,7 +1,4 @@
//Including header files
#include <iostream>
// Including Geant4 stuff, G4MT is for multithreading
#include "G4RunManager.hh"
#include "G4MTRunManager.hh"
#include "G4UImanager.hh"
@ -15,52 +12,49 @@
int main(int argc, char** argv)
{
//G4UIExecutive *ui = new G4UIExecutive(argc, argv);
G4UIExecutive *ui = 0;
if (argc == 1)
{
ui = new G4UIExecutive(argc, argv);
}
#ifdef G4MULTITHREADED
G4MTRunManager *runManager = new G4MTRunManager;
#else
G4RunManager *runManager = new G4RunManager;
#endif
// Physics list
runManager->SetUserInitialization(static_cast<G4VUserPhysicsList*>(new APhysicsList()));
// Detector Construction
runManager->SetUserInitialization(static_cast<G4VUserDetectorConstruction*>(new ADetectorConstruction()));
// Action initialization
runManager->SetUserInitialization(static_cast<G4VUserActionInitialization*>(new AActionInitialization()));
// UI
G4UIExecutive* ui = nullptr;
if (argc == 1) ui = new G4UIExecutive(argc, argv);
G4VisManager *visManager = new G4VisExecutive();
#ifdef G4MULTITHREADED
G4MTRunManager* runManager = new G4MTRunManager;
#else
G4RunManager* runManager = new G4RunManager;
#endif
// Physics
runManager->SetUserInitialization(new APhysicsList());
// Detector
runManager->SetUserInitialization(new ADetectorConstruction());
// Actions
runManager->SetUserInitialization(new AActionInitialization());
// Visualization
G4VisManager* visManager = new G4VisExecutive();
visManager->Initialize();
G4UImanager *UImanager = G4UImanager::GetUIpointer();
// UI manager
G4UImanager* UImanager = G4UImanager::GetUIpointer();
if (ui)
{
G4cout << "ui exists" << G4endl;
G4cout << "UI exists" << G4endl;
UImanager->ApplyCommand("/control/execute vis.mac");
ui->SessionStart();
ui->SessionStart();
}
else
{
G4cout << "ui does not exists" << G4endl;
G4String command = "/control/execute ";
G4String fileName = argv[1];
UImanager->ApplyCommand(command + fileName);
}
//clean up
// Clean up
delete runManager;
delete visManager;
if (ui) delete ui;
return 0;
}
}

View file

@ -1,40 +1,24 @@
#include "AActionInitialization.hh"
//#include "PrimaryGeneratorAction.hh"
#include "APrimaryGenerator.hh"
#include "ARunAction.hh"
AActionInitialization::AActionInitialization()
: G4VUserActionInitialization()
{
}
AActionInitialization::~AActionInitialization()
AActionInitialization::~AActionInitialization() {}
void AActionInitialization::Build() const
{
// Primärgenerator
SetUserAction(new APrimaryGenerator());
// RunAction
SetUserAction(new ARunAction());
}
void AActionInitialization::BuildForMaster() const
{
// This is needed to avoid problems due to multithreading when writing the data.
ARunAction *runAction = new ARunAction();
SetUserAction(runAction);
SetUserAction(new ARunAction());
}
void AActionInitialization::Build() const
{
// PrimaryGenerator and SteppingAction do not have to be set in BuildForMaster because they only
// regard individual threads.
APrimaryGenerator *generator = new APrimaryGenerator();
SetUserAction(generator);
ARunAction *runAction = new ARunAction();
SetUserAction(runAction);
// SteppingAction *steppingAction = new SteppingAction();
// SetUserAction(steppingAction);
}
// void UserActionInitialization::Build() const {
// SetUserAction(new PrimaryGeneratorAction);
// }
//
// void UserActionInitialization::BuildForMaster() const {
// }

View file

@ -1,5 +1,6 @@
#include "ADetectorConstruction.hh"
#include "ASensitiveDetector.hh"
#include "AMessenger.hh"
#include "G4Box.hh"
#include "G4PVPlacement.hh"
@ -10,9 +11,20 @@
#include "G4SDManager.hh"
#include "G4SystemOfUnits.hh"
ADetectorConstruction::ADetectorConstruction() {}
ADetectorConstruction::ADetectorConstruction()
{
//Ein einziges SensitiveDetector erzeugen
fSD = new ASensitiveDetector("shower_setup");
ADetectorConstruction::~ADetectorConstruction() {}
//Messenger für den SD erzeugen
AMessenger* messenger = new AMessenger(fSD);
fSD->SetMessenger(messenger);
}
ADetectorConstruction::~ADetectorConstruction()
{
delete fSD; // SD + Messenger werden hier aufgeräumt
}
G4VPhysicalVolume* ADetectorConstruction::Construct()
{
@ -93,15 +105,12 @@ G4VPhysicalVolume* ADetectorConstruction::Construct()
// --- SensitiveDetector zuweisen ---
void ADetectorConstruction::ConstructSDandField()
{
// Ein einziger SensitiveDetector für alle Layer
G4String sdName = "shower_setup";
ASensitiveDetector* sd = new ASensitiveDetector(sdName);
G4SDManager::GetSDMpointer()->AddNewDetector(sd);
// SD bei Geant4 registrieren
G4SDManager::GetSDMpointer()->AddNewDetector(fSD);
// Alle Layer bekommen denselben SD
for(auto lv : detectorVolumes)
{
lv->SetSensitiveDetector(sd);
lv->SetSensitiveDetector(fSD);
}
}

24
src/AMessenger.cc Normal file
View file

@ -0,0 +1,24 @@
#include "AMessenger.hh"
#include "ASensitiveDetector.hh"
AMessenger::AMessenger(ASensitiveDetector* sd)
: fSD(sd)
{
// eigenes UI Kommando
fOutputFileCmd = new G4UIcmdWithAString("/my/outputFilename", this);
fOutputFileCmd->SetGuidance("Set output filename for SD text output.");
fOutputFileCmd->SetParameterName("filename", false);
}
AMessenger::~AMessenger()
{
delete fOutputFileCmd;
}
void AMessenger::SetNewValue(G4UIcommand* cmd, G4String value)
{
if (cmd == fOutputFileCmd)
{
fSD->SetOutputFilename(value);
}
}

View file

@ -31,7 +31,7 @@ void ARunAction::BeginOfRunAction(const G4Run *run)
std::stringstream strRunID;
strRunID << runID;
//analysisManager->OpenFile("output" + strRunID.str() + ".root");
analysisManager->OpenFile("output" + strRunID.str() + ".root");
}
void ARunAction::EndOfRunAction(const G4Run *run)

View file

@ -1,4 +1,5 @@
#include "ASensitiveDetector.hh"
#include "AMessenger.hh"
#include "G4RunManager.hh"
#include "G4Event.hh"
#include "G4PrimaryVertex.hh"
@ -10,9 +11,14 @@
ASensitiveDetector::ASensitiveDetector(G4String name)
: G4VSensitiveDetector(name), fDetectorName(name)
{
fOutputFilename = "outfiles/shower_setup.txt";
std::filesystem::create_directories("outfiles");
}
ASensitiveDetector::~ASensitiveDetector() {}
ASensitiveDetector::~ASensitiveDetector()
{
}
void ASensitiveDetector::Initialize(G4HCofThisEvent* /*hce*/)
{
@ -22,6 +28,12 @@ void ASensitiveDetector::Initialize(G4HCofThisEvent* /*hce*/)
G4bool ASensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory* /*touchHist*/)
{
const G4Event* event = G4RunManager::GetRunManager()->GetCurrentEvent();
if (!event) return false;
// Event-ID direkt hier setzen
fCurrentEventID = event->GetEventID();
G4Track* track = step->GetTrack();
G4int trackID = track->GetTrackID();
@ -29,26 +41,26 @@ G4bool ASensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory* /*touch
if (it == fTrackHitMap.end())
{
HitInfo hit;
hit.eventID = event->GetEventID();
hit.eventID = fCurrentEventID;
hit.trackID = trackID;
hit.parentID = track->GetParentID();
hit.particleName = track->GetDefinition()->GetParticleName();
hit.particleEnergy = track->GetVertexKineticEnergy();
hit.detectorName = step->GetPreStepPoint()->GetTouchable()->GetVolume()->GetName();
std::string detNameStr = hit.detectorName;
size_t pos = detNameStr.find("_phys");
if (pos != std::string::npos)
detNameStr = detNameStr.substr(0, pos); // nur Basisname
hit.cleanDetectorName = detNameStr;
// Primary particle info
const G4Event* event = G4RunManager::GetRunManager()->GetCurrentEvent();
if (event)
G4PrimaryVertex* pv = event->GetPrimaryVertex();
if (pv)
{
G4PrimaryVertex* pv = event->GetPrimaryVertex();
if (pv)
{
G4PrimaryParticle* pp = pv->GetPrimary();
if (pp && pp->GetG4code())
hit.primaryParticleName = pp->GetG4code()->GetParticleName();
if (pp)
hit.primaryEnergy = pp->GetKineticEnergy();
}
G4PrimaryParticle* pp = pv->GetPrimary();
if (pp && pp->GetG4code())
hit.primaryParticleName = pp->GetG4code()->GetParticleName();
if (pp)
hit.primaryEnergy = pp->GetKineticEnergy();
}
hit.energyDeposited = step->GetTotalEnergyDeposit();
@ -62,22 +74,39 @@ G4bool ASensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory* /*touch
return true;
}
void ASensitiveDetector::EndOfEvent(G4HCofThisEvent* /*hce*/)
{
if (fOutputFilename.empty()) fOutputFilename = "outfiles/shower_setup.txt";
std::filesystem::create_directories("outfiles");
std::string filename = "outfiles/shower_setup.txt";
std::ofstream out(filename, std::ios::app);
if (!out.is_open())
{
G4cerr << "Cannot open file " << filename << "!" << G4endl;
std::ofstream out(fOutputFilename, std::ios::app);
if (!out.is_open()) {
G4cerr << "Cannot open file " << fOutputFilename << "!" << G4endl;
return;
}
out << "eventID\ttrackID\tparantID\tparticle\tEpart\tPrimparticle\tEprim\tDname\tEdep";
out << "\n";
static bool headerWritten = false;
if (!headerWritten) {
out << "eventID\ttrackID\tparentID\tparticle\tEpart\tPrimparticle\tEprim\tDname\tEdep\n";
headerWritten = true;
}
for (const auto& [trackID, hit] : fTrackHitMap)
// Hits nur für das aktuelle Event
std::vector<HitInfo> hits;
for (const auto& [trackID, hit] : fTrackHitMap) {
hits.push_back(hit);
}
// Sortieren: parentID -> trackID
std::sort(hits.begin(), hits.end(), [](const HitInfo& a, const HitInfo& b) {
if (a.parentID != b.parentID)
return a.parentID < b.parentID;
return a.trackID < b.trackID;
});
// Schreiben
for (const auto& hit : hits)
{
out << hit.eventID
<< "\t" << hit.trackID
@ -86,10 +115,17 @@ void ASensitiveDetector::EndOfEvent(G4HCofThisEvent* /*hce*/)
<< "\t" << hit.particleEnergy / MeV
<< "\t" << hit.primaryParticleName
<< "\t" << hit.primaryEnergy / MeV
<< "\t" << hit.detectorName
<< "\t" << hit.cleanDetectorName
<< "\t" << hit.energyDeposited / MeV
<< "\n";
}
out.close();
// Map leeren für nächstes Event
fTrackHitMap.clear();
}