1
0
Fork 0
mirror of https://github.com/gwm17/catima.git synced 2024-11-29 21:48:51 -05:00
catima/catima.pyx

549 lines
17 KiB
Cython
Raw Normal View History

2017-07-31 20:27:31 -04:00
"""
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
"""
2017-07-25 12:19:11 -04:00
cimport catimac
2018-02-14 05:53:56 -05:00
from libcpp.vector cimport vector
2017-07-25 12:19:11 -04:00
from enum import IntEnum
import numpy
cdef class Material:
cdef catimac.Material cbase
2018-01-29 07:38:54 -05:00
def __cinit__(self, elements=None, thickness=None, density=None, i_potential=None):
2017-07-25 12:19:11 -04:00
self.cbase = catimac.Material()
2017-07-31 20:27:31 -04:00
if(elements and (isinstance(elements[0],float) or isinstance(elements[0],int))):
2017-07-25 12:19:11 -04:00
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])
2017-12-14 09:29:23 -05:00
self.cbase.calculate()
2017-08-01 11:34:44 -04:00
if(not thickness is None):
self.thickness(thickness)
if(not density is None):
self.density(density)
2018-01-29 07:38:54 -05:00
if(not i_potential is None):
self.I(i_potential)
2017-07-25 12:19:11 -04:00
2017-07-31 20:27:31 -04:00
cdef from_c(self, catimac.Material &other):
self.cbase = other
2017-08-01 11:34:44 -04:00
cdef catimac.Material getc(self):
cdef catimac.Material res
res = self.cbase
return res
def copy(self):
res = Material()
res.cbase = self.cbase
return res
2017-07-31 20:27:31 -04:00
2017-07-25 12:19:11 -04:00
def add_element(self, a, z , s):
self.cbase.add_element(a, z, s)
def ncomponents(self):
return self.cbase.ncomponents()
def molar_mass(self):
return self.cbase.M()
def M(self):
return self.cbase.M()
def density(self, val=None):
if(val is None):
return self.cbase.density()
else:
return self.cbase.density(val)
def thickness(self, val=None):
if(val is None):
return self.cbase.thickness()
else:
return self.cbase.thickness(val)
2018-09-18 13:03:17 -04:00
def thickness_cm(self, val):
return self.cbase.thickness_cm(val)
2018-01-29 07:38:54 -05:00
def I(self, val=None):
if(val is None):
return self.cbase.I()
else:
return self.cbase.I(val)
2017-07-25 12:19:11 -04:00
2017-07-31 20:27:31 -04:00
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
2017-12-14 09:29:23 -05:00
STEEL = 221
METHANE = 222
2017-07-31 20:27:31 -04:00
def get_material(int matid):
res = Material()
cdef catimac.Material cres = catimac.get_material(matid);
res.from_c(cres)
return res
2017-07-25 12:19:11 -04:00
cdef class Target:
cdef catimac.Target cbase
2017-12-14 09:29:23 -05:00
def __cinit__(self,a,z,stn):
2017-07-25 12:19:11 -04:00
self.cbase.A = a
self.cbase.Z = z
2017-12-14 09:29:23 -05:00
self.cbase.stn = stn
2017-07-25 12:19:11 -04:00
def A(self):
return self.cbase.A
def Z(self):
return self.cbase.Z
2017-12-14 09:29:23 -05:00
def stn(self):
return self.cbase.stn
2017-07-25 12:19:11 -04:00
cdef class Layers:
2017-07-31 20:27:31 -04:00
cdef public:
materials
def __init__(self):
self.materials=[]
2017-07-25 12:19:11 -04:00
def add(self,Material m):
2017-08-01 11:34:44 -04:00
self.materials.append(m.copy())
2017-07-25 12:19:11 -04:00
def num(self):
2017-08-01 11:34:44 -04:00
return len(self.materials)
2017-07-31 20:27:31 -04:00
def get(self, key):
2017-08-01 11:34:44 -04:00
return self.materials[key]
2017-07-25 12:19:11 -04:00
def __getitem__(self, key):
2017-07-31 20:27:31 -04:00
if(isinstance(key,int) and key<self.num()):
return self.get(key)
return None
2017-08-01 11:34:44 -04:00
def __add__(self, other):
res = Layers()
for e in self.materials:
res.add(e)
if(isinstance(other,Layers)):
for e in other.materials:
res.add(e)
if(isinstance(other,Material)):
res.add(other.copy())
return res
cdef catimac.Layers getc(self):
cdef catimac.Layers res
#for l in self.materials:
# res.add(l.getc())
return res
2017-07-25 12:19:11 -04:00
cdef class Projectile:
cdef catimac.Projectile cbase
2017-07-31 20:27:31 -04:00
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
2017-07-25 12:19:11 -04:00
self.cbase.T = val;
def __call__(self,val=None):
if(val is None):
return self.cbase.T
else:
self.T(val)
return self
def A(self):
return self.cbase.A
def Z(self):
return self.cbase.Z
2017-07-31 20:27:31 -04:00
def Q(self):
return self.cbase.Q
2017-07-25 12:19:11 -04:00
cdef class Result:
cdef public double Ein
cdef public double Eout
cdef public double Eloss
cdef public double range
cdef public double dEdxi
cdef public double dEdxo
cdef public double sigma_E
cdef public double sigma_a
cdef public double sigma_r
cdef public double tof
2018-07-30 19:41:44 -04:00
cdef public double sp
2017-07-25 12:19:11 -04:00
def __init__(self):
self.Ein=0.0
self.Eout=0.0
self.Eloss=0.0
self.range=0.0
self.dEdxi=0.0
self.dEdxo=0.0
self.sigma_E=0.0
self.sigma_a=0.0
self.sigma_r=0.0
self.tof=0.0
2018-07-30 19:41:44 -04:00
self.sp=1.0
2017-07-25 12:19:11 -04:00
2017-07-31 20:27:31 -04:00
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,
2018-07-30 19:41:44 -04:00
"sp":self.sp,
2017-07-31 20:27:31 -04:00
}
2017-08-01 11:34:44 -04:00
def __getitem__(self,key):
d = self.get_dict()
if(key in d):
return d[key]
2017-07-25 12:19:11 -04:00
cdef setc(self,catimac.Result &val):
self.Ein=val.Ein
self.Eout=val.Eout
self.Eloss=val.Eloss
self.range=val.range
self.dEdxi=val.dEdxi
self.dEdxo=val.dEdxo
self.sigma_E=val.sigma_E
self.sigma_a=val.sigma_a
self.sigma_r=val.sigma_r
self.tof=val.tof
2018-07-30 19:41:44 -04:00
self.sp=val.sp
2017-07-25 12:19:11 -04:00
2017-07-31 20:27:31 -04:00
cdef class MultiResult:
2017-08-01 11:34:44 -04:00
cdef public Result total_result
cdef public results
cdef public total
2017-07-31 20:27:31 -04:00
def __init__(self):
self.total_result = Result()
self.results = []
2017-08-01 11:34:44 -04:00
self.total = {}
2017-07-31 20:27:31 -04:00
cdef setc(self, catimac.MultiResult &val):
self.total_result.setc(val.total_result)
for e in val.results:
self.results.append(e)
2017-08-01 11:34:44 -04:00
self.total = self.total_result.get_dict()
def __getitem__(self,key):
if(isinstance(key,int) and key<len(self.results)):
return self.results[key]
if(isinstance(key,str) and key in self.total):
return self.total[key]
return None
2017-08-02 06:17:34 -04:00
def getJSON(self):
res = {}
2017-10-17 10:05:55 -04:00
res["result"] = self.total
2017-08-02 06:17:34 -04:00
res["partial"] = []
for r in self.results:
res["partial"].append(r)
return res
2017-07-31 20:27:31 -04:00
2017-07-25 12:19:11 -04:00
class z_eff_type(IntEnum):
none = 0,
pierce_blann = 1
anthony_landorf = 2
hubert = 3
2018-01-15 09:11:51 -05:00
winger = 4
schiwietz = 5
global_code = 6
2018-01-18 13:20:42 -05:00
atima14 = 7
class omega_type(IntEnum):
atima = 0,
bohr = 1
2017-07-25 12:19:11 -04:00
class skip_calculation(IntEnum):
skip_none = 0
skip_tof = 1
skip_sigma_a = 2
skip_sigma_r = 4
class corrections(IntEnum):
no_barkas = 1
no_lindhard = 2
no_shell_correction = 4
2018-10-31 20:49:48 -04:00
no_highenergy = 8
2017-07-25 12:19:11 -04:00
cdef class Config:
cdef catimac.Config cbase
def __cinit__(self):
#self.cbase = catimac.Config()
2018-01-18 13:20:42 -05:00
self.cbase.z_effective = z_eff_type.pierce_blann
self.cbase.skip = 0
2019-05-10 15:02:51 -04:00
self.cbase.calculation = 1
self.cbase.corrections = 0
2017-07-25 12:19:11 -04:00
def z_effective(self, val=None):
if(val is None):
return self.cbase.z_effective
else:
self.cbase.z_effective = val
2019-05-10 15:02:51 -04:00
2017-07-25 12:19:11 -04:00
def skip_calculation(self, val=None):
if(val is None):
return self.cbase.skip
else:
self.cbase.skip = val
2019-05-10 15:02:51 -04:00
def corrections(self, val=None):
2017-07-25 12:19:11 -04:00
if(val is None):
2019-05-10 15:02:51 -04:00
return self.cbase.corrections
2017-07-25 12:19:11 -04:00
else:
2019-05-10 15:02:51 -04:00
self.cbase.corrections = val
def calculation(self, val=None):
2018-01-18 13:20:42 -05:00
if(val is None):
2019-05-10 15:02:51 -04:00
return self.cbase.calculation
2018-01-18 13:20:42 -05:00
else:
2019-05-10 15:02:51 -04:00
self.cbase.calculation = val
2018-01-21 18:37:22 -05:00
def set(self,other):
if("z_effective" in other):
self.cbase.z_effective = other["z_effective"]
2019-05-10 15:02:51 -04:00
if("calculation" in other):
self.cbase.calculation = other["calculation"]
if("corrections" in other):
self.cbase.corrections = other["corrections"]
2018-01-21 18:37:22 -05:00
2019-05-10 15:02:51 -04:00
2018-01-21 18:37:22 -05:00
def get(self):
res = {}
res["z_effective"] = self.cbase.z_effective
2019-05-10 15:02:51 -04:00
res["corrections"] = self.cbase.corrections
res["calculation"] = self.cbase.calculation
2018-01-21 18:37:22 -05:00
res["skip"] = self.cbase.skip
return res
2018-01-18 13:20:42 -05:00
def print_info(self):
print("z_effective = %s"%z_eff_type(self.cbase.z_effective))
2019-05-10 15:02:51 -04:00
print("calculation = %s"%omega_type(self.cbase.dedx_straggling))
2017-07-25 12:19:11 -04:00
default_config = Config()
2017-08-02 06:17:34 -04:00
def calculate(Projectile projectile, material, energy = None, config=default_config):
if(not energy is None):
projectile.T(energy)
if(isinstance(material,Material)):
return calculate_material(projectile, material, config = config)
if(isinstance(material,Layers)):
return calculate_layers(projectile, material, config = config)
def calculate_material(Projectile projectile, Material material, energy = None, Config config = default_config):
2017-07-25 12:19:11 -04:00
if(not energy is None):
projectile.T(energy)
cdef catimac.Result cres = catimac.calculate(projectile.cbase,material.cbase,config.cbase)
res = Result()
res.setc(cres)
return res
2017-08-02 06:17:34 -04:00
def calculate_layers(Projectile projectile, Layers layers, energy = None, Config config = default_config):
cdef catimac.Layers clayers
clayers = catimac.Layers()
clayers = get_clayers(layers)
if(not energy is None):
projectile.T(energy)
cdef catimac.MultiResult cres = catimac.calculate(projectile.cbase, clayers, config.cbase)
res = MultiResult()
res.setc(cres)
return res
2017-08-01 11:34:44 -04:00
cdef catimac.Layers get_clayers(Layers layers):
cdef catimac.Layers res
cdef catimac.Material m
for l in layers.materials:
m = get_cmaterial(l)
res.add(m)
return res
cdef catimac.Material get_cmaterial(Material material):
cdef catimac.Material res
res = material.cbase
return res
2017-10-08 18:54:14 -04:00
def projectile_range(Projectile projectile, Material material, energy = None, Config config = default_config):
2017-07-25 12:19:11 -04:00
if(isinstance(energy,numpy.ndarray)):
res = numpy.empty(energy.size)
for i,e in enumerate(energy):
res[i] = catimac.range(projectile.cbase, e, material.cbase, config.cbase)
return res
if(energy is None):
energy = projectile.T()
return catimac.range(projectile.cbase, energy, material.cbase, config.cbase);
def dedx_from_range(Projectile projectile, Material material, energy = None, Config config = default_config):
if(isinstance(energy,numpy.ndarray)):
2018-02-14 05:53:56 -05:00
res = catimac.dedx_from_range(projectile.cbase, <vector[double]>energy.tolist(), material.cbase, config.cbase)
return numpy.asarray(res);
if(isinstance(energy,list)):
return catimac.dedx_from_range(projectile.cbase, <vector[double]>energy, material.cbase, config.cbase)
2017-07-25 12:19:11 -04:00
if(energy is None):
energy = projectile.T()
2018-02-14 05:53:56 -05:00
return catimac.dedx_from_range(projectile.cbase, <double>energy, material.cbase, config.cbase);
2017-07-25 12:19:11 -04:00
def domega2de(Projectile projectile, Material material, energy = None, Config config = default_config):
if(isinstance(energy,numpy.ndarray)):
res = numpy.empty(energy.size)
for i,e in enumerate(energy):
res[i] = catimac.domega2de(projectile.cbase, e, material.cbase, config.cbase)
return res
if(energy is None):
energy = projectile.T()
return catimac.domega2de(projectile.cbase, energy, material.cbase, config.cbase);
def da2de(Projectile projectile, Material material, energy = None, Config config = default_config):
if(isinstance(energy,numpy.ndarray)):
res = numpy.empty(energy.size)
for i,e in enumerate(energy):
res[i] = catimac.da2de(projectile.cbase, e, material.cbase, config.cbase)
return res
if(energy is None):
energy = projectile.T()
return catimac.da2de(projectile.cbase, energy, material.cbase, config.cbase);
def dedx(Projectile projectile, Material material, energy = None, Config config = default_config):
if(isinstance(energy,numpy.ndarray)):
res = numpy.empty(energy.size)
for i,e in enumerate(energy):
res[i] = catimac.dedx(projectile.cbase, e, material.cbase, config.cbase)
2018-02-14 05:53:56 -05:00
return res
2017-07-25 12:19:11 -04:00
if(energy is None):
energy = projectile.T()
return catimac.dedx(projectile.cbase, energy, material.cbase, config.cbase)
2017-12-14 05:51:45 -05:00
def domega2dx(Projectile projectile, Material material, energy = None, Config config = default_config):
if(isinstance(energy,numpy.ndarray)):
res = numpy.empty(energy.size)
for i,e in enumerate(energy):
res[i] = catimac.domega2dx(projectile.cbase, e, material.cbase, config.cbase)
return res
if(energy is None):
energy = projectile.T()
return catimac.domega2dx(projectile.cbase, energy, material.cbase, config.cbase)
2017-07-25 12:19:11 -04:00
def energy_out(Projectile projectile, Material material, energy = None, Config config = default_config):
if(isinstance(energy,numpy.ndarray)):
2018-02-14 05:53:56 -05:00
res = catimac.energy_out(projectile.cbase, <vector[double]>energy.tolist(), material.cbase, config.cbase)
return numpy.asarray(res)
if(isinstance(energy,list)):
return catimac.energy_out(projectile.cbase, <vector[double]>energy, material.cbase, config.cbase)
2017-07-25 12:19:11 -04:00
if(energy is None):
energy = projectile.T()
2018-02-14 05:53:56 -05:00
return catimac.energy_out(projectile.cbase, <double>energy, material.cbase, config.cbase)
2017-07-25 12:19:11 -04:00
2018-02-14 09:04:49 -05:00
def w_magnification(Projectile projectile, Material material, energy = None, Config config = default_config):
if(energy is None):
energy = projectile.T()
return catimac.w_magnification(projectile.cbase,energy, material.cbase, config.cbase)
2018-02-08 12:58:12 -05:00
def bethek_dedx_e(Projectile projectile, Target t, Config c = default_config, Ipot=0.0):
return catimac.bethek_dedx_e(projectile.cbase, t.cbase,c.cbase,Ipot)
2018-01-22 13:36:50 -05:00
def lindhard(Projectile projectile):
return catimac.bethek_lindhard(projectile.cbase);
def lindhard_X(Projectile projectile):
return catimac.bethek_lindhard_X(projectile.cbase);
2017-07-25 12:19:11 -04:00
def z_effective(Projectile p, Target t, Config c = default_config):
return catimac.z_effective(p.cbase, t.cbase, c.cbase)
def z_eff_Pierce_Blann(double z, double beta):
return catimac.z_eff_Pierce_Blann(z,beta)
2018-01-15 09:11:51 -05:00
def z_eff_Anthony_Landford(double pz, double beta, double tz):
return catimac.z_eff_Anthony_Landford(pz, beta, tz);
def z_eff_Hubert(double pz, double E, double tz):
return catimac.z_eff_Hubert(pz, E, tz);
def z_eff_Winger(double pz, double beta, double tz):
return catimac.z_eff_Winger(pz, beta, tz);
def z_eff_global(double pz, double E, double tz):
return catimac.z_eff_global(pz, E, tz);
2018-01-18 13:20:42 -05:00
def z_eff_atima14(double pz, double E, double tz):
return catimac.z_eff_atima14(pz, E, tz);
2018-01-15 09:11:51 -05:00
def z_eff_Schiwietz(double pz, double beta, double tz):
return catimac.z_eff_Schiwietz(pz, beta, tz);
def gamma_from_T(double T):
return catimac.gamma_from_T(T);
2017-10-08 18:54:14 -04:00
2018-01-15 09:11:51 -05:00
def beta_from_T(double T):
return catimac.beta_from_T(T);
2017-10-08 18:54:14 -04:00
def get_data(Projectile projectile, Material material, Config config = default_config):
data = catimac.get_data(projectile.cbase, material.cbase, config.cbase)
return [data.range,data.range_straggling,data.angular_variance]
2017-10-18 19:36:54 -04:00
# constants
2017-10-08 18:54:14 -04:00
max_datapoints = catimac.max_datapoints
2017-10-18 19:36:54 -04:00
max_storage_data = catimac.max_storage_data
2017-12-11 13:53:42 -05:00
logEmin = catimac.logEmin
logEmax = catimac.logEmax
2017-10-08 18:54:14 -04:00
def energy_table(unsigned int i):
if(i<catimac.energy_table.num):
return catimac.energy_table(i)
else:
return -1.0
def get_energy_table():
r = [catimac.energy_table(x) for x in range(catimac.energy_table.num)]
return r
2017-10-18 19:36:54 -04:00
2017-10-19 07:43:09 -04:00
def storage_info():
2017-10-18 19:36:54 -04:00
res = []
for i in range(catimac.max_storage_data):
data = catimac._storage.Get(i)
if(data.p.A>0 and data.p.Z>0 and data.m.ncomponents()>0):
matter = []
for j in range(data.m.ncomponents()):
e = data.m.get_element(j)
2017-12-14 09:29:23 -05:00
matter.append([e.A,e.Z,e.stn])
2018-01-20 21:23:33 -05:00
res.append({"projectile":[data.p.A,data.p.Z],"matter":matter, "config":data.config})
2017-10-18 19:36:54 -04:00
return res
2017-12-11 13:53:42 -05:00
def catima_info():
2018-01-20 21:23:33 -05:00
print("CATIMA version = 1.1")
2017-12-11 13:53:42 -05:00
print("number of energy points = %g"%max_datapoints)
print("min energy point = 10^%g MeV/u"%logEmin)
print("max energy point = 10^%g MeV/u"%logEmax)