Compare commits
3 commits
6c121232f8
...
f003c1697a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f003c1697a | ||
|
|
22a080911f | ||
|
|
f193790483 |
11 changed files with 201 additions and 121 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
22
include/AMessenger.hh
Normal 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
|
||||
|
|
@ -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
66
sim.cc
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -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
24
src/AMessenger.cc
Normal 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue