pythonradex 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pythonradex/LAMDA_file.py +129 -0
- pythonradex/__about__.py +4 -0
- pythonradex/__init__.py +4 -0
- pythonradex/atomic_transition.py +351 -0
- pythonradex/escape_probability.py +119 -0
- pythonradex/escape_probability_functions.py +198 -0
- pythonradex/flux.py +209 -0
- pythonradex/helpers.py +69 -0
- pythonradex/molecule.py +360 -0
- pythonradex/radiative_transfer.py +548 -0
- pythonradex/rate_equations.py +308 -0
- pythonradex-1.0.0.dist-info/METADATA +28 -0
- pythonradex-1.0.0.dist-info/RECORD +15 -0
- pythonradex-1.0.0.dist-info/WHEEL +4 -0
- pythonradex-1.0.0.dist-info/licenses/LICENSE.txt +21 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Created on Fri Sep 13 09:03:13 2024
|
|
5
|
+
|
|
6
|
+
@author: gianni
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import numba as nb
|
|
10
|
+
import numpy as np
|
|
11
|
+
from pythonradex import atomic_transition,helpers
|
|
12
|
+
import numbers
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class RateEquations():
|
|
16
|
+
|
|
17
|
+
def __init__(self,geometry,molecule,collider_densities,Tkin,N,
|
|
18
|
+
treat_line_overlap,ext_background,T_dust,tau_dust):
|
|
19
|
+
self.geometry = geometry
|
|
20
|
+
self.molecule = molecule
|
|
21
|
+
self.treat_line_overlap = treat_line_overlap
|
|
22
|
+
self.N = N
|
|
23
|
+
self.set_collision_rates(Tkin=Tkin,collider_densities=collider_densities)
|
|
24
|
+
self.set_ext_background(ext_background=ext_background)
|
|
25
|
+
self.set_dust(T_dust=T_dust,tau_dust=tau_dust)
|
|
26
|
+
self.compute_Unu0_Vnu0()
|
|
27
|
+
#equation of steady state: A*x=b, x=fractional population that we search
|
|
28
|
+
self.b = np.zeros(self.molecule.n_levels)
|
|
29
|
+
# the system of equations is not linearly independent
|
|
30
|
+
#thus, I replace one equation by the normalisation condition,
|
|
31
|
+
#i.e. x1+...+xn=1, where xi is the fractional population of level i
|
|
32
|
+
#I replace the first equation (arbitrary choice):
|
|
33
|
+
self.b[0] = 1
|
|
34
|
+
if not treat_line_overlap:
|
|
35
|
+
self.GammaR = self.GammaR_nu0
|
|
36
|
+
else:
|
|
37
|
+
self.GammaR = self.GammaR_averaged
|
|
38
|
+
|
|
39
|
+
def set_N(self,N):
|
|
40
|
+
self.N = N
|
|
41
|
+
|
|
42
|
+
def set_collision_rates(self,Tkin,collider_densities):
|
|
43
|
+
self.Tkin = Tkin
|
|
44
|
+
self.collider_densities = collider_densities
|
|
45
|
+
self.GammaC = self.molecule.get_GammaC(
|
|
46
|
+
Tkin=self.Tkin,collider_densities=collider_densities)
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def generate_constant_func(const_value):
|
|
50
|
+
def const_func(nu):
|
|
51
|
+
return np.ones_like(nu)*const_value
|
|
52
|
+
return const_func
|
|
53
|
+
|
|
54
|
+
def assign_func_nu(self,func_name,argument):
|
|
55
|
+
if isinstance(argument, numbers.Number):
|
|
56
|
+
assert argument >= 0, 'ext_background, T_dust or tau_dust cannot be negative'
|
|
57
|
+
setattr(self,func_name,self.generate_constant_func(const_value=argument))
|
|
58
|
+
else:
|
|
59
|
+
setattr(self,func_name,argument)
|
|
60
|
+
|
|
61
|
+
def set_ext_background(self,ext_background):
|
|
62
|
+
self.assign_func_nu(func_name='ext_background',argument=ext_background)
|
|
63
|
+
if not self.treat_line_overlap:
|
|
64
|
+
if isinstance(ext_background,numbers.Number):
|
|
65
|
+
#faster than evaluating the function at each nu0
|
|
66
|
+
self.Iext_nu0 = np.full(shape=self.molecule.nu0.shape,
|
|
67
|
+
fill_value=ext_background)
|
|
68
|
+
else:
|
|
69
|
+
self.Iext_nu0 = np.array([self.ext_background(nu0) for nu0 in
|
|
70
|
+
self.molecule.nu0])
|
|
71
|
+
|
|
72
|
+
def set_dust(self,T_dust,tau_dust):
|
|
73
|
+
self.no_dust = (T_dust == 0 and tau_dust == 0)
|
|
74
|
+
for func_name,func in {'T_dust':T_dust,'tau_dust':tau_dust}.items():
|
|
75
|
+
self.assign_func_nu(func_name=func_name,argument=func)
|
|
76
|
+
if not self.treat_line_overlap:
|
|
77
|
+
if isinstance(tau_dust,numbers.Number):
|
|
78
|
+
#fast:
|
|
79
|
+
self.tau_dust_nu0 = np.full(shape=self.molecule.nu0.shape,
|
|
80
|
+
fill_value=tau_dust)
|
|
81
|
+
else:
|
|
82
|
+
self.tau_dust_nu0 = self.tau_dust(self.molecule.nu0)
|
|
83
|
+
self.S_dust_nu0 = self.S_dust(nu=self.molecule.nu0)
|
|
84
|
+
|
|
85
|
+
def S_dust(self,nu):
|
|
86
|
+
T = np.atleast_1d(self.T_dust(nu))
|
|
87
|
+
return helpers.B_nu(nu=nu,T=T)
|
|
88
|
+
|
|
89
|
+
# We need to consider three cases:
|
|
90
|
+
#1. no averaging over line profile (i.e. evaluate everything at nu0);
|
|
91
|
+
#this cannot be used for overlapping lines, but dust is ok
|
|
92
|
+
#2. with averaging, no treatment of overlapping lines
|
|
93
|
+
#3. with averaging, with treatement of overlapping lines
|
|
94
|
+
#all three cases need to include dust continuum
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
#### case 1: "nu0 case" (everything evaluated at nu0, no overlapping lines allowed
|
|
98
|
+
# (because no averaging))
|
|
99
|
+
#basically, instead of averaging over the line profile, everything evaluated
|
|
100
|
+
#at nu0, so the averaging function is a delta func instead of line profile
|
|
101
|
+
|
|
102
|
+
def U_matrix_nu0(self):
|
|
103
|
+
#already multiply by 4*pi/h*nu0 here
|
|
104
|
+
U = np.zeros((self.molecule.n_levels,)*2)
|
|
105
|
+
n_low = self.molecule.nlow_rad_transitions
|
|
106
|
+
n_up = self.molecule.nup_rad_transitions
|
|
107
|
+
U[n_up,n_low] = self.molecule.A21
|
|
108
|
+
return U
|
|
109
|
+
|
|
110
|
+
def V_matrix_nu0(self):
|
|
111
|
+
#already multiply by 4*pi/h*nu0 here
|
|
112
|
+
V = np.zeros((self.molecule.n_levels,)*2)
|
|
113
|
+
n_low = self.molecule.nlow_rad_transitions
|
|
114
|
+
n_up = self.molecule.nup_rad_transitions
|
|
115
|
+
V[n_up,n_low] = self.molecule.B21
|
|
116
|
+
V[n_low,n_up] = self.molecule.B12
|
|
117
|
+
return V
|
|
118
|
+
|
|
119
|
+
def compute_Unu0_Vnu0(self):
|
|
120
|
+
self.U_nu0 = self.U_matrix_nu0()
|
|
121
|
+
self.V_nu0 = self.V_matrix_nu0()
|
|
122
|
+
|
|
123
|
+
@staticmethod
|
|
124
|
+
@nb.jit(nopython=True,cache=True)
|
|
125
|
+
def tau_line_nu0(level_population,N,trans_low_number,trans_up_number,
|
|
126
|
+
A21,phi_nu0,glow_rad_transitions,gup_rad_transitions,nu0):
|
|
127
|
+
#careful, don't use empty_like with an array that is made of integers...
|
|
128
|
+
tau_nu0 = np.empty(len(trans_low_number))
|
|
129
|
+
for i in range(len(trans_low_number)):
|
|
130
|
+
N1 = N * level_population[trans_low_number[i]]
|
|
131
|
+
N2 = N * level_population[trans_up_number[i]]
|
|
132
|
+
tau_nu0[i] = atomic_transition.tau_nu(
|
|
133
|
+
A21=A21[i],phi_nu=phi_nu0[i],
|
|
134
|
+
g_low=glow_rad_transitions[i],
|
|
135
|
+
g_up=gup_rad_transitions[i],N1=N1,N2=N2,nu=nu0[i])
|
|
136
|
+
return tau_nu0
|
|
137
|
+
|
|
138
|
+
@staticmethod
|
|
139
|
+
@nb.jit(nopython=True,cache=True)
|
|
140
|
+
def Ieff_nu0(beta_nu0,tau_tot_nu0,no_dust,S_dust_nu0,tau_dust_nu0,
|
|
141
|
+
n_levels,trans_low_number,trans_up_number,Iext_nu0):
|
|
142
|
+
Ieff = np.zeros((n_levels,n_levels))
|
|
143
|
+
for i in range(len(trans_low_number)):
|
|
144
|
+
tau_tot = tau_tot_nu0[i]
|
|
145
|
+
if no_dust or tau_tot==0:
|
|
146
|
+
psistar_eta_c = 0
|
|
147
|
+
else:
|
|
148
|
+
psistar_eta_c = (1-beta_nu0[i])*S_dust_nu0[i]*tau_dust_nu0[i]/tau_tot
|
|
149
|
+
nlow = trans_low_number[i]
|
|
150
|
+
nup = trans_up_number[i]
|
|
151
|
+
I = beta_nu0[i]*Iext_nu0[i] + psistar_eta_c
|
|
152
|
+
Ieff[nlow,nup] = I
|
|
153
|
+
Ieff[nup,nlow] = I
|
|
154
|
+
return Ieff
|
|
155
|
+
|
|
156
|
+
@staticmethod
|
|
157
|
+
@nb.jit(nopython=True,cache=True)
|
|
158
|
+
def mixed_term_nu0(beta_nu0,tau_tot_nu0,tau_line_nu0,n_levels,
|
|
159
|
+
trans_low_number,trans_up_number,A21):
|
|
160
|
+
#this is the term (Sum_l'' Chi^{dagger}_{l''l}) * Psi^*_nu * (Sum_l''' U_{l'l'''})
|
|
161
|
+
#if there is no overlap, only the term l''=l' and l'''=l survives:
|
|
162
|
+
#Psi^*_nu * Chi^{dagger}_l'l * U_l'l
|
|
163
|
+
#note that U_l'l is 0 if l'<l
|
|
164
|
+
term = np.zeros((n_levels,n_levels))
|
|
165
|
+
#already multiply by 4*pi/h*nu0 here
|
|
166
|
+
for i in range(len(trans_low_number)):
|
|
167
|
+
n_low = trans_low_number[i]
|
|
168
|
+
n_up = trans_up_number[i]
|
|
169
|
+
tau_tot = tau_tot_nu0[i]
|
|
170
|
+
if tau_tot == 0:
|
|
171
|
+
term[n_up,n_low] = 0
|
|
172
|
+
else:
|
|
173
|
+
term[n_up,n_low] = (1-beta_nu0[i])*tau_line_nu0[i]/tau_tot*A21[i]
|
|
174
|
+
return term
|
|
175
|
+
|
|
176
|
+
@staticmethod
|
|
177
|
+
@nb.jit(nopython=True,cache=True)
|
|
178
|
+
def transposed_GammaR(U_nu0,V_nu0,Ieff_nu0,mixed_term_nu0):
|
|
179
|
+
return np.transpose(U_nu0+V_nu0*Ieff_nu0-mixed_term_nu0)
|
|
180
|
+
|
|
181
|
+
@staticmethod
|
|
182
|
+
@nb.jit(nopython=True,cache=True)
|
|
183
|
+
def get_diagonal_GammaR(GammaR):
|
|
184
|
+
#the diagonal of GammaR is the negative row sum over the non-diagonal terms
|
|
185
|
+
return -(np.sum(GammaR,axis=0)-np.diag(GammaR))
|
|
186
|
+
|
|
187
|
+
def GammaR_nu0(self,level_population):
|
|
188
|
+
tau_line_nu0 = self.tau_line_nu0(
|
|
189
|
+
level_population=level_population,N=self.N,
|
|
190
|
+
trans_low_number=self.molecule.nlow_rad_transitions,
|
|
191
|
+
trans_up_number=self.molecule.nup_rad_transitions,
|
|
192
|
+
A21=self.molecule.A21,phi_nu0=self.molecule.phi_nu0,
|
|
193
|
+
glow_rad_transitions=self.molecule.glow_rad_transitions,
|
|
194
|
+
gup_rad_transitions=self.molecule.gup_rad_transitions,
|
|
195
|
+
nu0=self.molecule.nu0)
|
|
196
|
+
tau_tot_nu0 = tau_line_nu0 + self.tau_dust_nu0
|
|
197
|
+
beta_nu0 = self.geometry.beta(tau_tot_nu0)
|
|
198
|
+
Ieff_nu0 = self.Ieff_nu0(
|
|
199
|
+
beta_nu0=beta_nu0,tau_tot_nu0=tau_tot_nu0,
|
|
200
|
+
no_dust=self.no_dust,
|
|
201
|
+
S_dust_nu0=self.S_dust_nu0,tau_dust_nu0=self.tau_dust_nu0,
|
|
202
|
+
n_levels=self.molecule.n_levels,
|
|
203
|
+
trans_low_number=self.molecule.nlow_rad_transitions,
|
|
204
|
+
trans_up_number=self.molecule.nup_rad_transitions,
|
|
205
|
+
Iext_nu0=self.Iext_nu0)
|
|
206
|
+
mixed_term_nu0 = self.mixed_term_nu0(
|
|
207
|
+
beta_nu0=beta_nu0,tau_tot_nu0=tau_tot_nu0,
|
|
208
|
+
tau_line_nu0=tau_line_nu0,n_levels=self.molecule.n_levels,
|
|
209
|
+
trans_low_number=self.molecule.nlow_rad_transitions,
|
|
210
|
+
trans_up_number=self.molecule.nup_rad_transitions,
|
|
211
|
+
A21=self.molecule.A21)
|
|
212
|
+
#GammaR_ll' = U_l'l+... i.e. indices are interchanged, so I have to transpose
|
|
213
|
+
#see eq. 2.19 in Rybicki & Hummer (1992)
|
|
214
|
+
#note that the factor h*nu/4pi is already taken into account in all terms
|
|
215
|
+
GammaR = self.transposed_GammaR(
|
|
216
|
+
U_nu0=self.U_nu0,V_nu0=self.V_nu0,Ieff_nu0=Ieff_nu0,
|
|
217
|
+
mixed_term_nu0=mixed_term_nu0)
|
|
218
|
+
diag = self.get_diagonal_GammaR(GammaR=GammaR)
|
|
219
|
+
np.fill_diagonal(a=GammaR,val=diag)
|
|
220
|
+
return GammaR
|
|
221
|
+
|
|
222
|
+
#### cases 2: averaging over line profile
|
|
223
|
+
#note that U is proportional to phi_nu (when divided by h*nu), so we don't
|
|
224
|
+
#need to average the U term
|
|
225
|
+
|
|
226
|
+
def get_tau_tot_functions(self,level_population):
|
|
227
|
+
kwargs = {'level_population':level_population,'N':self.N,
|
|
228
|
+
'tau_dust':self.tau_dust}
|
|
229
|
+
return [self.molecule.get_tau_tot_nu(line_index=i,**kwargs)
|
|
230
|
+
for i in range(self.molecule.n_rad_transitions)]
|
|
231
|
+
|
|
232
|
+
def get_tau_line_functions(self,level_population):
|
|
233
|
+
kwargs = {'level_population':level_population,'N':self.N}
|
|
234
|
+
return [self.molecule.get_tau_line_nu(line_index=i,**kwargs) for i in
|
|
235
|
+
range(self.molecule.n_rad_transitions)]
|
|
236
|
+
|
|
237
|
+
def V_Ieff_averaged(self,tau_tot_functions):
|
|
238
|
+
V_Ieff = np.zeros((self.molecule.n_levels,)*2)
|
|
239
|
+
for i,trans in enumerate(self.molecule.rad_transitions):
|
|
240
|
+
def Ieff(nu):
|
|
241
|
+
tau_tot = tau_tot_functions[i](nu)
|
|
242
|
+
beta = self.geometry.beta(tau_tot)
|
|
243
|
+
betaIext = beta*self.ext_background(nu)
|
|
244
|
+
return np.where(tau_tot==0,betaIext,betaIext
|
|
245
|
+
+(1-beta)*self.S_dust(nu)*self.tau_dust(nu)/tau_tot)
|
|
246
|
+
Ieff_averaged = trans.line_profile.average_over_phi_nu(Ieff)
|
|
247
|
+
n_low = trans.low.number
|
|
248
|
+
n_up = trans.up.number
|
|
249
|
+
V_Ieff[n_low,n_up] = self.V_nu0[n_low,n_up]*Ieff_averaged
|
|
250
|
+
V_Ieff[n_up,n_low] = self.V_nu0[n_up,n_low]*Ieff_averaged
|
|
251
|
+
return V_Ieff
|
|
252
|
+
|
|
253
|
+
def mixed_term_averaged(self,tau_tot_functions,tau_line_functions):
|
|
254
|
+
mixed_term = np.zeros((self.molecule.n_levels,)*2)
|
|
255
|
+
#I choose that trans corresponds to the term U_lprime_lprimeprimeprime
|
|
256
|
+
#while the pairing transition corresponds to chi_lprimeprime_l. This makes
|
|
257
|
+
#it easier because I know that U_ab is zero if a<b, so I can simply iterate
|
|
258
|
+
#over all transitions to have all posibilities for the U term covered
|
|
259
|
+
for i,trans in enumerate(self.molecule.rad_transitions):
|
|
260
|
+
#add the transition itself to the list of pairing transitions
|
|
261
|
+
#(this is for the term lprimeprime=lprime and lprimeprimeprime=l):
|
|
262
|
+
pairing_transitions = self.molecule.overlapping_lines[i] + [i,]
|
|
263
|
+
for j in pairing_transitions:
|
|
264
|
+
def mixed(nu):
|
|
265
|
+
#for tau_tot it doesn't matter which transition I take,
|
|
266
|
+
#because they are overlapping
|
|
267
|
+
tau_tot = tau_tot_functions[i](nu)
|
|
268
|
+
beta = self.geometry.beta(tau_tot)
|
|
269
|
+
#need to be careful here: need to take tau_line of the
|
|
270
|
+
#lprimeprime -> l transition
|
|
271
|
+
tau_line = tau_line_functions[j](nu)
|
|
272
|
+
#A21 (U matrix) needs to be from the lprime -> lprimeprimeprime
|
|
273
|
+
#transition
|
|
274
|
+
A21 = trans.A21
|
|
275
|
+
return np.where(tau_tot==0,0,(1-beta)*tau_line/tau_tot*A21)
|
|
276
|
+
#need to average over the line profile of the
|
|
277
|
+
#lprime -> lprimeprimeprime transition!
|
|
278
|
+
mixed_averaged = trans.line_profile.average_over_phi_nu(mixed)
|
|
279
|
+
pairing_trans = self.molecule.rad_transitions[j]
|
|
280
|
+
#only non-diagonal terms need to be calculated, as the diagonal
|
|
281
|
+
#of Gamma will be calculated from the non-diagonal terms directly
|
|
282
|
+
if trans.up.number != pairing_trans.low.number:
|
|
283
|
+
mixed_term[trans.up.number,pairing_trans.low.number] += mixed_averaged
|
|
284
|
+
if trans.up.number != pairing_trans.up.number:
|
|
285
|
+
mixed_term[trans.up.number,pairing_trans.up.number] += -mixed_averaged
|
|
286
|
+
return mixed_term
|
|
287
|
+
|
|
288
|
+
def GammaR_averaged(self,level_population):
|
|
289
|
+
tau_line_functions = self.get_tau_line_functions(
|
|
290
|
+
level_population=level_population)
|
|
291
|
+
tau_tot_functions = self.get_tau_tot_functions(
|
|
292
|
+
level_population=level_population)
|
|
293
|
+
V_Ieff = self.V_Ieff_averaged(tau_tot_functions=tau_tot_functions)
|
|
294
|
+
mixed_term = self.mixed_term_averaged(tau_tot_functions=tau_tot_functions,
|
|
295
|
+
tau_line_functions=tau_line_functions)
|
|
296
|
+
GammaR = np.transpose(self.U_nu0+V_Ieff-mixed_term)
|
|
297
|
+
diag = self.get_diagonal_GammaR(GammaR=GammaR)
|
|
298
|
+
np.fill_diagonal(a=GammaR,val=diag)
|
|
299
|
+
return GammaR
|
|
300
|
+
|
|
301
|
+
def solve(self,level_population):
|
|
302
|
+
Gamma = self.GammaR(level_population=level_population) + self.GammaC
|
|
303
|
+
Gamma[0,:] = np.ones(self.molecule.n_levels)
|
|
304
|
+
fractional_population = np.linalg.solve(Gamma,b=self.b)
|
|
305
|
+
assert np.all(fractional_population >= 0),\
|
|
306
|
+
'negative level population, potentially due to high column'\
|
|
307
|
+
+'density and/or low collider density'
|
|
308
|
+
return fractional_population
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pythonradex
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: 1D non-LTE radiative transfer
|
|
5
|
+
Project-URL: Documentation, https://pythonradex.readthedocs.io/en/latest/
|
|
6
|
+
Project-URL: Issues, https://github.com/gica3618/pythonradex/issues
|
|
7
|
+
Project-URL: Source, https://github.com/gica3618/pythonradex
|
|
8
|
+
Author-email: Gianni Cataldi <cataldi.gia@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE.txt
|
|
11
|
+
Keywords: non-LTE,radex,radiative transfer
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Requires-Dist: numba>=0.61.0
|
|
20
|
+
Requires-Dist: numpy>=2.0
|
|
21
|
+
Requires-Dist: scipy>=1.14
|
|
22
|
+
Description-Content-Type: text/plain
|
|
23
|
+
|
|
24
|
+
pythonradex solves the 1D non-LTE radiative transfer for a homogeneous medium. It is a tool to quickly estimate the radiation from an astrophysical gas. It also provides a convenient function to read data files from the LAMDA database. pythonradex is a python re-implementation of the RADEX code, with additional functionality not included in RADEX (treatment of overlapping lines, treatment of dust continuum, output of spectra,...)
|
|
25
|
+
|
|
26
|
+
For more details, please refer to the documentation: http://pythonradex.readthedocs.io/
|
|
27
|
+
|
|
28
|
+
pythonradex is written and maintained by Gianni Cataldi
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
pythonradex/LAMDA_file.py,sha256=K-lIJa-5Qj_fwQm2iFJP99eDNOW2fQUB9IsRh_EaEVE,6304
|
|
2
|
+
pythonradex/__about__.py,sha256=VtFVQjqY6htZKsKHWnMX6fPxVvmPA5My0o-1h-RVj5E,133
|
|
3
|
+
pythonradex/__init__.py,sha256=8AAxjGySDAcXBqMpDwMRGDOGByrmmvw5tA-ZcJ3CaMo,90
|
|
4
|
+
pythonradex/atomic_transition.py,sha256=NsH_ngC1WqdJ2BZU80qa4BZVeyaBKq3wx53ojgFjj0E,13216
|
|
5
|
+
pythonradex/escape_probability.py,sha256=8gcXYdlOrSLk0x0rFXhUCNQCM7bKMKB0zSxgOPEBLeI,4317
|
|
6
|
+
pythonradex/escape_probability_functions.py,sha256=Px4peWRd5LsWmjEuqCJoljPNFq3sj0WZsn8Eo5nc3CM,9229
|
|
7
|
+
pythonradex/flux.py,sha256=q_yHAVn0VO6b20-lCNropHPBrM4vQMIrsc5P57spr5s,10589
|
|
8
|
+
pythonradex/helpers.py,sha256=JfoporFSdOBBn8kAYJQaAmSxGIFWm_nkSCpe85JRLS8,1985
|
|
9
|
+
pythonradex/molecule.py,sha256=6nuHkxt3TuPWuwr-BRGBf4llzrRycVoVmfb8GDC3_tE,17647
|
|
10
|
+
pythonradex/radiative_transfer.py,sha256=IV5lThKw44qsMWzSnwFmCoxSAMhzX0_2xn-tKBVzFas,31598
|
|
11
|
+
pythonradex/rate_equations.py,sha256=HRbSR4JtPy1Z8H14RFnamG9nqCL9ScYdrnPqPNzWkxA,14699
|
|
12
|
+
pythonradex-1.0.0.dist-info/METADATA,sha256=milpT8jfkaCPPXZ2_rv3fwlVIfwF4xIDL5WzENyZhTo,1457
|
|
13
|
+
pythonradex-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
14
|
+
pythonradex-1.0.0.dist-info/licenses/LICENSE.txt,sha256=biAf-Gv0h8Xr2r-CuwVZJsJKnj6WCL6KJfof8mz-M0U,1071
|
|
15
|
+
pythonradex-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Gianni Cataldi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|