""" 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 libcpp.vector cimport vector from enum import IntEnum import numpy cdef class Material: cdef catimac.Material cbase def __cinit__(self, elements=None, thickness=None, density=None, i_potential=None): self.cbase = catimac.Material() 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]) self.cbase.calculate() if(not thickness is None): self.thickness(thickness) if(not density is None): self.density(density) if(not i_potential is None): self.I(i_potential) cdef from_c(self, catimac.Material &other): self.cbase = other 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 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) def thickness_cm(self, val): return self.cbase.thickness_cm(val) def I(self, val=None): if(val is None): return self.cbase.I() else: return self.cbase.I(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 STEEL = 221 METHANE = 222 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 def __cinit__(self,a,z,stn): self.cbase.A = a self.cbase.Z = z self.cbase.stn = stn def A(self): return self.cbase.A def Z(self): return self.cbase.Z def stn(self): return self.cbase.stn cdef class Layers: cdef public: materials def __init__(self): self.materials=[] def add(self,Material m): self.materials.append(m.copy()) def num(self): return len(self.materials) def get(self, key): return self.materials[key] def __getitem__(self, key): if(isinstance(key,int) and keyenergy.tolist(), material.cbase, config.cbase) return numpy.asarray(res); if(isinstance(energy,list)): return catimac.dedx_from_range(projectile.cbase, energy, material.cbase, config.cbase) if(energy is None): energy = projectile.T() return catimac.dedx_from_range(projectile.cbase, energy, material.cbase, config.cbase); 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) return res if(energy is None): energy = projectile.T() return catimac.dedx(projectile.cbase, energy, material.cbase, config.cbase) 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) def energy_out(Projectile projectile, Material material, energy = None, Config config = default_config): if(isinstance(energy,numpy.ndarray)): res = catimac.energy_out(projectile.cbase, energy.tolist(), material.cbase, config.cbase) return numpy.asarray(res) if(isinstance(energy,list)): return catimac.energy_out(projectile.cbase, energy, material.cbase, config.cbase) if(energy is None): energy = projectile.T() return catimac.energy_out(projectile.cbase, energy, material.cbase, config.cbase) 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) def sezi_dedx_e(Projectile projectile, Target t): return catimac.sezi_dedx_e(projectile.cbase, t.cbase) 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) def lindhard(Projectile projectile): return catimac.bethek_lindhard(projectile.cbase); def lindhard_X(Projectile projectile): return catimac.bethek_lindhard_X(projectile.cbase); 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) 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); def z_eff_atima14(double pz, double E, double tz): return catimac.z_eff_atima14(pz, E, tz); 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); def beta_from_T(double T): return catimac.beta_from_T(T); 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] # constants max_datapoints = catimac.max_datapoints max_storage_data = catimac.max_storage_data logEmin = catimac.logEmin logEmax = catimac.logEmax def energy_table(unsigned int i): if(i0 and data.p.Z>0 and data.m.ncomponents()>0): matter = [] for j in range(data.m.ncomponents()): e = data.m.get_element(j) matter.append([e.A,e.Z,e.stn]) res.append({"projectile":[data.p.A,data.p.Z],"matter":matter, "config":data.config}) return res def catima_info(): print("CATIMA version = 1.1") 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)