Skip to content

Commit

Permalink
First attempt at dlopen-based physics list plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
tkittel committed Mar 1, 2024
1 parent ef2b04c commit ef6fd5f
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 182 deletions.
16 changes: 2 additions & 14 deletions src/simplebuild_dgcode/data/pkgs/G4/G4Launcher/libsrc/Launcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "Core/String.hh"
#include "G4Launcher/Launcher.hh"
#include "G4Launcher/SingleParticleGun.hh"
#include "G4PhysicsLists/PhysicsListFactory.hh"
#include "G4PhysicsLists/PhysListMgr.hh"
#include "G4Interfaces/GeoConstructBase.hh"
#include "G4Interfaces/ParticleGenBase.hh"
#include "G4Interfaces/StepFilterBase.hh"
Expand Down Expand Up @@ -431,19 +431,7 @@ void G4Launcher::Launcher::Imp::preinit()
}
}

//A bit brute-force and inefficient, but no biggie:
std::vector<std::string> reflists;
PhysicsListFactory::getAllReferenceListNames(reflists);
for (auto it = reflists.begin();it!=reflists.end();++it) {
if (*it==pln_parts.front()) {
pl = PhysicsListFactory::createReferencePhysicsList(pln_parts.front());
assert(pl);
}
}
if (!pl) {
//Our own custom list which was simply specified via a string name rather than a provider?
pl = PhysicsListFactory::attemptCreateCustomPhysicsList(pln_parts.front());
}
pl = PhysListMgr::createList( pln_parts.front() );
if (!pl) {
printf("%sUnknown physics list: %s\n",prefix(),pln_parts.front().c_str());
error("Physics list name is not known");
Expand Down
27 changes: 14 additions & 13 deletions src/simplebuild_dgcode/data/pkgs/G4/G4Launcher/python/_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,19 +583,20 @@ def create_density_map():

self._shutdown()#shutdown: Make sure run-manager deletion happens now and not when garbage collection runs

_setPhysicsList_orig = Launcher.setPhysicsList
def _setPhysicsList(self,physlistname):
#Make sure that custom physics lists will be translated into a provider
#rather than just the string (this assumes that the default physics list
#will not be custom, which it can't be if we want to avoid a direct
#dependency on the custom physics list code in question).
import G4PhysicsLists
if G4PhysicsLists.listIsCustom(physlistname):
#extract physics list provider and apply that:
self.setPhysicsListProvider(G4PhysicsLists.extractProvider(physlistname))
else:
_setPhysicsList_orig(self,physlistname)
##_setPhysicsList_orig = Launcher.setPhysicsList
##def _setPhysicsList(self,physlistname):
## #Make sure that custom physics lists will be translated into a provider
## #rather than just the string (this assumes that the default physics list
## #will not be custom, which it can't be if we want to avoid a direct
## #dependency on the custom physics list code in question).
## import G4PhysicsLists
## if G4PhysicsLists.listIsCustom(physlistname):
## #extract physics list provider and apply that:
## self.setPhysicsListProvider(G4PhysicsLists.extractProvider(physlistname))
## else:
## _setPhysicsList_orig(self,physlistname)
##
#Launcher.setPhysicsList = _setPhysicsList

Launcher.setPhysicsList = _setPhysicsList
Launcher.swallowCmdLineAndLaunch = _swallowCmdLineAndLaunch
Launcher.go = _swallowCmdLineAndLaunch#alias
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Empty physics list.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef dgcode_PhysListMgr_hh
#define dgcode_PhysListMgr_hh

#include <string>
#include <vector>
class G4VUserPhysicsList;

namespace PhysListMgr {
struct PhysListInfo {
std::string name;
std::string pkg_name;//not set for g4 ref lists
std::string description;//only set if loaded.
};
enum class LoadDescriptions { YES, NO };
std::vector<PhysListInfo> getAllLists( LoadDescriptions
= LoadDescriptions::NO );
G4VUserPhysicsList * createList( std::string name );
}

#endif

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#include "G4PhysicsLists/PhysListMgr.hh"
#include "NCrystal/internal/NCStrView.hh"
#include <cstdlib>
#include "G4PhysListFactory.hh"
#include "PluginUtils/PluginHelper.hh"

namespace PhysListMgr {
namespace {
struct dgcode_PluginDef_G4PL {
using plugin_fct_signature_t = G4VUserPhysicsList *();
static constexpr const char * plugin_type = "g4physlist";
};

G4VUserPhysicsList *
createReferencePhysicsList(const std::string& name)
{
//G4 provided reference lists:
G4PhysListFactory reflist_factory;
return reflist_factory.GetReferencePhysList(name);
}

std::vector<std::string> getAllReferenceListNames()
{
//G4 provided reference lists:
G4PhysListFactory reflist_factory;
auto refpl_buggy = reflist_factory.AvailablePhysLists();
//alternative endings for EM physics:
auto refplEM = reflist_factory.AvailablePhysListsEM();

//Workaround bug in G4PhysListFactory: QGSP is too much, ShieldingLEND is
//missing. Also, ShieldingLEND should only be there when G4LENDDATA is
//set.
static const std::string envG4LENDDATA = []() {
const char * envG4LENDDATA_cstr = std::getenv("G4LENDDATA");
return std::string( envG4LENDDATA_cstr ? envG4LENDDATA_cstr : "" );
}();

bool allowLEND = !envG4LENDDATA.empty();

std::vector<std::string> refpl;
bool sawShieldingLEND = false;
for (auto it = refpl_buggy.begin();it != refpl_buggy.end();++it) {
if (*it=="QGSP")
continue;
if (*it=="ShieldingLEND") {
sawShieldingLEND = true;
if (allowLEND)
refpl.push_back(*it);
} else {
refpl.push_back(*it);
}
}
if (allowLEND&&!sawShieldingLEND)
refpl.push_back("ShieldingLEND");

//combine hadronic and em parts (a large number admittedly):
std::vector<std::string> v;
v.reserve(128);
for (auto it = refpl.begin();it != refpl.end();++it) {
for (auto itEM = refplEM.begin();itEM!= refplEM.end();++itEM)
v.push_back(*it+*itEM);
}
return v;
}
}
}

std::vector<PhysListMgr::PhysListInfo>
PhysListMgr::getAllLists( LoadDescriptions load_descr_enum )
{
bool load_descr( load_descr_enum==LoadDescriptions::YES );
auto load_descr_ph( load_descr
? PluginHelper::LoadDescriptions::YES
: PluginHelper::LoadDescriptions::NO );
std::vector<PhysListMgr::PhysListInfo> res;

//First the G4 ref lists:
const std::string g4reflistdescr("Geant4 reference list");
for ( auto& reflistname : getAllReferenceListNames() ) {
if ( NCrystal::StrView( reflistname ).startswith("PL_") )
throw std::runtime_error("g4 ref lists are assumed"
" to never start with \"PL_\"");
res.emplace_back();
auto& e = res.back();
e.name = reflistname;
if ( load_descr )
e.description = g4reflistdescr;
}
//Then the custom plugins:

for ( auto & plugininfo : PluginHelper::getAvailablePlugins
<dgcode_PluginDef_G4PL>( load_descr_ph ) )
{
res.emplace_back();
auto& e = res.back();
e.name = std::string("PL_")+plugininfo.plugin_key;
e.pkg_name = plugininfo.pkgname;
if ( plugininfo.description.has_value() )
e.description = plugininfo.description.value();
}
return res;
}

G4VUserPhysicsList * PhysListMgr::createList( std::string name )
{
NCrystal::StrView name_sv(name);
if ( name_sv.startswith("PL_") ) {
//A custom plugins:
name_sv = name_sv.substr(3);//discard "PL_"
auto pl_fct
= PluginHelper::loadPlugin<dgcode_PluginDef_G4PL>(name_sv.to_string());
return pl_fct();
} else {
return createReferencePhysicsList( name );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,10 @@ void PhysicsListEmpty::ConstructProcess()
}



extern "C" {
G4VUserPhysicsList * sbldplugindef_g4physlist_Empty()
{
return new PhysicsListEmpty;
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
#include "Core/Python.hh"
#include "G4PhysicsLists/PhysicsListFactory.hh"
#include "G4PhysicsLists/PhysListMgr.hh"

namespace {
py::list pyPhysicsListFactory_getAllReferenceListNames()

py::list pyPhysListMgr_getLists( bool with_descr,
bool include_g4ref,
bool include_custom )
{
py::list l;
std::vector<std::string> v;
PhysicsListFactory::getAllReferenceListNames(v);
for (auto it=v.begin();it!=v.end();++it)
l.append(*it);
if ( !include_g4ref && !include_custom )
return l;
for ( auto& e : PhysListMgr::getAllLists() ) {
bool is_custom = !e.pkg_name.empty();
if ( !include_g4ref && !is_custom )
continue;
if ( !include_custom && is_custom )
continue;
if ( with_descr ) {
std::string descr;
if ( is_custom ) {
descr = "List defined in package ";
descr += e.pkg_name;
} else {
descr = "Geant4 reference list";
}
//FIXME: e.description could also be used?!?
l.append( py::make_tuple(py::str(e.name),
py::str(descr)) );
} else {
l.append( e.name );
}
}
return l;
}


}

PYTHON_MODULE( mod )
{
mod.def("getAllReferenceListNames",pyPhysicsListFactory_getAllReferenceListNames);
mod.def("_get_lists",&pyPhysListMgr_getLists);
}

This file was deleted.

Loading

0 comments on commit ef6fd5f

Please sign in to comment.