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) find_package(Geant4 REQUIRED ui_all vis_all)
include(${Geant4_USE_FILE}) include(${Geant4_USE_FILE})
include_directories(${PROJECT_SOURCE_DIR}/include) include_directories(${PROJECT_SOURCE_DIR}/include)
# Sammle alle .cc Dateien
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc) 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(GLOB MACRO_FILES "macros/*.mac")
file(COPY ${MACRO_FILES} DESTINATION ${CMAKE_BINARY_DIR}/) file(COPY ${MACRO_FILES} DESTINATION ${CMAKE_BINARY_DIR}/)
add_executable(sim sim.cc ${sources}) add_executable(sim sim.cc ${sources})
target_link_libraries(sim ${Geant4_LIBRARIES}) target_link_libraries(sim ${Geant4_LIBRARIES})
add_custom_target(Tutorial DEPENDS sim)

View file

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

View file

@ -3,7 +3,6 @@
#include "G4VUserDetectorConstruction.hh" #include "G4VUserDetectorConstruction.hh"
#include "G4UImessenger.hh" #include "G4UImessenger.hh"
#include "G4Cache.hh"
#include "G4Box.hh" #include "G4Box.hh"
#include "G4LogicalVolume.hh" #include "G4LogicalVolume.hh"
@ -20,30 +19,24 @@
#include "G4SDManager.hh" #include "G4SDManager.hh"
#include "ASensitiveDetector.hh" #include "ASensitiveDetector.hh"
#include "G4UImessenger.hh" #include "AMessenger.hh"
#include "G4Cache.hh"
#include "G4UImessenger.hh"
#include "G4Cache.hh"
#include <vector> #include <vector>
//#include "G4GDMLParser.hh" class ADetectorConstruction : public G4VUserDetectorConstruction
class ADetectorConstruction : public G4VUserDetectorConstruction, public G4UImessenger
{ {
public: public:
ADetectorConstruction(); ADetectorConstruction();
virtual ~ADetectorConstruction(); virtual ~ADetectorConstruction();
virtual G4VPhysicalVolume* Construct(); virtual G4VPhysicalVolume* Construct();
void ConstructSDandField(); void ConstructSDandField();
private: private:
std::vector<G4LogicalVolume*> detectorVolumes; std::vector<G4LogicalVolume*> detectorVolumes;
// Hier fSD als Member speichern
ASensitiveDetector* fSD;
}; };
#endif #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 "G4Track.hh"
#include "G4SystemOfUnits.hh" #include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh" #include "G4UnitsTable.hh"
#include "G4UImessenger.hh"
#include "G4UIcmdWithAString.hh"
#include <unordered_map> #include <unordered_map>
#include <fstream> #include <fstream>
class AMessenger;
class ASensitiveDetector : public G4VSensitiveDetector class ASensitiveDetector : public G4VSensitiveDetector
{ {
public: public:
@ -21,8 +25,17 @@ public:
virtual void Initialize(G4HCofThisEvent* hce) override; virtual void Initialize(G4HCofThisEvent* hce) override;
virtual void EndOfEvent(G4HCofThisEvent* hce) override; virtual void EndOfEvent(G4HCofThisEvent* hce) override;
virtual G4bool ProcessHits(G4Step* step, G4TouchableHistory* touchHist) 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: private:
AMessenger* fMessenger = nullptr; // jetzt optional
G4String fOutputFilename = "outfiles/shower_setup.txt";
G4int fCurrentEventID = -1; // speichert die aktuelle Event-ID
struct HitInfo { struct HitInfo {
G4int eventID; G4int eventID;
G4int trackID; G4int trackID;
@ -33,13 +46,16 @@ private:
G4double primaryEnergy; G4double primaryEnergy;
G4double energyDeposited; G4double energyDeposited;
G4String detectorName; G4String detectorName;
G4String cleanDetectorName;
HitInfo() HitInfo()
: trackID(-1), parentID(-1), particleEnergy(0.), primaryEnergy(0.), energyDeposited(0.) {} : trackID(-1), parentID(-1), particleEnergy(0.), primaryEnergy(0.), energyDeposited(0.) {}
}; };
G4String fDetectorName; G4String fDetectorName;
std::unordered_map<G4LogicalVolume*, std::string> fCleanNames;
std::unordered_map<G4int, HitInfo> fTrackHitMap; // TrackID → HitInfo std::unordered_map<G4int, HitInfo> fTrackHitMap; // TrackID → HitInfo
}; };
#endif #endif

32
sim.cc
View file

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

View file

@ -1,40 +1,24 @@
#include "AActionInitialization.hh" #include "AActionInitialization.hh"
//#include "PrimaryGeneratorAction.hh" #include "APrimaryGenerator.hh"
#include "ARunAction.hh"
AActionInitialization::AActionInitialization() AActionInitialization::AActionInitialization()
: G4VUserActionInitialization()
{ {
} }
AActionInitialization::~AActionInitialization() AActionInitialization::~AActionInitialization() {}
void AActionInitialization::Build() const
{ {
// Primärgenerator
SetUserAction(new APrimaryGenerator());
// RunAction
SetUserAction(new ARunAction());
} }
void AActionInitialization::BuildForMaster() const void AActionInitialization::BuildForMaster() const
{ {
// This is needed to avoid problems due to multithreading when writing the data. SetUserAction(new ARunAction());
ARunAction *runAction = new ARunAction();
SetUserAction(runAction);
} }
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 "ADetectorConstruction.hh"
#include "ASensitiveDetector.hh" #include "ASensitiveDetector.hh"
#include "AMessenger.hh"
#include "G4Box.hh" #include "G4Box.hh"
#include "G4PVPlacement.hh" #include "G4PVPlacement.hh"
@ -10,9 +11,20 @@
#include "G4SDManager.hh" #include "G4SDManager.hh"
#include "G4SystemOfUnits.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() G4VPhysicalVolume* ADetectorConstruction::Construct()
{ {
@ -93,15 +105,12 @@ G4VPhysicalVolume* ADetectorConstruction::Construct()
// --- SensitiveDetector zuweisen --- // --- SensitiveDetector zuweisen ---
void ADetectorConstruction::ConstructSDandField() void ADetectorConstruction::ConstructSDandField()
{ {
// Ein einziger SensitiveDetector für alle Layer // SD bei Geant4 registrieren
G4String sdName = "shower_setup"; G4SDManager::GetSDMpointer()->AddNewDetector(fSD);
ASensitiveDetector* sd = new ASensitiveDetector(sdName);
G4SDManager::GetSDMpointer()->AddNewDetector(sd);
// Alle Layer bekommen denselben SD // Alle Layer bekommen denselben SD
for(auto lv : detectorVolumes) 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; std::stringstream strRunID;
strRunID << runID; strRunID << runID;
//analysisManager->OpenFile("output" + strRunID.str() + ".root"); analysisManager->OpenFile("output" + strRunID.str() + ".root");
} }
void ARunAction::EndOfRunAction(const G4Run *run) void ARunAction::EndOfRunAction(const G4Run *run)

View file

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