1
0
Fork 0
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:
hrocho 2017-08-01 02:27:31 +02:00
parent 82c0800210
commit 8f09a32bbe
4 changed files with 206 additions and 20 deletions

View File

@ -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)

View File

@ -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
View 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()

View File

@ -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));
} }
} }