diff --git a/README.md b/README.md index 2ba5bc2..60f7acb 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,9 @@ The output file is a ROOT file. Can be checked by TBrowser. ## Prerequisities * CERN Geant4 -* CERN Root (tested on 6.13/03) +* CERN Root (tested on 6.19/01) * Linux or MacOS (should work on Windows, not tested) +* Also tested on WLS Ubuntu (X11 needed) ## Building Before building, be sure that you changed the macroPath to the right directory in sipm.cc. @@ -18,3 +19,8 @@ mkdir build_dir && cd build_dir cmake ../SiPM make -jN (where N is the number of jobs to run simultaneously) ``` + +## Updates +* 2020/02/06 - SiPMAnalisys' and SiPMParameters' GetInstance functions are returning a static reference instead of pointer +* 2020/02/06 - G4Mutex replaced with std::mutex +* 2020/02/06 - Input config file and output data file name can be changed with the GetInstance functions on the first call diff --git a/include/SiPMAnalysis.hh b/include/SiPMAnalysis.hh index 16f152a..a38b02b 100644 --- a/include/SiPMAnalysis.hh +++ b/include/SiPMAnalysis.hh @@ -11,8 +11,6 @@ #include #include -#include "G4Threading.hh" -#include "G4AutoLock.hh" #include "TTree.h" #include "TFile.h" @@ -20,37 +18,36 @@ #include #include #include +#include #include "SiPMParameters.hh" class SiPMAnalysis { -private: - /* Here will be the instance stored. */ - static SiPMAnalysis* instance; - +private: std::vector ttree; - //TTree *tree; - //TTree *electrontree; TFile *file; - G4Mutex SiPMAnalysisMutex; + mutable std::mutex SiPMAnalysisMutex; /* Private constructor to prevent instancing. */ - SiPMAnalysis(); + SiPMAnalysis(const std::string& _filename); + + std::string filename; + double x, y, e, time; int sipm; int noOfSipm = 0; public: ~SiPMAnalysis(); - SiPMAnalysis(const SiPMAnalysis&) = delete; - SiPMAnalysis& operator=(const SiPMAnalysis&) = delete; void Fill(int copyNo, double x1, double y1, double e1, int sipm1, double time1); void Close(); - - /* Static access method. */ - static SiPMAnalysis* getInstance(); + + static SiPMAnalysis& getInstance(const std::string& _filename = "data.root"); + + SiPMAnalysis(const SiPMAnalysis&) = delete; + SiPMAnalysis& operator=(const SiPMAnalysis&) = delete; }; #endif /* SiPMAnalysis_hh */ diff --git a/include/SiPMParameters.hh b/include/SiPMParameters.hh index 302f2ea..71d981e 100644 --- a/include/SiPMParameters.hh +++ b/include/SiPMParameters.hh @@ -21,7 +21,7 @@ class SiPMParameters { public: - static SiPMParameters *GetInstance(); + static SiPMParameters& GetInstance(const std::string& config_file_name = "config.conf"); ~SiPMParameters(); //---Config file--------------------------------------------------------------------------------------- @@ -65,15 +65,19 @@ public: G4int GetNumberOfEvents() { return numberofevents; } void ResetToDefaults(); + + SiPMParameters(const SiPMParameters&) = delete; + SiPMParameters& operator=(const SiPMParameters&) = delete; private: - SiPMParameters(); - static SiPMParameters *instance; + SiPMParameters(const std::string& config_file_name); + void PrintUsedFilename(); //---Config file--------------------------------------------------------------------------------------- std::string config_file; void StoreConfigValues(std::string key1, std::string value1); void CheckValues(); + bool conf_loaded = false; G4ThreeVector particleGun_position; G4ThreeVector particleGun_MomentumDirection; @@ -88,6 +92,8 @@ private: G4double scint_radius; G4int numberofevents; + + }; diff --git a/sipm.cc b/sipm.cc index 92eb73e..89eec28 100644 --- a/sipm.cc +++ b/sipm.cc @@ -32,7 +32,8 @@ int main(int argc, char** argv) { - SiPMParameters *parameters = SiPMParameters::GetInstance(); + SiPMParameters& parameters = SiPMParameters::GetInstance(); + SiPMAnalysis& analysis = SiPMAnalysis::getInstance(); bool visualization = true; int NoE=0; @@ -43,7 +44,7 @@ int main(int argc, char** argv) if(!strcmp("-df", argv[i])) //number of events { std::cout << "Settings will be read from the default file." << std::endl; - parameters -> ParseConfigFile(); + parameters.ParseConfigFile(); } else if(!strcmp("-f", argv[i])) //number of events { @@ -52,7 +53,7 @@ int main(int argc, char** argv) { filename = argv[i+1]; std::cout << "Settings will be read from " << filename << "." << std::endl; - parameters -> ParseConfigFile(filename); + parameters.ParseConfigFile(filename); } if(filename.empty()) { @@ -66,7 +67,7 @@ int main(int argc, char** argv) } } - NoE = parameters -> GetNumberOfEvents(); + NoE = parameters.GetNumberOfEvents(); #ifdef G4MULTITHREADED G4MTRunManager* runManager = new G4MTRunManager; @@ -82,7 +83,7 @@ int main(int argc, char** argv) /////////////// //Initialize the analysis instance here first to avoid crash - SiPMAnalysis *analysis = SiPMAnalysis::getInstance(); + //SiPMAnalysis *analysis = SiPMAnalysis::getInstance(); G4VisManager* visManager = new G4VisExecutive; visManager->Initialize(); diff --git a/src/SiPMAnalysis.cc b/src/SiPMAnalysis.cc index 3a4dede..3c99ff8 100644 --- a/src/SiPMAnalysis.cc +++ b/src/SiPMAnalysis.cc @@ -8,17 +8,17 @@ #include "SiPMAnalysis.hh" -SiPMAnalysis::SiPMAnalysis() +SiPMAnalysis::SiPMAnalysis(const std::string& _filename) : filename(_filename) { - SiPMParameters *parameters = SiPMParameters::GetInstance(); - G4int xDiv = parameters -> GetXDivison(); - G4int yDiv = parameters -> GetYDivison(); + SiPMParameters ¶meters = SiPMParameters::GetInstance(); + G4int xDiv = parameters.GetXDivison(); + G4int yDiv = parameters.GetYDivison(); noOfSipm = xDiv * yDiv; G4int counter = 0; - char filename[20]; - char treename[20]; - snprintf(filename, 30, "data.root"); + char filename1[30]; + char treename[30]; + snprintf(filename1, 30, filename.c_str()); ttree = std::vector(noOfSipm,0); for(int i = 0; i < xDiv; i++) @@ -37,9 +37,7 @@ SiPMAnalysis::SiPMAnalysis() } counter = 0; - file = new TFile(filename,"RECREATE"); - instance = this; - SiPMAnalysisMutex = G4MUTEX_INITIALIZER; + file = new TFile(filename1,"RECREATE"); } SiPMAnalysis::~SiPMAnalysis() @@ -47,21 +45,17 @@ SiPMAnalysis::~SiPMAnalysis() } -SiPMAnalysis* SiPMAnalysis::getInstance() +SiPMAnalysis& SiPMAnalysis::getInstance(const std::string& _filename) { - if (instance == 0) - { - std::cout << "Created analysis instance" << std::endl; - instance = new SiPMAnalysis(); - } - + static SiPMAnalysis instance(_filename); return instance; } void SiPMAnalysis::Fill(int copyNo, double x1, double y1, double e1, int sipm1, double time1) { - G4AutoLock lock(&SiPMAnalysisMutex); - + //std::lock_guard guard(SiPMAnalysisMutex); + + SiPMAnalysisMutex.lock(); x = x1; y = y1; e = e1; @@ -71,8 +65,7 @@ void SiPMAnalysis::Fill(int copyNo, double x1, double y1, double e1, int sipm1, ttree[copyNo] -> Fill(); ttree[copyNo] -> FlushBaskets(); - - lock.unlock(); + SiPMAnalysisMutex.unlock(); } void SiPMAnalysis::Close() @@ -83,6 +76,3 @@ void SiPMAnalysis::Close() } file -> Close(); } - -/* Null, because instance will be initialized on demand. */ -SiPMAnalysis* SiPMAnalysis::instance = 0; diff --git a/src/SiPMDetectorConstruction.cc b/src/SiPMDetectorConstruction.cc index ccfb241..563185a 100644 --- a/src/SiPMDetectorConstruction.cc +++ b/src/SiPMDetectorConstruction.cc @@ -26,7 +26,7 @@ G4VPhysicalVolume* SiPMDetectorConstruction::Construct() G4NistManager* nist = G4NistManager::Instance(); //Get the parameters instance - SiPMParameters *parameters = SiPMParameters::GetInstance(); + SiPMParameters& parameters = SiPMParameters::GetInstance(); // Option to switch on/off checking of volumes overlaps @@ -64,11 +64,11 @@ G4VPhysicalVolume* SiPMDetectorConstruction::Construct() // // World // - G4ThreeVector sipm_size = parameters -> GetSiPMSize(); + G4ThreeVector sipm_size = parameters.GetSiPMSize(); - G4double world_sizeX = parameters -> GetXDivison() * sipm_size.getX() * cm; //2*m; - G4double world_sizeY = parameters -> GetYDivison() * sipm_size.getY() * cm; //2*m; - G4double world_sizeZ = 2*sipm_size.getZ() + parameters -> GetScintillatorLength(); + G4double world_sizeX = parameters.GetXDivison() * sipm_size.getX() * cm; //2*m; + G4double world_sizeY = parameters.GetYDivison() * sipm_size.getY() * cm; //2*m; + G4double world_sizeZ = 2*sipm_size.getZ() + parameters.GetScintillatorLength(); G4Material* world_mat = air; //nist->FindOrBuildMaterial("G4_AIR"); G4Box* solidWorld = @@ -93,7 +93,7 @@ G4VPhysicalVolume* SiPMDetectorConstruction::Construct() //Place a container which contains everything for G4Replica G4double container_sizeX = sipm_size.getX()*cm; G4double container_sizeY = sipm_size.getY()*cm; - G4double container_sizeZ = (sipm_size.getZ()*2 + parameters -> GetScintillatorLength())*cm; + G4double container_sizeZ = (sipm_size.getZ()*2 + parameters.GetScintillatorLength())*cm; G4Box *solidContainer = new G4Box("Container", container_sizeX*0.5, container_sizeY*0.5, container_sizeZ*0.5); @@ -156,7 +156,7 @@ G4VPhysicalVolume* SiPMDetectorConstruction::Construct() // box shape G4double scint_sizeX = sizeX; G4double scint_sizeY = sizeY; - G4double scint_sizeZ = parameters -> GetScintillatorLength() * cm; + G4double scint_sizeZ = parameters.GetScintillatorLength() * cm; G4double z_pos = sipm_width + (scint_sizeZ*0.5); @@ -186,7 +186,7 @@ G4VPhysicalVolume* SiPMDetectorConstruction::Construct() * Scintillator */ - G4double scint_radius = parameters -> GetScintillatorRadius()*cm; + G4double scint_radius = parameters.GetScintillatorRadius()*cm; G4Tubs * solidScint = new G4Tubs("tube", 0, scint_radius, 0.5*(scint_sizeZ+(0.5*mm)), 0, 2*CLHEP::pi); //name, inner R, outter R, Half length in Z, starting angle, angle of the segment in rad new G4Box("Scintillator", @@ -304,8 +304,8 @@ G4VPhysicalVolume* SiPMDetectorConstruction::Construct() //Using G4PVPlacement instead of replica or others - int x = parameters -> GetXDivison(); - int y = parameters -> GetYDivison(); + int x = parameters.GetXDivison(); + int y = parameters.GetYDivison(); int helper = 0; G4VPhysicalVolume *physContainer[x][y]; char s1[30]; diff --git a/src/SiPMParameters.cc b/src/SiPMParameters.cc index 4e259df..ad133a6 100644 --- a/src/SiPMParameters.cc +++ b/src/SiPMParameters.cc @@ -9,21 +9,15 @@ #include "SiPMParameters.hh" -SiPMParameters* SiPMParameters::GetInstance() +SiPMParameters& SiPMParameters::GetInstance(const std::string& config_file_name) { - if (instance == 0) - { - instance = new SiPMParameters(); - } - + static SiPMParameters instance(config_file_name); + instance.PrintUsedFilename(); return instance; } -SiPMParameters* SiPMParameters::instance = 0; - -SiPMParameters::SiPMParameters() +SiPMParameters::SiPMParameters(const std::string& config_file_name) : config_file(config_file_name) { - config_file = "config.conf"; ResetToDefaults(); } @@ -31,6 +25,11 @@ SiPMParameters::~SiPMParameters() { } +void SiPMParameters::PrintUsedFilename() +{ + std::cout << config_file << (conf_loaded ? " loaded." : " will be loaded. Call ParseConfigFile().") << std::endl; +} + void SiPMParameters::ResetToDefaults() { particleGun_position = G4ThreeVector(50, -5, 0); diff --git a/src/SiPMPrimaryGeneratorAction.cc b/src/SiPMPrimaryGeneratorAction.cc index 05e26a5..695a7e6 100644 --- a/src/SiPMPrimaryGeneratorAction.cc +++ b/src/SiPMPrimaryGeneratorAction.cc @@ -9,7 +9,7 @@ SiPMPrimaryGeneratorAction::SiPMPrimaryGeneratorAction() : G4VUserPrimaryGeneratorAction(), fParticleGun(0) { - SiPMParameters *parameters = SiPMParameters::GetInstance(); + SiPMParameters& parameters = SiPMParameters::GetInstance(); G4int n_particle = 1; //particles per event fParticleGun = new G4ParticleGun(n_particle); @@ -18,8 +18,8 @@ SiPMPrimaryGeneratorAction::SiPMPrimaryGeneratorAction() : G4VUserPrimaryGenerat G4String particleName; G4ParticleDefinition* particle = particleTable->FindParticle(particleName="mu+"); fParticleGun->SetParticleDefinition(particle); - fParticleGun->SetParticleMomentumDirection(parameters -> GetParticleGunMomentumDirection()); - fParticleGun->SetParticleEnergy(parameters -> GetParticleGunEnergy()*GeV); //1GeV + fParticleGun->SetParticleMomentumDirection(parameters.GetParticleGunMomentumDirection()); + fParticleGun->SetParticleEnergy(parameters.GetParticleGunEnergy()*GeV); //1GeV } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... @@ -33,7 +33,7 @@ SiPMPrimaryGeneratorAction::~SiPMPrimaryGeneratorAction() void SiPMPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent) { - SiPMParameters *parameters = SiPMParameters::GetInstance(); - fParticleGun->SetParticlePosition(parameters -> GetParticleGunPosition()); + SiPMParameters ¶meters = SiPMParameters::GetInstance(); + fParticleGun->SetParticlePosition(parameters.GetParticleGunPosition()); fParticleGun->GeneratePrimaryVertex(anEvent); } diff --git a/src/SiPMRunAction.cc b/src/SiPMRunAction.cc index 8396a00..067eea4 100644 --- a/src/SiPMRunAction.cc +++ b/src/SiPMRunAction.cc @@ -42,8 +42,8 @@ void SiPMRunAction::EndOfRunAction(const G4Run* run) // Print // if (IsMaster()) { - SiPMAnalysis *analysis = SiPMAnalysis::getInstance(); - analysis -> Close(); + SiPMAnalysis &analysis = SiPMAnalysis::getInstance(); + analysis.Close(); G4cout << G4endl << "--------------------End of Global Run-----------------------"; diff --git a/src/SiPMSteppingAction.cc b/src/SiPMSteppingAction.cc index b82ea51..4bc2261 100644 --- a/src/SiPMSteppingAction.cc +++ b/src/SiPMSteppingAction.cc @@ -21,7 +21,7 @@ SiPMSteppingAction::~SiPMSteppingAction() void SiPMSteppingAction::UserSteppingAction(const G4Step* step) { - SiPMAnalysis *analysis = SiPMAnalysis::getInstance(); + SiPMAnalysis &analysis = SiPMAnalysis::getInstance(); G4LogicalVolume* volume = step->GetPreStepPoint()->GetTouchableHandle() @@ -71,7 +71,7 @@ void SiPMSteppingAction::UserSteppingAction(const G4Step* step) std::cout << "Photon reached Sipm0 at: " << step -> GetPostStepPoint() -> GetTouchableHandle() -> GetVolume(1) -> GetCopyNo() << std::endl; std::cout << "Mother Logical name: " << step -> GetPostStepPoint() -> GetTouchableHandle() -> GetVolume(1) -> GetName() << std::endl; - analysis -> Fill(step -> GetPostStepPoint() -> GetTouchableHandle() -> GetVolume(1) -> GetCopyNo(), postX, postY, postkinE, 1, fTrack -> GetGlobalTime()); + analysis.Fill(step -> GetPostStepPoint() -> GetTouchableHandle() -> GetVolume(1) -> GetCopyNo(), postX, postY, postkinE, 1, fTrack -> GetGlobalTime()); //sipm0_num++; } @@ -85,7 +85,7 @@ void SiPMSteppingAction::UserSteppingAction(const G4Step* step) std::cout << "Local time: " << postTime << std::endl; //std::cout << "Photon reached Sipm1 at copy no: " << postvolume -> GetCopyNo() << std::endl; //sipm1_num++; - analysis -> Fill(step -> GetPostStepPoint() -> GetTouchableHandle() -> GetVolume(1) -> GetCopyNo(), postX, postY, postkinE, 2, fTrack -> GetGlobalTime()); + analysis.Fill(step -> GetPostStepPoint() -> GetTouchableHandle() -> GetVolume(1) -> GetCopyNo(), postX, postY, postkinE, 2, fTrack -> GetGlobalTime()); } /*if(postName == "Scintillator_W") {