diff --git a/CMakeLists.txt b/CMakeLists.txt index e6fe12e..77a398a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # Setup the project # cmake_minimum_required(VERSION 3.16...3.21) -project(B4a) +project(minicalo) @@ -41,9 +41,11 @@ target_link_libraries(exampleB4a ${Geant4_LIBRARIES}) ## needs to be added later -#file(GLOB_RECURSE SOURCES "${PROJECT_SOURCE_DIR}/src/*.cc" ) -#add_subdirectory(lib/pybind11) -#pybind11_add_module(compiled ${SOURCES} "${PROJECT_SOURCE_DIR}/bind/bindings.cpp") +file(GLOB_RECURSE SOURCES "${PROJECT_SOURCE_DIR}/src/*.cc" ) +add_subdirectory(lib/pybind11) +pybind11_add_module(bindings ${SOURCES} "${PROJECT_SOURCE_DIR}/bind/bindings.cpp") +target_include_directories(bindings PUBLIC lib/pybind11/include) +target_link_libraries(bindings PUBLIC ${Geant4_LIBRARIES}) #---------------------------------------------------------------------------- # Copy all scripts to the build directory, i.e. the directory in which we diff --git a/bind/bindings.cpp b/bind/bindings.cpp index e69de29..e31092e 100644 --- a/bind/bindings.cpp +++ b/bind/bindings.cpp @@ -0,0 +1,32 @@ + +#include +#include +#include + +#include "ConstructionWrapper.hh" +#include "SystemBuilder.hh" + +namespace py = pybind11; + +template +void makeConstructionWrapper(M & m, std::string name){ + + py::class_(m, name.data()).def(py::init()) + .def("addLayer", &ConstructionWrapper::addLayer) + .def("getNSensors", &ConstructionWrapper::getNSensors); + +} +template +void makeSystemBuilder(M& m, std::string name){ + py::class_(m, name.data()).def(py::init()) + .def("init", &SystemBuilder::init) + .def("run_gui", &SystemBuilder::run_gui) + .def("run_batch", &SystemBuilder::run_batch) + .def("visualize", &SystemBuilder::visualize); +} + +PYBIND11_MODULE(bindings, m) { + m.doc() = "pybind11 example plugin"; // optional module docstring + makeConstructionWrapper(m, "ConstructionWrapper"); + makeSystemBuilder(m, "SystemBuilder"); +} \ No newline at end of file diff --git a/exampleB4a.cc b/exampleB4a.cc index 7a819f2..6eda7f0 100644 --- a/exampleB4a.cc +++ b/exampleB4a.cc @@ -41,8 +41,15 @@ #include "ConstructionWrapper.hh" +#include "SystemBuilder.hh" + //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + + + + + namespace { void PrintUsage() { G4cerr << " Usage: " << G4endl; @@ -55,7 +62,7 @@ namespace { //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... -int main(int argc,char** argv) +int main2(int argc,char** argv) { // Evaluate arguments // @@ -135,6 +142,8 @@ int main(int argc,char** argv) auto actionInitialization = new B4a::ActionInitialization(detConstruction); runManager->SetUserInitialization(actionInitialization); + actionInitialization->setGeneratorProperties(100, 1000, "e-"); + // Initialize visualization // auto visManager = new G4VisExecutive; @@ -170,6 +179,105 @@ int main(int argc,char** argv) delete visManager; delete runManager; delete cw; + return 0; +} + +//later +//class Runner { +//public: +// void initialize(ConstructionWrapper CW, bool gui=false); +// void run(int nEvents, std::string partSpecies, double minEnergy, double maxEnergy); +//} + +void run(ConstructionWrapper CW, int nEvents, std::string partSpecies, double minEnergy, double maxEnergy, bool gui=false){ + + char* argv[]={(char*)"dummy"}; + + // Construct the default run manager + // + auto* runManager = + G4RunManagerFactory::CreateRunManager(G4RunManagerType::Default); + runManager->SetNumberOfThreads(1); + + ConstructionWrapper * cw = &CW; + G4String session; + G4UIExecutive* ui = nullptr; + if ( gui ) { + ui = new G4UIExecutive((int)1, argv, session); + } + + // Set mandatory initialization classes + // + auto detConstruction = new B4::DetectorConstruction(cw); + + runManager->SetUserInitialization(detConstruction); + + auto physicsList = new FTFP_BERT; + runManager->SetUserInitialization(physicsList); + + auto actionInitialization = new B4a::ActionInitialization(detConstruction); + runManager->SetUserInitialization(actionInitialization); + + actionInitialization->setGeneratorProperties(minEnergy, maxEnergy, partSpecies); + + // Initialize visualization + // + auto visManager = new G4VisExecutive; + // G4VisExecutive can take a verbosity argument - see /vis/verbose guidance. + // G4VisManager* visManager = new G4VisExecutive("Quiet"); + visManager->Initialize(); + + // Get the pointer to the User Interface manager + auto UImanager = G4UImanager::GetUIpointer(); + + // Process macro or start UI session + // + + + if ( gui ) { + // interactive mode : define UI session + UImanager->ApplyCommand("/control/execute init_vis.mac"); + if (ui->IsGUI()) { + UImanager->ApplyCommand("/control/execute gui.mac"); + } + ui->SessionStart(); + delete ui; + } + else { + G4String command = "/control/execute run1.mac"; + UImanager->ApplyCommand("/run/initialize"); + UImanager->ApplyCommand("/run/beamOn "+ std::to_string(nEvents)); + } + + + // Job termination + // Free the store: user actions, physics_list and detector_description are + // owned and deleted by the run manager, so they should not be deleted + // in the main() program ! + delete visManager; + delete runManager; + +} + +int main(){ + + ConstructionWrapper cw; + //to be moved + cw.addLayer(1, "G4_Pb", false); + cw.addLayer(10, "G4_Si", true, 9); + cw.addLayer(1, "G4_Pb", false); + cw.addLayer(20, "G4_Si", true, 15); + cw.addLayer(4, "G4_Pb", false); + cw.addLayer(3, "G4_Si", true, 23); + + SystemBuilder builder; + builder.init(cw, true); + //builder.run_gui(); + builder.run_batch(10000, "e-", 1, 100); + + //run(cw, 1000, "e-", 1, 100, true); + + return 0; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... diff --git a/include/ActionInitialization.hh b/include/ActionInitialization.hh index f68bc4d..87d8257 100644 --- a/include/ActionInitialization.hh +++ b/include/ActionInitialization.hh @@ -31,7 +31,7 @@ #define B4aActionInitialization_h 1 #include "G4VUserActionInitialization.hh" - +#include "PrimaryGeneratorAction.hh" namespace B4 { @@ -52,8 +52,17 @@ class ActionInitialization : public G4VUserActionInitialization void BuildForMaster() const override; void Build() const override; + void setGeneratorProperties(G4double minEnergy, G4double maxEnergy, G4String partSpecies){ + this->minEnergy = minEnergy; + this->maxEnergy = maxEnergy; + this->partSpecies = partSpecies; + } + private: B4::DetectorConstruction* fDetConstruction = nullptr; + G4double minEnergy; + G4double maxEnergy; + G4String partSpecies; }; } diff --git a/include/SystemBuilder.hh b/include/SystemBuilder.hh new file mode 100644 index 0000000..cd9d0cf --- /dev/null +++ b/include/SystemBuilder.hh @@ -0,0 +1,141 @@ + +#include "ConstructionWrapper.hh" +#include +#include "G4RunManagerFactory.hh" +#include "DetectorConstruction.hh" +#include "ActionInitialization.hh" + +#include "G4RunManagerFactory.hh" +#include "G4SteppingVerbose.hh" +#include "G4UIcommand.hh" +#include "G4UImanager.hh" +#include "G4UIExecutive.hh" +#include "G4VisExecutive.hh" + +#include "FTFP_BERT.hh" +#include "Randomize.hh" + +class SystemBuilder{ +public: + +SystemBuilder(){}; +~SystemBuilder(){ + if(visManager != nullptr){ + delete visManager; + delete runManager; + delete ui; +} +}; + + +void init(ConstructionWrapper &cw, bool gui=false); +void visualize()const{} //TBI +void run_gui(); +void run_batch(int nEvents, std::string partSpecies, double minEnergy, double maxEnergy); + +private: + +inline void check(){ + if(runManager == nullptr){ + throw std::runtime_error("runManager not found"); + } + if(detConstruction == nullptr){ + throw std::runtime_error("DetectorConstruction not found"); + } + if(actionInitialization == nullptr){ + throw std::runtime_error("ActionInitialization not found"); + } + if(visManager == nullptr){ + throw std::runtime_error("VisManager not found"); + } + if(UImanager == nullptr){ + throw std::runtime_error("UImanager not found"); + } + if(ui == nullptr){ + throw std::runtime_error("UI not found"); + } + } + + +G4RunManager * runManager=nullptr; +B4::DetectorConstruction * detConstruction=nullptr; +B4a::ActionInitialization * actionInitialization=nullptr; +G4VisExecutive * visManager=nullptr; +G4UImanager * UImanager=nullptr; +G4UIExecutive * ui=nullptr; + +}; + +/* + + +void run(ConstructionWrapper CW, int nEvents, std::string partSpecies, double minEnergy, double maxEnergy, bool gui=false){ + + char* argv[]={(char*)"dummy"}; + + // Construct the default run manager + // + auto* runManager = + G4RunManagerFactory::CreateRunManager(G4RunManagerType::Default); + runManager->SetNumberOfThreads(1); + + ConstructionWrapper * cw = &CW; + G4String session; + G4UIExecutive* ui = nullptr; + if ( gui ) { + ui = new G4UIExecutive((int)1, argv, session); + } + + // Set mandatory initialization classes + // + auto detConstruction = new B4::DetectorConstruction(cw); + + runManager->SetUserInitialization(detConstruction); + + auto physicsList = new FTFP_BERT; + runManager->SetUserInitialization(physicsList); + + auto actionInitialization = new B4a::ActionInitialization(detConstruction); + runManager->SetUserInitialization(actionInitialization); + + actionInitialization->setGeneratorProperties(minEnergy, maxEnergy, partSpecies); + + // Initialize visualization + // + auto visManager = new G4VisExecutive; + // G4VisExecutive can take a verbosity argument - see /vis/verbose guidance. + // G4VisManager* visManager = new G4VisExecutive("Quiet"); + visManager->Initialize(); + + // Get the pointer to the User Interface manager + auto UImanager = G4UImanager::GetUIpointer(); + + // Process macro or start UI session + // + + + if ( gui ) { + // interactive mode : define UI session + UImanager->ApplyCommand("/control/execute init_vis.mac"); + if (ui->IsGUI()) { + UImanager->ApplyCommand("/control/execute gui.mac"); + } + ui->SessionStart(); + delete ui; + } + else { + G4String command = "/control/execute run1.mac"; + UImanager->ApplyCommand("/run/initialize"); + UImanager->ApplyCommand("/run/beamOn "+ std::to_string(nEvents)); + } + + + // Job termination + // Free the store: user actions, physics_list and detector_description are + // owned and deleted by the run manager, so they should not be deleted + // in the main() program ! + delete visManager; + delete runManager; + +} +*/ \ No newline at end of file diff --git a/src/ActionInitialization.cc b/src/ActionInitialization.cc index b71ba21..b38ec20 100644 --- a/src/ActionInitialization.cc +++ b/src/ActionInitialization.cc @@ -58,6 +58,9 @@ void ActionInitialization::BuildForMaster() const void ActionInitialization::Build() const { auto gen = new PrimaryGeneratorAction; + gen->setMinPartEnergy(minEnergy); + gen->setMaxPartEnergy(maxEnergy); + gen->setPartSpecies(partSpecies); SetUserAction(gen); auto runact = new RunAction; SetUserAction(runact); diff --git a/src/RunAction.cc b/src/RunAction.cc index 40dc611..85b7360 100644 --- a/src/RunAction.cc +++ b/src/RunAction.cc @@ -43,7 +43,7 @@ namespace B4 RunAction::RunAction() { // set printing event number per each event - G4RunManager::GetRunManager()->SetPrintProgress(1); + G4RunManager::GetRunManager()->SetPrintProgress(1000); // Create analysis manager // The choice of the output format is done via the specified