1
0
Fork 0
mirror of https://github.com/gwm17/catima.git synced 2024-11-22 18:28:51 -05:00

pybind module

This commit is contained in:
hrocho 2019-05-12 20:14:53 +02:00
parent 7088148f5b
commit 955334a0b6
2 changed files with 262 additions and 10 deletions

View File

@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.2.0) cmake_minimum_required(VERSION 3.2.0)
project(catima) project(catima)
############ options ############# ############ options #############
option(BUILD_SHARED_LIBS "build as shared library" ON) option(BUILD_SHARED_LIBS "build as shared library" ON)
option(PYTHON_MODULE "compile the Catima python module(requires numpy and cython installed)" OFF) option(PYTHON_MODULE "compile the Catima python module(requires numpy and cython installed)" ON)
option(TESTS "build tests" OFF) option(TESTS "build tests" OFF)
option(EXAMPLES "build examples" ON) option(EXAMPLES "build examples" ON)
option(APPS "build catima applications" ON) option(APPS "build catima applications" ON)
@ -104,14 +104,14 @@ if(PYTHON_MODULE)
if(NOT PYTHONINTERP_FOUND) if(NOT PYTHONINTERP_FOUND)
MESSAGE(SEND_ERROR "Python is required to build nurex python modules") MESSAGE(SEND_ERROR "Python is required to build nurex python modules")
endif(NOT PYTHONINTERP_FOUND) endif(NOT PYTHONINTERP_FOUND)
#find_package(pybind11 REQUIRED) find_package(pybind11 REQUIRED)
#set(PYBIND11_CPP_STANDARD -std=c++14) set(PYBIND11_CPP_STANDARD -std=c++14)
#pybind11_add_module(pycatima pymodule/pycatima) pybind11_add_module(pycatima pymodule/pycatima)
#target_include_directories(pycatima PUBLIC target_include_directories(pycatima PUBLIC
# $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
# $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/libs> $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/libs>
# $<INSTALL_INTERFACE:include>) $<INSTALL_INTERFACE:include>)
#target_link_libraries(pycatima PRIVATE catima) target_link_libraries(pycatima PRIVATE catima)
find_program(CYTHON_EXECUTABLE find_program(CYTHON_EXECUTABLE
NAMES cython cython2 cython3 cython.bat NAMES cython cython2 cython3 cython.bat

252
pymodule/pycatima.cpp Normal file
View File

@ -0,0 +1,252 @@
#include <exception>
#include <stdexcept>
#include <pybind11/pybind11.h>
#include <pybind11/operators.h>
#include <pybind11/numpy.h>
#include "catima/catima.h"
#include "catima/srim.h"
#include "catima/nucdata.h"
#include <iostream>
namespace py = pybind11;
using namespace catima;
void catima_info(){
printf("CATIMA version = 1.5\n");
printf("number of energy points = %d\n",max_datapoints);
printf("min energy point = 10^%lf MeV/u\n",logEmin);
printf("max energy point = 10^%lf MeV/u\n",logEmax);
}
py::list storage_info(){
py::list res;
for(int i=0; i<max_storage_data;i++){
auto& data = _storage.Get(i);
if(data.p.A>0 && data.p.Z && data.m.ncomponents()>0){
py::list mat;
for(int j=0; j<data.m.ncomponents();j++){
auto e = data.m.get_element(j);
mat.append(e.A);
mat.append(e.Z);
mat.append(e.stn);
}
py::dict d;
py::list p;
p.append(data.p.A);
p.append(data.p.Z);
d["projectile"] = p;
d["matter"] = mat;
d["config"] = py::cast(data.config);
res.append(d);
}
}
return res;
}
py::list get_energy_table(){
py::list r;
for(auto e : energy_table){
r.append(e);
}
return r;
}
py::list get_data(Projectile& p, const Material &m, const Config& c=default_config){
py::list r;
auto& data = _storage.Get(p, m, c);
py::list ran;
py::list rans;
py::list av;
for(double e:data.range){ran.append(py::float_(e));}
for(double e:data.range_straggling)rans.append(e);
for(double e:data.angular_variance)av.append(e);
r.append(ran);
r.append(rans);
r.append(av);
return r;
}
Material py_make_material(py::list d, double density=0.0, double ipot=0.0, double mass=0.0){
Material m;
if(density>0.0)m.density(density);
if(ipot>0.0)m.I(ipot);
if(mass>0.0)m.M(mass);
for(int i=0;i<d.size();i++){
py::list e(d[i]);
if(e.size() != 3)throw std::invalid_argument("invalid Material constructor argument");
double a = e[0].cast<double>();
int z = e[1].cast<int>();
double stn = e[2].cast<double>();
m.add_element(a,z,stn);
}
return m;
}
PYBIND11_MODULE(pycatima,m){
py::class_<Projectile>(m,"Projectile")
.def(py::init<>(),"constructor")
.def(py::init<double, double, double, double>(), "constructor", py::arg("A"),py::arg("Z"),py::arg("Q")=0, py::arg("T")=0)
.def("__call__",&Projectile::operator())
.def("A",[](const Projectile& p){return p.A;})
.def("Z",[](const Projectile& p){return p.Z;})
.def("Q",[](const Projectile& p){return p.Q;})
.def("T",[](const Projectile& p){return p.T;})
.def("T",[](Projectile& p, double v){p.T = v;});
//.def_readwrite("A", &Projectile::A)
//.def_readwrite("Z", &Projectile::Z)
//.def_readwrite("T", &Projectile::T)
//.def_readwrite("Q", &Projectile::Q);
py::class_<Material>(m,"Material")
.def(py::init<>(),"constructor")
.def(py::init(&py_make_material),"constructor", py::arg("elements"),py::arg("density")=0.0,py::arg("i_potential")=0.0, py::arg("mass")=0.0)
.def("add_element",&Material::add_element)
.def("ncomponents",&Material::ncomponents)
.def("density",py::overload_cast<>(&Material::density, py::const_), "get density")
.def("density",py::overload_cast<double>(&Material::density), "set density")
.def("molar_mass",py::overload_cast<>(&Material::M, py::const_), "get mass")
.def("thickness",py::overload_cast<>(&Material::thickness, py::const_), "get thickness")
.def("thickness",py::overload_cast<double>(&Material::thickness), "set thickness")
.def("thickness_cm",&Material::thickness_cm,"set thickness in cm unit")
.def("I",py::overload_cast<>(&Material::I, py::const_), "get I")
.def("I",py::overload_cast<double>(&Material::I), "set I");
py::class_<Layers>(m,"Layers")
.def(py::init<>(),"constructor")
.def("add",&Layers::add)
.def("num",&Layers::num)
.def("__getitem__",&Layers::operator[], py::is_operator())
.def("get",&Layers::operator[])
.def(py::self + py::self);
py::class_<Result>(m,"Result")
.def(py::init<>(),"constructor")
.def_readwrite("Ein", &Result::Ein)
.def_readwrite("Eout", &Result::Eout)
.def_readwrite("Eloss", &Result::Eloss)
.def_readwrite("range", &Result::range)
.def_readwrite("dEdxi", &Result::dEdxi)
.def_readwrite("dEdxo", &Result::dEdxo)
.def_readwrite("sigma_E", &Result::sigma_E)
.def_readwrite("sigma_a", &Result::sigma_a)
.def_readwrite("sigma_r", &Result::sigma_r)
.def_readwrite("tof", &Result::tof)
.def_readwrite("sp", &Result::sp)
.def("get_dict",[](const Result& r){
py::dict d;
d["Ein"] = r.Ein;
d["Eout"] = r.Eout;
d["Eloss"] = r.Eloss;
d["range"] = r.range;
d["dEdxi"] = r.dEdxi;
d["dEdxo"] = r.dEdxo;
d["sigma_E"] = r.sigma_E;
d["sigma_r"] = r.sigma_r;
d["sigma_a"] = r.sigma_a;
d["tof"] = r.tof;
d["sp"] = r.sp;
return d;
});
py::class_<MultiResult>(m,"MultiResult")
.def(py::init<>(),"constructor")
.def_readwrite("total_result", &MultiResult::total_result)
.def_readwrite("results", &MultiResult::results)
.def("getJSON",[](const MultiResult &r){
py::dict d;
py::list p;
d["result"] = r.total_result;
for(auto& entry:r.results){
p.append(py::cast(entry));
}
d["partial"] = p;
return d;
});
py::enum_<z_eff_type>(m,"z_eff_type")
.value("none", z_eff_type::none)
.value("pierce_blann", z_eff_type::pierce_blann)
.value("anthony_landorf", z_eff_type::anthony_landorf)
.value("hubert", z_eff_type::hubert)
.value("winger", z_eff_type::winger)
.value("schiwietz", z_eff_type::schiwietz)
.value("global", z_eff_type::global)
.value("atima14", z_eff_type::atima14);
py::enum_<skip_calculation>(m,"skip_calculation")
.value("skip_none", skip_calculation::skip_none)
.value("skip_tof", skip_calculation::skip_tof)
.value("skip_sigma_a", skip_calculation::skip_sigma_a)
.value("skip_sigma_r", skip_calculation::skip_sigma_r)
.value("skip_reactions", skip_calculation::skip_reactions);
py::enum_<corrections>(m,"corrections")
.value("no_barkas", corrections::no_barkas)
.value("no_lindhard", corrections::no_lindhard)
.value("no_shell_correction", corrections::no_shell_correction)
.value("no_highenergy", corrections::no_highenergy);
py::enum_<omega_types>(m,"omega_types")
.value("atima", omega_types::atima)
.value("bohr", omega_types::bohr);
py::enum_<low_energy_types>(m,"low_energy_types")
.value("srim_85", low_energy_types::srim_85)
.value("srim_95", low_energy_types::srim_95);
py::enum_<material>(m,"material")
.value("Plastics", material::Plastics)
.value("Air", material::Air)
.value("CH2", material::CH2)
.value("lH2", material::lH2)
.value("lD2", material::lD2)
.value("Water", material::Water)
.value("Diamond", material::Diamond)
.value("Glass", material::Glass)
.value("ALMG3", material::ALMG3)
.value("ArCO2_30", material::ArCO2_30)
.value("CF4", material::CF4)
.value("Isobutane", material::Isobutane)
.value("Kapton", material::Kapton)
.value("Mylar", material::Mylar)
.value("NaF", material::NaF)
.value("P10", material::P10)
.value("Polyolefin", material::Polyolefin)
.value("CmO2", material::CmO2)
.value("Suprasil", material::Suprasil)
.value("HAVAR", material::HAVAR)
.value("Steel", material::Steel)
.value("CO2", material::CO2);
py::class_<Config>(m,"Config")
.def(py::init<>(),"constructor")
.def_readwrite("z_effective", &Config::z_effective)
.def_readwrite("corrections", &Config::corrections)
.def_readwrite("calculation", &Config::calculation)
.def_readwrite("skip", &Config::skip)
.def("get",[](const Config &r){
py::dict d;
d["z_effective"] = r.z_effective;
d["corrections"] = r.corrections;
d["calculation"] = r.calculation;
d["skip"] = r.skip;
return d;
});
m.def("srim_dedx_e",&srim_dedx_e);
m.def("sezi_dedx_e",&sezi_dedx_e, "sezi_dedx_e", py::arg("Projectile"), py::arg("Material"), py::arg("Config")=default_config);
m.def("calculate",py::overload_cast<Projectile&, const Material&, const Config&>(&calculate),"calculate",py::arg("Projectile"), py::arg("Material"), py::arg("Config")=default_config);
m.def("dedx_from_range",py::overload_cast<Projectile&, double, const Material&, const Config&>(&dedx_from_range),"calculate",py::arg("Projectile"), py::arg("energy") ,py::arg("Material"), py::arg("config")=default_config);
m.def("dedx_from_range",py::overload_cast<Projectile&, const std::vector<double>&, const Material&, const Config&>(&dedx_from_range),"calculate",py::arg("Projectile"), py::arg("energy") ,py::arg("Material"), py::arg("config")=default_config);
//m.def("calculate",py::overload_cast<Projectile&, const Material&, double, const Config&>(&calculate), "calculate",py::arg("Projectile"), py::arg("Material"), py::arg("energy"), py::arg("config")=default_config);
m.def("get_material",py::overload_cast<int>(&get_material));
m.def("get_data",py::overload_cast<Projectile&, const Material&, const Config&>(get_data),"list of data",py::arg("projectile"),py::arg("material"),py::arg("Config")=default_config);
m.def("catima_info",&catima_info);
m.def("storage_info",&storage_info);
m.def("get_energy_table",&get_energy_table);
m.attr("max_datapoints") = max_datapoints;
m.attr("max_storage_data") = max_storage_data;
m.attr("logEmin")=logEmin;
m.attr("logEmax")=logEmax;
}