mirror of
https://github.com/gwm17/catima.git
synced 2025-02-17 01:48:50 -05:00
python branch update
This commit is contained in:
parent
82c0800210
commit
8f09a32bbe
116
catima.pyx
116
catima.pyx
|
@ -1,17 +1,28 @@
|
||||||
|
"""
|
||||||
|
catima python module
|
||||||
|
~~~~~~~~~~~
|
||||||
|
This module provides interface to the catima c++ library
|
||||||
|
:copyright: (c) 2017 by Andrej Prochazka
|
||||||
|
:licence: GNU Affero General Public License, see LICENCE for more details
|
||||||
|
"""
|
||||||
|
|
||||||
cimport catimac
|
cimport catimac
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
cdef class Material:
|
cdef class Material:
|
||||||
cdef catimac.Material cbase
|
cdef catimac.Material cbase
|
||||||
def __cinit__(self, elements):
|
def __cinit__(self, elements=None):
|
||||||
self.cbase = catimac.Material()
|
self.cbase = catimac.Material()
|
||||||
if(elements and isinstance(elements[0],int)):
|
if(elements and (isinstance(elements[0],float) or isinstance(elements[0],int))):
|
||||||
self.cbase.add_element(elements[0],elements[1],elements[2])
|
self.cbase.add_element(elements[0],elements[1],elements[2])
|
||||||
if(elements and isinstance(elements[0],list)):
|
if(elements and isinstance(elements[0],list)):
|
||||||
for e in elements:
|
for e in elements:
|
||||||
self.cbase.add_element(e[0],e[1],e[2])
|
self.cbase.add_element(e[0],e[1],e[2])
|
||||||
|
|
||||||
|
cdef from_c(self, catimac.Material &other):
|
||||||
|
self.cbase = other
|
||||||
|
|
||||||
def add_element(self, a, z , s):
|
def add_element(self, a, z , s):
|
||||||
self.cbase.add_element(a, z, s)
|
self.cbase.add_element(a, z, s)
|
||||||
|
|
||||||
|
@ -36,6 +47,35 @@ cdef class Material:
|
||||||
else:
|
else:
|
||||||
return self.cbase.thickness(val)
|
return self.cbase.thickness(val)
|
||||||
|
|
||||||
|
class material(IntEnum):
|
||||||
|
PLASTIC = 201
|
||||||
|
AIR = 202
|
||||||
|
CH2 = 203
|
||||||
|
LH2 = 204
|
||||||
|
LD2 = 205
|
||||||
|
WATER = 206
|
||||||
|
DIAMOND = 207
|
||||||
|
GLASS = 208
|
||||||
|
ALMG3 = 209
|
||||||
|
ARCO2_30 = 210
|
||||||
|
CF4 = 211
|
||||||
|
ISOBUTANE = 212
|
||||||
|
KAPTON = 213
|
||||||
|
MYLAR = 214
|
||||||
|
NAF = 215
|
||||||
|
P10 = 216
|
||||||
|
POLYOLEFIN = 217
|
||||||
|
CMO2 = 218
|
||||||
|
SUPRASIL = 219
|
||||||
|
HAVAR = 220
|
||||||
|
|
||||||
|
def get_material(int matid):
|
||||||
|
res = Material()
|
||||||
|
cdef catimac.Material cres = catimac.get_material(matid);
|
||||||
|
res.from_c(cres)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
cdef class Target:
|
cdef class Target:
|
||||||
cdef catimac.Target cbase
|
cdef catimac.Target cbase
|
||||||
|
|
||||||
|
@ -50,10 +90,10 @@ cdef class Target:
|
||||||
|
|
||||||
cdef class Layers:
|
cdef class Layers:
|
||||||
cdef catimac.Layers cbase
|
cdef catimac.Layers cbase
|
||||||
|
cdef public:
|
||||||
def __cinit__(self):
|
materials
|
||||||
self.cbase = catimac.Layers()
|
def __init__(self):
|
||||||
self.materials = []
|
self.materials=[]
|
||||||
|
|
||||||
def add(self,Material m):
|
def add(self,Material m):
|
||||||
self.cbase.add(m.cbase)
|
self.cbase.add(m.cbase)
|
||||||
|
@ -62,21 +102,30 @@ cdef class Layers:
|
||||||
def num(self):
|
def num(self):
|
||||||
return self.cbase.num()
|
return self.cbase.num()
|
||||||
|
|
||||||
|
def get(self, key):
|
||||||
|
cdef catimac.Material cmat = self.cbase[key]
|
||||||
|
res = Material()
|
||||||
|
res.from_c(cmat)
|
||||||
|
return res
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
if(isinstance(key,int)):
|
if(isinstance(key,int) and key<self.num()):
|
||||||
return self.materials[key]
|
return self.get(key)
|
||||||
|
return None
|
||||||
|
|
||||||
cdef class Projectile:
|
cdef class Projectile:
|
||||||
cdef catimac.Projectile cbase
|
cdef catimac.Projectile cbase
|
||||||
def __cinit__(self, a, z, t=None,q=None):
|
def __cinit__(self, A, Z, Q=None,T=None):
|
||||||
self.cbase.A = a
|
self.cbase.A = A
|
||||||
self.cbase.Z = z
|
self.cbase.Z = Z
|
||||||
self.cbase.Q = z
|
self.cbase.Q = Z
|
||||||
if(q):
|
if(Q):
|
||||||
self.cbase.Q = q
|
self.cbase.Q = Q
|
||||||
if(t):
|
if(T):
|
||||||
self.cbase.T = t
|
self.cbase.T = T
|
||||||
def T(self,val):
|
def T(self,val=None):
|
||||||
|
if(val is None):
|
||||||
|
return self.cbase.T
|
||||||
self.cbase.T = val;
|
self.cbase.T = val;
|
||||||
def __call__(self,val=None):
|
def __call__(self,val=None):
|
||||||
if(val is None):
|
if(val is None):
|
||||||
|
@ -88,6 +137,8 @@ cdef class Projectile:
|
||||||
return self.cbase.A
|
return self.cbase.A
|
||||||
def Z(self):
|
def Z(self):
|
||||||
return self.cbase.Z
|
return self.cbase.Z
|
||||||
|
def Q(self):
|
||||||
|
return self.cbase.Q
|
||||||
|
|
||||||
cdef class Result:
|
cdef class Result:
|
||||||
cdef public double Ein
|
cdef public double Ein
|
||||||
|
@ -112,6 +163,19 @@ cdef class Result:
|
||||||
self.sigma_r=0.0
|
self.sigma_r=0.0
|
||||||
self.tof=0.0
|
self.tof=0.0
|
||||||
|
|
||||||
|
def get_dict(self):
|
||||||
|
return {"Ein":self.Ein,
|
||||||
|
"Eout":self.Eout,
|
||||||
|
"Eloss":self.Eloss,
|
||||||
|
"range":self.range,
|
||||||
|
"dEdxi":self.dEdxi,
|
||||||
|
"dEdxo":self.dEdxo,
|
||||||
|
"sigma_E":self.sigma_E,
|
||||||
|
"sigma_a":self.sigma_a,
|
||||||
|
"sigma_r":self.sigma_r,
|
||||||
|
"tof":self.tof,
|
||||||
|
}
|
||||||
|
|
||||||
cdef setc(self,catimac.Result &val):
|
cdef setc(self,catimac.Result &val):
|
||||||
self.Ein=val.Ein
|
self.Ein=val.Ein
|
||||||
self.Eout=val.Eout
|
self.Eout=val.Eout
|
||||||
|
@ -124,6 +188,15 @@ cdef class Result:
|
||||||
self.sigma_r=val.sigma_r
|
self.sigma_r=val.sigma_r
|
||||||
self.tof=val.tof
|
self.tof=val.tof
|
||||||
|
|
||||||
|
cdef class MultiResult:
|
||||||
|
def __init__(self):
|
||||||
|
self.total_result = Result()
|
||||||
|
self.results = []
|
||||||
|
cdef setc(self, catimac.MultiResult &val):
|
||||||
|
self.total_result.setc(val.total_result)
|
||||||
|
for e in val.results:
|
||||||
|
self.results.append(e)
|
||||||
|
|
||||||
class z_eff_type(IntEnum):
|
class z_eff_type(IntEnum):
|
||||||
none = 0,
|
none = 0,
|
||||||
atima = 1
|
atima = 1
|
||||||
|
@ -176,6 +249,15 @@ def calculate(Projectile projectile, Material material, energy = None, Config co
|
||||||
res.setc(cres)
|
res.setc(cres)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def calculate(Projectile projectile, Layers layers, energy = None, Config config = default_config):
|
||||||
|
if(not energy is None):
|
||||||
|
projectile.T(energy)
|
||||||
|
cdef catimac.MultiResult cres = catimac.calculate(projectile.cbase, layers.cbase, config.cbase)
|
||||||
|
res = MultiResult()
|
||||||
|
res.setc(cres)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
def range(Projectile projectile, Material material, energy = None, Config config = default_config):
|
def range(Projectile projectile, Material material, energy = None, Config config = default_config):
|
||||||
if(isinstance(energy,numpy.ndarray)):
|
if(isinstance(energy,numpy.ndarray)):
|
||||||
res = numpy.empty(energy.size)
|
res = numpy.empty(energy.size)
|
||||||
|
|
17
catimac.pxd
17
catimac.pxd
|
@ -1,5 +1,13 @@
|
||||||
|
"""
|
||||||
|
catima cython
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
:copyright: (c) 2017 by Andrej Prochazka
|
||||||
|
:licence: GNU Affero General Public License, see LICENCE for more details
|
||||||
|
"""
|
||||||
|
|
||||||
from libcpp.pair cimport pair
|
from libcpp.pair cimport pair
|
||||||
from libcpp.vector cimport vector
|
from libcpp.vector cimport vector
|
||||||
|
from libcpp cimport bool
|
||||||
|
|
||||||
cdef extern from "catima/structures.h" namespace "catima":
|
cdef extern from "catima/structures.h" namespace "catima":
|
||||||
cdef struct Target:
|
cdef struct Target:
|
||||||
|
@ -24,12 +32,14 @@ cdef extern from "catima/structures.h" namespace "catima":
|
||||||
double sigma_r
|
double sigma_r
|
||||||
double tof
|
double tof
|
||||||
|
|
||||||
cdef cppclass MultiResult
|
cdef cppclass MultiResult:
|
||||||
|
vector[Result] results
|
||||||
|
Result total_result
|
||||||
|
|
||||||
cdef cppclass Material:
|
cdef cppclass Material:
|
||||||
Material() except +
|
Material() except +
|
||||||
void add_element(double , int , double )
|
void add_element(double , int , double )
|
||||||
pair[Target,double] getElement(int)
|
pair[Target,double] get_element(int)
|
||||||
int ncomponents()
|
int ncomponents()
|
||||||
double M()
|
double M()
|
||||||
double density()
|
double density()
|
||||||
|
@ -45,6 +55,9 @@ cdef extern from "catima/structures.h" namespace "catima":
|
||||||
Material& operator[](int i)
|
Material& operator[](int i)
|
||||||
Layers& operator=(const Layers& other)
|
Layers& operator=(const Layers& other)
|
||||||
|
|
||||||
|
cdef extern from "catima/material_database.h" namespace "catima":
|
||||||
|
cdef Material get_material(int)
|
||||||
|
|
||||||
cdef extern from "catima/config.h" namespace "catima":
|
cdef extern from "catima/config.h" namespace "catima":
|
||||||
cdef struct Config:
|
cdef struct Config:
|
||||||
char z_effective;
|
char z_effective;
|
||||||
|
|
91
tests/test.py
Normal file
91
tests/test.py
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0,"../build")
|
||||||
|
import unittest
|
||||||
|
import catima
|
||||||
|
|
||||||
|
class TestStructures(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_Projectile(self):
|
||||||
|
p = catima.Projectile(238,92)
|
||||||
|
self.assertEqual(p.A(),238)
|
||||||
|
self.assertEqual(p.Z(),92)
|
||||||
|
self.assertEqual(p.Q(),92)
|
||||||
|
|
||||||
|
p = catima.Projectile(238,92,90)
|
||||||
|
self.assertEqual(p.A(),238)
|
||||||
|
self.assertEqual(p.Z(),92)
|
||||||
|
self.assertEqual(p.Q(),90)
|
||||||
|
p.T(1000)
|
||||||
|
self.assertEqual(p.T(),1000)
|
||||||
|
self.assertEqual(p(),1000)
|
||||||
|
p(500)
|
||||||
|
self.assertEqual(p.T(),500)
|
||||||
|
self.assertEqual(p(),500)
|
||||||
|
|
||||||
|
p = catima.Projectile(238,92,90, T=100)
|
||||||
|
self.assertEqual(p.T(),100)
|
||||||
|
|
||||||
|
def test_Material(self):
|
||||||
|
mat = catima.Material()
|
||||||
|
mat.add_element(12,6,1)
|
||||||
|
self.assertEqual(mat.ncomponents(),1)
|
||||||
|
mat.add_element(1,1,2)
|
||||||
|
self.assertEqual(mat.ncomponents(),2)
|
||||||
|
|
||||||
|
mat2 = catima.Material([12.01,6,1])
|
||||||
|
self.assertEqual(mat2.ncomponents(),1)
|
||||||
|
self.assertEqual(mat2.molar_mass(),12.01)
|
||||||
|
|
||||||
|
mat3 = catima.Material([12,6,1])
|
||||||
|
self.assertEqual(mat3.ncomponents(),1)
|
||||||
|
self.assertEqual(mat3.molar_mass(),12)
|
||||||
|
|
||||||
|
water = catima.Material([[1,1,2],[16,8,1]])
|
||||||
|
self.assertEqual(water.molar_mass(),18)
|
||||||
|
|
||||||
|
mat2 = catima.Material([0,6,1])
|
||||||
|
self.assertEqual(mat2.ncomponents(),1)
|
||||||
|
self.assertAlmostEqual(mat2.molar_mass(),12,1)
|
||||||
|
|
||||||
|
def test_default_material(self):
|
||||||
|
m1 = catima.get_material(6);
|
||||||
|
self.assertAlmostEqual(m1.molar_mass(),12,1)
|
||||||
|
self.assertEqual(m1.ncomponents(),1)
|
||||||
|
self.assertAlmostEqual(m1.density(),2.0,1)
|
||||||
|
|
||||||
|
m2 = catima.get_material(catima.material.WATER)
|
||||||
|
self.assertEqual(m2.ncomponents(),2)
|
||||||
|
self.assertAlmostEqual(m2.molar_mass(),18,1)
|
||||||
|
self.assertAlmostEqual(m2.density(),1.0,1)
|
||||||
|
|
||||||
|
def test_layers(self):
|
||||||
|
graphite = catima.get_material(6);
|
||||||
|
graphite.thickness(0.5)
|
||||||
|
p10 = catima.get_material(catima.material.P10);
|
||||||
|
p10.thickness(0.01)
|
||||||
|
|
||||||
|
mat= catima.Layers()
|
||||||
|
self.assertEqual(mat.num(),0)
|
||||||
|
mat.add(graphite)
|
||||||
|
self.assertEqual(mat.num(),1)
|
||||||
|
self.assertAlmostEqual(mat[0].molar_mass(),12,1)
|
||||||
|
self.assertAlmostEqual(mat[0].thickness(),0.5,1)
|
||||||
|
self.assertAlmostEqual(mat[0].density(),2.0,1)
|
||||||
|
|
||||||
|
mat.add(p10)
|
||||||
|
self.assertEqual(mat.num(),2)
|
||||||
|
|
||||||
|
graphite.thickness(1.0)
|
||||||
|
graphite.density(1.8)
|
||||||
|
mat.add(graphite)
|
||||||
|
self.assertEqual(mat.num(),3)
|
||||||
|
self.assertAlmostEqual(mat[2].molar_mass(),12,1)
|
||||||
|
self.assertAlmostEqual(mat[0].thickness(),0.5,1)
|
||||||
|
self.assertAlmostEqual(mat[0].density(),2.0,1)
|
||||||
|
self.assertAlmostEqual(mat[2].thickness(),1.0,1)
|
||||||
|
self.assertAlmostEqual(mat[2].density(),1.8,1)
|
||||||
|
self.assertEqual(mat[3],None)
|
||||||
|
self.assertEqual(mat["a"],None)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
|
@ -49,7 +49,7 @@ const lest::test specification[] =
|
||||||
EXPECT(water2.M()==18);
|
EXPECT(water2.M()==18);
|
||||||
}
|
}
|
||||||
SECTION("equal operator check"){
|
SECTION("equal operator check"){
|
||||||
EXPECT(water==water);
|
EXPECT(water==water2);
|
||||||
EXPECT(!(water==graphite));
|
EXPECT(!(water==graphite));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user