1
0
Fork 0
mirror of https://github.com/gwm17/catima.git synced 2024-11-22 18:28:51 -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
from enum import IntEnum
import numpy
cdef class Material:
cdef catimac.Material cbase
def __cinit__(self, elements):
def __cinit__(self, elements=None):
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])
if(elements and isinstance(elements[0],list)):
for e in elements:
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):
self.cbase.add_element(a, z, s)
@ -36,6 +47,35 @@ cdef class Material:
else:
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 catimac.Target cbase
@ -50,10 +90,10 @@ cdef class Target:
cdef class Layers:
cdef catimac.Layers cbase
def __cinit__(self):
self.cbase = catimac.Layers()
self.materials = []
cdef public:
materials
def __init__(self):
self.materials=[]
def add(self,Material m):
self.cbase.add(m.cbase)
@ -62,21 +102,30 @@ cdef class Layers:
def num(self):
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):
if(isinstance(key,int)):
return self.materials[key]
if(isinstance(key,int) and key<self.num()):
return self.get(key)
return None
cdef class Projectile:
cdef catimac.Projectile cbase
def __cinit__(self, a, z, t=None,q=None):
self.cbase.A = a
self.cbase.Z = z
self.cbase.Q = z
if(q):
self.cbase.Q = q
if(t):
self.cbase.T = t
def T(self,val):
def __cinit__(self, A, Z, Q=None,T=None):
self.cbase.A = A
self.cbase.Z = Z
self.cbase.Q = Z
if(Q):
self.cbase.Q = Q
if(T):
self.cbase.T = T
def T(self,val=None):
if(val is None):
return self.cbase.T
self.cbase.T = val;
def __call__(self,val=None):
if(val is None):
@ -88,6 +137,8 @@ cdef class Projectile:
return self.cbase.A
def Z(self):
return self.cbase.Z
def Q(self):
return self.cbase.Q
cdef class Result:
cdef public double Ein
@ -112,6 +163,19 @@ cdef class Result:
self.sigma_r=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):
self.Ein=val.Ein
self.Eout=val.Eout
@ -124,6 +188,15 @@ cdef class Result:
self.sigma_r=val.sigma_r
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):
none = 0,
atima = 1
@ -176,6 +249,15 @@ def calculate(Projectile projectile, Material material, energy = None, Config co
res.setc(cres)
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):
if(isinstance(energy,numpy.ndarray)):
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.vector cimport vector
from libcpp cimport bool
cdef extern from "catima/structures.h" namespace "catima":
cdef struct Target:
@ -24,12 +32,14 @@ cdef extern from "catima/structures.h" namespace "catima":
double sigma_r
double tof
cdef cppclass MultiResult
cdef cppclass MultiResult:
vector[Result] results
Result total_result
cdef cppclass Material:
Material() except +
void add_element(double , int , double )
pair[Target,double] getElement(int)
pair[Target,double] get_element(int)
int ncomponents()
double M()
double density()
@ -45,6 +55,9 @@ cdef extern from "catima/structures.h" namespace "catima":
Material& operator[](int i)
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 struct Config:
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);
}
SECTION("equal operator check"){
EXPECT(water==water);
EXPECT(water==water2);
EXPECT(!(water==graphite));
}
}