pyatomdb 1.2.0__tar.gz → 1.2.2__tar.gz
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.
- {pyatomdb-1.2.0/pyatomdb.egg-info → pyatomdb-1.2.2}/PKG-INFO +9 -1
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/README.rst +8 -0
- pyatomdb-1.2.2/examples/wrapper_xspec_kappa_example.py +48 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb/__init__.py +1 -1
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb/apec.py +19 -21
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb/atomdb.py +1 -1
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb/spectrum.py +158 -31
- {pyatomdb-1.2.0 → pyatomdb-1.2.2/pyatomdb.egg-info}/PKG-INFO +9 -1
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb.egg-info/SOURCES.txt +2 -4
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/wrappers/kappa_xspec.py +22 -8
- pyatomdb-1.2.0/pyatomdb/web.py +0 -832
- pyatomdb-1.2.0/wrappers/__pycache__/apec_xspec.cpython-312.pyc +0 -0
- pyatomdb-1.2.0/wrappers/__pycache__/rsapec_xspec.cpython-312.pyc +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/COPYING.txt +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/MANIFEST.in +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/Makefile +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/apec.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/atomdb.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/atomic.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/conf.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/const.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/contact.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/examples.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/index.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/installation.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/license.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/models.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/modules.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/requirements.txt +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/spectrum.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/docs/util.rst +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/Rsapec_hitomi.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/Rsapec_hitomi.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/aciss_meg1_cy22.garf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/aciss_meg1_cy22.grmf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/ah100040030_sxs_cl2_HP_small.rmf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/ah100040030sxs_p0px1010_cl2_HP.pi +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/ah100040030sxs_p0px1010_ptsrc.arf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/apec_example_1_get_ionbal.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/apec_examples_1_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/apec_examples_1_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/apec_examples_1_2.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/apec_examples_1_2.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/atomdb_example_1_get_data.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/atomdb_example_2_get_maxwell.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/atomdb_examples_2_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/atomdb_examples_2_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/atomdb_examples_2_2.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/atomdb_examples_2_2.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/calc_power.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/calc_power_examples_1_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/calc_power_examples_1_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/calc_power_nei.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/calc_power_nei_examples_1_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/calc_power_nei_examples_1_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/first_installation.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/make_line_list.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/make_spectrum.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/new_make_spectrum.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/output.txt +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/photoionization_data.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/rsapec.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_NEIsession_examples.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_NEIsession_linelist_examples.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_kappa_examples_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_kappa_examples_1.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_kappa_examples_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_kappa_examples_2.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_kappa_examples_2.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_kappa_examples_2.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_1.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_1_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_1_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_1b.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_1b_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_1b_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_2.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_2_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_2_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_2b.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_2b_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_2b_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_3_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_3_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_3_abund.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_4_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_4_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_4_abund.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_5_linelist.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_6_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_6_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_6_line_emissivity.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_7_1.pdf +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_7_1.svg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_7_nei.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_examples_8_nei_linelist.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/spectrum_session_linelist_examples.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/examples/wrapper_xspec_examples.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/linear_approx.c +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb/atomic.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb/const.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb/util.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb.egg-info/dependency_links.txt +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb.egg-info/requires.txt +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyatomdb.egg-info/top_level.txt +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/pyproject.toml +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/setup.cfg +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/setup.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/tests/__init__.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/tests/test1.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/wrappers/IonE_apec_xspec.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/wrappers/apec_xspec.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/wrappers/bapec_xspec.py +0 -0
- {pyatomdb-1.2.0 → pyatomdb-1.2.2}/wrappers/rsapec_xspec.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyatomdb
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: AtomDB python library.
|
|
5
5
|
Author-email: Adam Foster <afoster@cfa.harvard.edu>
|
|
6
6
|
Maintainer-email: Adam Foster <afoster@cfa.harvard.edu>
|
|
@@ -344,3 +344,11 @@ Made multiple ionization calculation more transparent.
|
|
|
344
344
|
1.2.0
|
|
345
345
|
April 23rd 2026
|
|
346
346
|
Added in web.py, which is not useful as part of pyatomdb but does generate the online plotting content. This will undergo frequent revision. Other minor changes for making web content with Plotly and Dash.
|
|
347
|
+
|
|
348
|
+
1.2.1
|
|
349
|
+
August 13th 2026
|
|
350
|
+
Updated solve_ionbal_eigen to work with numpy >=2.5 (issues with matrix data indexing)
|
|
351
|
+
|
|
352
|
+
1.2.2
|
|
353
|
+
September 15th 2026
|
|
354
|
+
Corrections to eebrems in the 1 < T < 300keV
|
|
@@ -289,3 +289,11 @@ Made multiple ionization calculation more transparent.
|
|
|
289
289
|
1.2.0
|
|
290
290
|
April 23rd 2026
|
|
291
291
|
Added in web.py, which is not useful as part of pyatomdb but does generate the online plotting content. This will undergo frequent revision. Other minor changes for making web content with Plotly and Dash.
|
|
292
|
+
|
|
293
|
+
1.2.1
|
|
294
|
+
August 13th 2026
|
|
295
|
+
Updated solve_ionbal_eigen to work with numpy >=2.5 (issues with matrix data indexing)
|
|
296
|
+
|
|
297
|
+
1.2.2
|
|
298
|
+
September 15th 2026
|
|
299
|
+
Corrections to eebrems in the 1 < T < 300keV
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# temporarily add the wrappers folder to the path
|
|
2
|
+
import sys
|
|
3
|
+
sys.path.append('../wrappers')
|
|
4
|
+
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
|
|
7
|
+
from kappa_xspec import *
|
|
8
|
+
|
|
9
|
+
# declare a new model
|
|
10
|
+
# inital import creates pykappa, pyvkappa, pyvvkappa, analagous to apec, vapec, vvapec
|
|
11
|
+
|
|
12
|
+
m = xspec.Model('pykappa')
|
|
13
|
+
|
|
14
|
+
m.show()
|
|
15
|
+
|
|
16
|
+
m.pykappa.kT=3.0
|
|
17
|
+
|
|
18
|
+
m.pykappa.kappa = 2.5
|
|
19
|
+
|
|
20
|
+
# let's plot a spectrum
|
|
21
|
+
xspec.Plot.device='/xs'
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
#set dummy response
|
|
25
|
+
xspec.AllData.dummyrsp(0.1, 10, 10001,'lin')
|
|
26
|
+
|
|
27
|
+
xspec.Plot('model')
|
|
28
|
+
|
|
29
|
+
x1 = xspec.Plot.x(1)
|
|
30
|
+
m1 = xspec.Plot.model(1)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
m.pykappa.Velocity = 1000.0
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
xspec.Plot('model')
|
|
37
|
+
|
|
38
|
+
x2 = xspec.Plot.x(1)
|
|
39
|
+
m2 = xspec.Plot.model(1)
|
|
40
|
+
fig = plt.figure()
|
|
41
|
+
fig.show()
|
|
42
|
+
ax = fig.add_subplot(111)
|
|
43
|
+
ax.plot(x1,m1, label='0km/s')
|
|
44
|
+
ax.plot(x2,m2, label='1000km/s')
|
|
45
|
+
ax.legend(loc=0)
|
|
46
|
+
plt.draw()
|
|
47
|
+
|
|
48
|
+
zzz=input('Press enter')
|
|
@@ -1264,12 +1264,12 @@ def calc_ee_brems(E, T, N):
|
|
|
1264
1264
|
Returns
|
|
1265
1265
|
-------
|
|
1266
1266
|
array(float)
|
|
1267
|
-
ee_brems in photons cm^
|
|
1267
|
+
ee_brems in photons cm^3 s^-1 keV-1 at each point E.
|
|
1268
1268
|
This should be multiplied by the bin width to get flux per bin.
|
|
1269
1269
|
|
|
1270
1270
|
References
|
|
1271
1271
|
----------
|
|
1272
|
-
|
|
1272
|
+
S. Nozawa, K. Takahashi, Y. Kohyama and N. Itoh A&A, 499 3 (2009) 661-667
|
|
1273
1273
|
"""
|
|
1274
1274
|
#
|
|
1275
1275
|
# T is the electron temperature (in keV)
|
|
@@ -1279,7 +1279,8 @@ def calc_ee_brems(E, T, N):
|
|
|
1279
1279
|
|
|
1280
1280
|
# series of data constants
|
|
1281
1281
|
# Region I, k_BT<=1 keV
|
|
1282
|
-
|
|
1282
|
+
|
|
1283
|
+
from scipy.special import exp1
|
|
1283
1284
|
|
|
1284
1285
|
aI1 = numpy.array([(3.15847E+0, -2.52430E+0, 4.04877E-1, 6.13466E-1, 6.28867E-1, 3.29441E-1),
|
|
1285
1286
|
(2.46819E-2, 1.03924E-1, 1.98935E-1, 2.18843E-1, 1.20482E-1, -4.82390E-2),
|
|
@@ -1339,7 +1340,7 @@ def calc_ee_brems(E, T, N):
|
|
|
1339
1340
|
(0.0000000E+0, -1.6053650E+2, -4.6080700E+1, -2.7617000E+1, -3.4943210E+2),
|
|
1340
1341
|
(1.9970000E-1, 2.3392500E+1, 8.7301000E+0, 8.8453000E+0, 9.2205900E+1)])
|
|
1341
1342
|
# column aII_0j-aIII_2j, bIII_0j, bIII_1j; line j=0-8
|
|
1342
|
-
|
|
1343
|
+
|
|
1343
1344
|
aI = numpy.hstack((aI1,aI2))
|
|
1344
1345
|
|
|
1345
1346
|
inum1 = numpy.arange(11)
|
|
@@ -1367,17 +1368,10 @@ def calc_ee_brems(E, T, N):
|
|
|
1367
1368
|
tao = T/const.ME_KEV
|
|
1368
1369
|
# find the length of the input
|
|
1369
1370
|
Earray, Eisvec = util.make_vec(E)
|
|
1370
|
-
#if isinstance(E, (collections.Sequence, numpy.ndarray)):
|
|
1371
|
-
# x = E/T
|
|
1372
|
-
# (numx,) = x.shape
|
|
1373
|
-
#else:
|
|
1374
|
-
# Earray = numpy.array([E])
|
|
1375
1371
|
|
|
1376
1372
|
x = Earray/T
|
|
1377
1373
|
numx=len(Earray)
|
|
1378
1374
|
|
|
1379
|
-
#print "x", x
|
|
1380
|
-
#print "numx:", numx
|
|
1381
1375
|
GI = numpy.zeros((numx,))
|
|
1382
1376
|
AIIr = numpy.zeros((numx,))
|
|
1383
1377
|
BIIr = numpy.zeros((numx,))
|
|
@@ -1388,8 +1382,8 @@ def calc_ee_brems(E, T, N):
|
|
|
1388
1382
|
GpwIII = numpy.zeros((numx,))
|
|
1389
1383
|
if T<0.05:
|
|
1390
1384
|
ret = numpy.zeros(len(x), dtype=float)
|
|
1391
|
-
elif 0.05<=T<
|
|
1392
|
-
|
|
1385
|
+
elif 0.05<=T<1.:
|
|
1386
|
+
|
|
1393
1387
|
GI=numpy.zeros(len(x))
|
|
1394
1388
|
theta = (1/1.35) * ( numpy.log10(tao) + 2.65)
|
|
1395
1389
|
bigx = (1/2.5) * (numpy.log10(x) + 1.50)
|
|
@@ -1398,13 +1392,14 @@ def calc_ee_brems(E, T, N):
|
|
|
1398
1392
|
GI += aI[i,j]*(theta**i)*(bigx**j)
|
|
1399
1393
|
GI *= numpy.sqrt(8/(3*numpy.pi))
|
|
1400
1394
|
ret = 1.455e-16*N**2*numpy.exp(-x)/(x*numpy.sqrt(tao))*GI
|
|
1401
|
-
elif
|
|
1395
|
+
elif 1.<=T<300.:
|
|
1402
1396
|
taoII = tao
|
|
1397
|
+
Ei0[:,] = exp1(x)
|
|
1403
1398
|
for k in range(numx):
|
|
1404
|
-
def integrand(t):
|
|
1405
|
-
return numpy.exp(-1.0*t)/t
|
|
1406
|
-
[Ei0[k,],error] = scipy.integrate.quad(integrand,x[k,],\
|
|
1407
|
-
numpy.inf,args=())
|
|
1399
|
+
# def integrand(t):
|
|
1400
|
+
# return numpy.exp(-1.0*t)/t
|
|
1401
|
+
# [Ei0[k,],error] = scipy.integrate.quad(integrand,x[k,],\
|
|
1402
|
+
# numpy.inf,args=())
|
|
1408
1403
|
AIIr[k,] = numpy.sum(aII*taoII**(aIIj/8.)*x[k,]**(aIIi))
|
|
1409
1404
|
BIIr[k,] = numpy.sum(bII*taoII**(bIIj/8.)*x[k,]**(bIIi))
|
|
1410
1405
|
FCCII[k,] = 1.+numpy.sum(cII*taoII**(cIIj/6.)*x[k,]**(cIIi/8.))
|
|
@@ -1415,6 +1410,7 @@ def calc_ee_brems(E, T, N):
|
|
|
1415
1410
|
ret = 1.455e-16*N**2*numpy.exp(-x)/(x*numpy.sqrt(taoII))*GII
|
|
1416
1411
|
elif 300.<=T<7000.:
|
|
1417
1412
|
taoIII = tao
|
|
1413
|
+
Ei0[:,] = exp1(x)
|
|
1418
1414
|
for k in range(numx):
|
|
1419
1415
|
GpwIII[k,] = numpy.sum(aIII*taoIII**(aIIj/8.)*x[k,]**(aIIi))-\
|
|
1420
1416
|
numpy.exp(x[k,])*(-1.0)*Ei0[k,]*\
|
|
@@ -1423,6 +1419,7 @@ def calc_ee_brems(E, T, N):
|
|
|
1423
1419
|
(x*numpy.sqrt(taoIII))*GpwIII
|
|
1424
1420
|
else:
|
|
1425
1421
|
taoIV = tao
|
|
1422
|
+
Ei0[:,] = exp1(x)
|
|
1426
1423
|
GIV = 3./(4.*numpy.pi*numpy.sqrt(taoIV))*\
|
|
1427
1424
|
(28./3.+2.*x+x**2/2.+2.*(8./3.+4.*x/3.+x**2)*\
|
|
1428
1425
|
(numpy.log(2.*taoIV)-0.57721)-numpy.exp(x) \
|
|
@@ -1883,6 +1880,8 @@ def run_apec(fname):
|
|
|
1883
1880
|
chdulist.insert(0,PricHDU)
|
|
1884
1881
|
chdulist.insert(1,seccHDU)
|
|
1885
1882
|
tmpchdulist = pyfits.HDUList(chdulist)
|
|
1883
|
+
generate_apec_headerblurb(settings, tmplhdulist, tmpchdulist)
|
|
1884
|
+
|
|
1886
1885
|
if settings['Ionization']=='CIE':
|
|
1887
1886
|
tmpchdulist.writeto('%s_coco.fits'%(fileroot), overwrite=True, checksum=True)
|
|
1888
1887
|
elif settings['Ionization']=='NEI':
|
|
@@ -6074,16 +6073,15 @@ def _solve_ionbal_eigen(Z, Te, init_pop=False, tau=False, \
|
|
|
6074
6073
|
fspectmp = numpy.matrix(lefteigenvec) * numpy.matrix(work).transpose()
|
|
6075
6074
|
|
|
6076
6075
|
delt = 1.0
|
|
6077
|
-
|
|
6078
6076
|
worktmp = numpy.zeros(Z)
|
|
6079
6077
|
|
|
6080
6078
|
for itau, ttau in enumerate(tau_vec):
|
|
6081
6079
|
if Z >1:
|
|
6082
6080
|
for i in range(Z):
|
|
6083
|
-
worktmp[i] = fspectmp
|
|
6081
|
+
worktmp[i] = numpy.squeeze(fspectmp.item(i)*numpy.exp(dd.data['EIG'][kTindex,i]*delt*ttau))
|
|
6084
6082
|
|
|
6085
6083
|
else:
|
|
6086
|
-
worktmp[0] = fspectmp
|
|
6084
|
+
worktmp[0] = numpy.squeeze(fspectmp.item(i)*numpy.exp(dd.data['EIG'][kTindex]*delt*ttau))
|
|
6087
6085
|
|
|
6088
6086
|
frac = numpy.zeros(Z+1)
|
|
6089
6087
|
for i in range(Z):
|
|
@@ -2369,7 +2369,7 @@ def _calc_ionrec_ci(cidat, Te, extrap=False, ionpot=False):
|
|
|
2369
2369
|
elif ((cidat['par_type']> const.CI_DERE) &\
|
|
2370
2370
|
(cidat['par_type']<= const.CI_DERE+20)):
|
|
2371
2371
|
npts = cidat['par_type']-const.CI_DERE
|
|
2372
|
-
ci[ici] = _calc_ci_dere(Te[ici], ionpot, cidat['
|
|
2372
|
+
ci[ici] = _calc_ci_dere(Te[ici], ionpot, cidat['temperature'][:npts], \
|
|
2373
2373
|
cidat['ionrec_par'][:npts])
|
|
2374
2374
|
|
|
2375
2375
|
|
|
@@ -30,15 +30,16 @@ try:
|
|
|
30
30
|
except ImportError:
|
|
31
31
|
import pyfits
|
|
32
32
|
|
|
33
|
-
import numpy, os, hashlib, pickle, math
|
|
33
|
+
import numpy, os, hashlib, pickle, math#, re
|
|
34
34
|
# other pyatomdb modules
|
|
35
35
|
#import pyatomdb.atomic, pyatomdb.util, pyatomdb.const, atomdb, apec
|
|
36
36
|
from . import atomic, util, const, atomdb, apec
|
|
37
37
|
|
|
38
|
-
import
|
|
38
|
+
import wget, bz2#, time
|
|
39
39
|
import warnings
|
|
40
40
|
from astropy.modeling.models import Voigt1D
|
|
41
|
-
|
|
41
|
+
import time
|
|
42
|
+
#from scipy.interpolate import UnivariateSpline
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
def __make_spectrum(bins, index, linefile="$ATOMDB/apec_line.fits",\
|
|
@@ -1684,7 +1685,7 @@ class _Lorentzian_CDF():
|
|
|
1684
1685
|
return ret
|
|
1685
1686
|
|
|
1686
1687
|
|
|
1687
|
-
|
|
1688
|
+
from scipy.special import voigt_profile
|
|
1688
1689
|
class _Voigt_CDF():
|
|
1689
1690
|
"""
|
|
1690
1691
|
For fast interpolation, pre-calculate the CDF and interpolate it when
|
|
@@ -1715,7 +1716,7 @@ class _Voigt_CDF():
|
|
|
1715
1716
|
|
|
1716
1717
|
|
|
1717
1718
|
def __init__(self, sigma, gamma):
|
|
1718
|
-
|
|
1719
|
+
|
|
1719
1720
|
self.x = numpy.linspace(-12,12,2400)
|
|
1720
1721
|
self.broadentype='Voigt'
|
|
1721
1722
|
|
|
@@ -3004,7 +3005,7 @@ class CIESession():
|
|
|
3004
3005
|
|
|
3005
3006
|
|
|
3006
3007
|
|
|
3007
|
-
def _adjust_line_lambda(self, change, Z, z1, upper,lower, quantity="Epsilon", method="Replace", trackchanges=False):
|
|
3008
|
+
def _adjust_line_lambda(self, change, Z, z1, upper,lower, quantity="Epsilon", method="Replace", trackchanges=False, z1_drv=0):
|
|
3008
3009
|
"""
|
|
3009
3010
|
Change the emissivity or wavelength of a line. Integer parameters set to 0 mean "all". Note this all
|
|
3010
3011
|
happens in memory and does not edit the underlying files.
|
|
@@ -3030,6 +3031,8 @@ class CIESession():
|
|
|
3030
3031
|
"Divide" : divide existing value by change
|
|
3031
3032
|
"Add" : add change to existing value
|
|
3032
3033
|
"Subtract" : subtract change from existing
|
|
3034
|
+
z1_drv : int or array(int)
|
|
3035
|
+
which driving ions to switch the wavelengths for. Default (0) means all.
|
|
3033
3036
|
Returns
|
|
3034
3037
|
-------
|
|
3035
3038
|
None
|
|
@@ -3752,7 +3755,7 @@ class CIESession_RS(CIESession):
|
|
|
3752
3755
|
|
|
3753
3756
|
|
|
3754
3757
|
|
|
3755
|
-
def _adjust_line_lambda(self, change, Z, z1, upper,lower, quantity="Epsilon", method="Replace", trackchanges=False):
|
|
3758
|
+
def _adjust_line_lambda(self, change, Z, z1, upper,lower, quantity="Epsilon", method="Replace", trackchanges=False, z1_drv=0):
|
|
3756
3759
|
"""
|
|
3757
3760
|
Change the emissivity or wavelength of a line. Integer parameters set to 0 mean "all". Note this all
|
|
3758
3761
|
happens in memory and does not edit the underlying files.
|
|
@@ -3778,6 +3781,9 @@ class CIESession_RS(CIESession):
|
|
|
3778
3781
|
"Divide" : divide existing value by change
|
|
3779
3782
|
"Add" : add change to existing value
|
|
3780
3783
|
"Subtract" : subtract change from existing
|
|
3784
|
+
z1_drv : int or array(int)
|
|
3785
|
+
which driving ions to switch the wavelengths for. Default (0) means all.
|
|
3786
|
+
|
|
3781
3787
|
Returns
|
|
3782
3788
|
-------
|
|
3783
3789
|
None
|
|
@@ -5408,8 +5414,7 @@ class _LineData():
|
|
|
5408
5414
|
emax = max(eedges)
|
|
5409
5415
|
emin = min(eedges)
|
|
5410
5416
|
# identify all the good lines!
|
|
5411
|
-
igood = numpy.where((
|
|
5412
|
-
((elines < emin) & (eplu < emin)))[0]
|
|
5417
|
+
igood = numpy.where((eplu > emin) & (eneg < emax))[0]
|
|
5413
5418
|
spec = numpy.zeros(len(eedges))
|
|
5414
5419
|
# t0 = time.time()
|
|
5415
5420
|
for iline in igood:
|
|
@@ -7227,7 +7232,9 @@ class PShockSession(NEISession):
|
|
|
7227
7232
|
|
|
7228
7233
|
def return_linelist(self,Te, tau_u, specrange, tau_l = 0.0, init_pop='ionizing',specunit='A', \
|
|
7229
7234
|
teunit='keV', apply_aeff=False, by_ion_drv = False,\
|
|
7230
|
-
nearest=False, apply_binwidth=False
|
|
7235
|
+
nearest=False, apply_binwidth=False,\
|
|
7236
|
+
log_interp=True, freeze_ion_pop=False):
|
|
7237
|
+
|
|
7231
7238
|
"""
|
|
7232
7239
|
Get the list of line emissivities vs wavelengths
|
|
7233
7240
|
|
|
@@ -7257,8 +7264,14 @@ class PShockSession(NEISession):
|
|
|
7257
7264
|
by_ion_drv : bool
|
|
7258
7265
|
If true, keep lines which are the same but have different ion_drv separate.
|
|
7259
7266
|
Otherwise, merge them.
|
|
7260
|
-
nearest :
|
|
7267
|
+
nearest : bool
|
|
7268
|
+
calculate spectrum at nearest temperature in linelist, no
|
|
7269
|
+
interpolation. Ionization fraction calculation still exact.
|
|
7261
7270
|
apply_binwidth :
|
|
7271
|
+
log_interp : bool
|
|
7272
|
+
Perform linear interpolation on a logT/logEpsilon grid (default), or linear.
|
|
7273
|
+
freeze_ion_pop : bool
|
|
7274
|
+
If True, skip the ion population calculation, use init_pop as the final pop instead.
|
|
7262
7275
|
|
|
7263
7276
|
Returns
|
|
7264
7277
|
-------
|
|
@@ -8328,7 +8341,8 @@ class KappaSession(NEISession):
|
|
|
8328
8341
|
|
|
8329
8342
|
def return_linelist(self, Te, kappa, specrange, specunit='A', \
|
|
8330
8343
|
teunit='keV', apply_aeff=False, \
|
|
8331
|
-
|
|
8344
|
+
apply_binwidth=False,\
|
|
8345
|
+
log_interp=True):
|
|
8332
8346
|
"""
|
|
8333
8347
|
Get the list of line emissivities vs wavelengths
|
|
8334
8348
|
|
|
@@ -8348,6 +8362,9 @@ class KappaSession(NEISession):
|
|
|
8348
8362
|
apply_aeff : bool
|
|
8349
8363
|
If true, apply the effective area to the lines in the linelist to
|
|
8350
8364
|
modify their intensities.
|
|
8365
|
+
apply_binwidth :
|
|
8366
|
+
log_interp : bool
|
|
8367
|
+
Perform linear interpolation on a logT/logEpsilon grid (default), or linear.
|
|
8351
8368
|
|
|
8352
8369
|
Returns
|
|
8353
8370
|
-------
|
|
@@ -9043,7 +9060,7 @@ class _KappaSpectrum(_NEISpectrum):
|
|
|
9043
9060
|
|
|
9044
9061
|
for i, iikT in enumerate(ikT):
|
|
9045
9062
|
|
|
9046
|
-
s[i] += self.spectra[
|
|
9063
|
+
s[i] += self.spectra[iikT][Z][z1].return_spectrum(self.ebins,\
|
|
9047
9064
|
kT,\
|
|
9048
9065
|
ebins_checksum = self.ebins_checksum,\
|
|
9049
9066
|
thermal_broadening = self.thermal_broadening,\
|
|
@@ -9337,10 +9354,13 @@ class ir_data():
|
|
|
9337
9354
|
self.elements=elements
|
|
9338
9355
|
ionrec_data = {}
|
|
9339
9356
|
ir = pyfits.open(irfile)
|
|
9340
|
-
|
|
9341
|
-
|
|
9357
|
+
d = numpy.array(ir['KAPPA_IR'].data)
|
|
9358
|
+
d.dtype.names = [n.lower() for n in d.dtype.names]
|
|
9342
9359
|
|
|
9343
|
-
|
|
9360
|
+
for irdat in d:
|
|
9361
|
+
Z = irdat['element']
|
|
9362
|
+
|
|
9363
|
+
z1 = irdat['ion_init']
|
|
9344
9364
|
if not Z in ionrec_data.keys():
|
|
9345
9365
|
ionrec_data[Z] = {}
|
|
9346
9366
|
if not z1 in ionrec_data[Z].keys():
|
|
@@ -9351,15 +9371,15 @@ class ir_data():
|
|
|
9351
9371
|
ionrec_data[Z][z1]['DR']=False
|
|
9352
9372
|
|
|
9353
9373
|
# print(irdat)
|
|
9354
|
-
if ionrec_data[Z][z1][irdat['
|
|
9355
|
-
ionrec_data[Z][z1][irdat['
|
|
9356
|
-
|
|
9357
|
-
ionrec_data[Z][z1][irdat['
|
|
9374
|
+
if ionrec_data[Z][z1][irdat['tr_type'].decode()]==False:
|
|
9375
|
+
ionrec_data[Z][z1][irdat['tr_type'].decode()]={}
|
|
9376
|
+
|
|
9377
|
+
ionrec_data[Z][z1][irdat['tr_type'].decode()][irdat['ion_final']-1]=numpy.array(irdat)
|
|
9358
9378
|
|
|
9359
|
-
for ionpot in ir['
|
|
9360
|
-
ionrec_data[ionpot['
|
|
9379
|
+
for ionpot in ir['ionpot'].data:
|
|
9380
|
+
ionrec_data[ionpot['element']][ionpot['ion']]['IONPOT'] = ionpot['IONPOT']
|
|
9361
9381
|
|
|
9362
|
-
ionrec_data[ionpot['
|
|
9382
|
+
ionrec_data[ionpot['element']][ionpot['ion']]['IP_DERE'] = ionpot['IP_DERE']
|
|
9363
9383
|
# print(ionrec_data[12])
|
|
9364
9384
|
# zzz=input()
|
|
9365
9385
|
self.ionrecdata=ionrec_data
|
|
@@ -9386,7 +9406,7 @@ class ir_data():
|
|
|
9386
9406
|
for dd in self.ionrecdata[Z][z1]['CI'].keys():
|
|
9387
9407
|
ionpot = self.ionrecdata[Z][z1]['IONPOT']
|
|
9388
9408
|
d=self.ionrecdata[Z][z1]['CI'][dd]
|
|
9389
|
-
if ((d['
|
|
9409
|
+
if ((d['par_type']>=const.CI_DERE) & (d['par_type']<=const.CI_DERE+20)):
|
|
9390
9410
|
try:
|
|
9391
9411
|
ionpot = self.ionrecdata[Z][z1]['IP_DERE']
|
|
9392
9412
|
except:
|
|
@@ -9403,8 +9423,9 @@ class ir_data():
|
|
|
9403
9423
|
d = self.ionrecdata[Z][z1]['DR'][dd]
|
|
9404
9424
|
#print('d DR:',d)
|
|
9405
9425
|
#print(self.ionrecdata[Z][z1]['DR'])
|
|
9406
|
-
|
|
9407
|
-
|
|
9426
|
+
try:
|
|
9427
|
+
d==False
|
|
9428
|
+
except TypeError:
|
|
9408
9429
|
drrate = atomdb._calc_ionrec_dr(d, Tvec, extrap=True)
|
|
9409
9430
|
ionrec[d['ion_final']-1, d['ion_init']-1,:]+=drrate
|
|
9410
9431
|
else:
|
|
@@ -9413,9 +9434,10 @@ class ir_data():
|
|
|
9413
9434
|
if self.ionrecdata[Z][z1]['RR'] != False:
|
|
9414
9435
|
for dd in self.ionrecdata[Z][z1]['RR'].keys():
|
|
9415
9436
|
d = self.ionrecdata[Z][z1]['RR'][dd]
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
|
|
9437
|
+
# print('d RR:',d)
|
|
9438
|
+
try:
|
|
9439
|
+
d == False
|
|
9440
|
+
except TypeError:
|
|
9419
9441
|
rrrate = atomdb._calc_ionrec_rr(d, Tvec, extrap=True)
|
|
9420
9442
|
ionrec[d['ion_final']-1, d['ion_init']-1,:]+=rrrate
|
|
9421
9443
|
else:
|
|
@@ -9425,7 +9447,9 @@ class ir_data():
|
|
|
9425
9447
|
for dd in self.ionrecdata[Z][z1]['EA'].keys():
|
|
9426
9448
|
d = self.ionrecdata[Z][z1]['EA'][dd]
|
|
9427
9449
|
#print('d EA:',d)
|
|
9428
|
-
|
|
9450
|
+
try:
|
|
9451
|
+
d==False
|
|
9452
|
+
except TypeError:
|
|
9429
9453
|
earate = atomdb._calc_ionrec_ea(d, Tvec, extrap=True)
|
|
9430
9454
|
ionrec[d['ion_final']-1, d['ion_init']-1,:]+=earate
|
|
9431
9455
|
else:
|
|
@@ -9759,7 +9783,7 @@ def calc_ee_brems_spec(ebins, Te, dens, teunit='keV'):
|
|
|
9759
9783
|
electron-electron bremsstrahlung in ph cm^3 s^-1 bin^-1
|
|
9760
9784
|
|
|
9761
9785
|
"""
|
|
9762
|
-
|
|
9786
|
+
|
|
9763
9787
|
# convert temperature to keV if required
|
|
9764
9788
|
kT = util.convert_temp(Te, teunit, 'keV')
|
|
9765
9789
|
|
|
@@ -9774,6 +9798,109 @@ def calc_ee_brems_spec(ebins, Te, dens, teunit='keV'):
|
|
|
9774
9798
|
return ee
|
|
9775
9799
|
|
|
9776
9800
|
|
|
9801
|
+
|
|
9802
|
+
|
|
9803
|
+
def _broaden_lines(linelist, eedges, T,\
|
|
9804
|
+
thermal_broadening = False, \
|
|
9805
|
+
velocity_broadening = 0.0, \
|
|
9806
|
+
broaden_limit = 1e-20,\
|
|
9807
|
+
broaden_object=False):
|
|
9808
|
+
"""
|
|
9809
|
+
return the line emission spectrum at tempterature T
|
|
9810
|
+
|
|
9811
|
+
Parameters
|
|
9812
|
+
----------
|
|
9813
|
+
|
|
9814
|
+
eedges : array
|
|
9815
|
+
energy bin edges, keV
|
|
9816
|
+
T : float
|
|
9817
|
+
temperature in Kelvin
|
|
9818
|
+
ebins_checksum : string
|
|
9819
|
+
the md5 checksum of eedges
|
|
9820
|
+
thermal_broadening : bool
|
|
9821
|
+
true to apply thermal broadening
|
|
9822
|
+
velocity_broadening : float
|
|
9823
|
+
velocity broadening to apply, km/s. Set <=0 for none (default)
|
|
9824
|
+
broaden_limit : float
|
|
9825
|
+
only broaden lines stronger than this.
|
|
9826
|
+
broaden_object : class
|
|
9827
|
+
Object with routine "broaden" which applies line broadening. Usually a Gaussian.
|
|
9828
|
+
|
|
9829
|
+
Returns
|
|
9830
|
+
-------
|
|
9831
|
+
spectrum : array(float)
|
|
9832
|
+
Emissivity on eedges spectral bins of the lines, in ph cm^3 s^-1 bin^-1
|
|
9833
|
+
"""
|
|
9834
|
+
if velocity_broadening is None:
|
|
9835
|
+
velocity_broadening=0.0
|
|
9836
|
+
|
|
9837
|
+
if ((thermal_broadening == False) & \
|
|
9838
|
+
(velocity_broadening == False)):
|
|
9839
|
+
|
|
9840
|
+
spec,zzz = numpy.histogram(const.HC_IN_KEV_A/linelist['Lambda'], \
|
|
9841
|
+
bins=eedges, \
|
|
9842
|
+
weights = linelist['Epsilon'])
|
|
9843
|
+
else:
|
|
9844
|
+
|
|
9845
|
+
# ind = strong line indicies
|
|
9846
|
+
# nonind = weak line indicies
|
|
9847
|
+
ind = linelist['Epsilon']>broaden_limit
|
|
9848
|
+
nonind = ~ind
|
|
9849
|
+
|
|
9850
|
+
# calculate the widths of the strong lines
|
|
9851
|
+
llist = linelist[ind]
|
|
9852
|
+
|
|
9853
|
+
# get a raw dictionary of masses in amu
|
|
9854
|
+
masslist = atomic.Z_to_mass(1,raw=True)
|
|
9855
|
+
|
|
9856
|
+
if thermal_broadening==False:
|
|
9857
|
+
T=0.0
|
|
9858
|
+
Tb = 0.0
|
|
9859
|
+
else:
|
|
9860
|
+
Tb = util.convert_temp(T, 'K','keV')*const.ERG_KEV/(masslist[llist['Element']]*1e3*const.AMUKG)
|
|
9861
|
+
|
|
9862
|
+
if velocity_broadening <0:
|
|
9863
|
+
velocity_broadening = 0.0
|
|
9864
|
+
vb=0.0
|
|
9865
|
+
else:
|
|
9866
|
+
vb = (velocity_broadening * 1e5)**2
|
|
9867
|
+
|
|
9868
|
+
wcoeff = numpy.sqrt(Tb+vb) / (const.LIGHTSPEED*1e2)
|
|
9869
|
+
|
|
9870
|
+
elines = const.HC_IN_KEV_A/linelist['Lambda'][ind]
|
|
9871
|
+
width = wcoeff*elines
|
|
9872
|
+
|
|
9873
|
+
|
|
9874
|
+
# Filter out lines more than NSIGMALIMIT sigma outside the range
|
|
9875
|
+
NSIGMALIMIT=4
|
|
9876
|
+
eplu = elines+NSIGMALIMIT*width
|
|
9877
|
+
eneg = elines-NSIGMALIMIT*width
|
|
9878
|
+
emax = max(eedges)
|
|
9879
|
+
emin = min(eedges)
|
|
9880
|
+
# identify all the good lines!
|
|
9881
|
+
igood = numpy.where((eplu > emin) & (eneg < emax))[0]
|
|
9882
|
+
spec = numpy.zeros(len(eedges))
|
|
9883
|
+
# t0 = time.time()
|
|
9884
|
+
for iline in igood:
|
|
9885
|
+
|
|
9886
|
+
spec += broaden_object.broaden(const.HC_IN_KEV_A/llist['Lambda'][iline],\
|
|
9887
|
+
width[iline],eedges)*llist['Epsilon'][iline]
|
|
9888
|
+
|
|
9889
|
+
# t1 = time.time()
|
|
9890
|
+
# print("Broadeninging %i lines, in %f seconds"%(len(igood), t1-t0))
|
|
9891
|
+
spec = spec[1:]-spec[:-1]
|
|
9892
|
+
|
|
9893
|
+
|
|
9894
|
+
# Then add on the weak lines
|
|
9895
|
+
s,z = numpy.histogram(const.HC_IN_KEV_A/linelist['Lambda'][nonind], \
|
|
9896
|
+
bins = eedges,\
|
|
9897
|
+
weights = linelist['Epsilon'][nonind])
|
|
9898
|
+
spec+=s
|
|
9899
|
+
|
|
9900
|
+
return spec
|
|
9901
|
+
|
|
9902
|
+
|
|
9903
|
+
|
|
9777
9904
|
#### LEGACY CODE BEYOND THIS POINT
|
|
9778
9905
|
|
|
9779
9906
|
def __get_nei_line_emissivity(Z, z1, up, lo):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyatomdb
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: AtomDB python library.
|
|
5
5
|
Author-email: Adam Foster <afoster@cfa.harvard.edu>
|
|
6
6
|
Maintainer-email: Adam Foster <afoster@cfa.harvard.edu>
|
|
@@ -344,3 +344,11 @@ Made multiple ionization calculation more transparent.
|
|
|
344
344
|
1.2.0
|
|
345
345
|
April 23rd 2026
|
|
346
346
|
Added in web.py, which is not useful as part of pyatomdb but does generate the online plotting content. This will undergo frequent revision. Other minor changes for making web content with Plotly and Dash.
|
|
347
|
+
|
|
348
|
+
1.2.1
|
|
349
|
+
August 13th 2026
|
|
350
|
+
Updated solve_ionbal_eigen to work with numpy >=2.5 (issues with matrix data indexing)
|
|
351
|
+
|
|
352
|
+
1.2.2
|
|
353
|
+
September 15th 2026
|
|
354
|
+
Corrections to eebrems in the 1 < T < 300keV
|
|
@@ -88,6 +88,7 @@ examples/spectrum_session_examples_7_nei.py
|
|
|
88
88
|
examples/spectrum_session_examples_8_nei_linelist.py
|
|
89
89
|
examples/spectrum_session_linelist_examples.py
|
|
90
90
|
examples/wrapper_xspec_examples.py
|
|
91
|
+
examples/wrapper_xspec_kappa_example.py
|
|
91
92
|
pyatomdb/__init__.py
|
|
92
93
|
pyatomdb/apec.py
|
|
93
94
|
pyatomdb/atomdb.py
|
|
@@ -95,7 +96,6 @@ pyatomdb/atomic.py
|
|
|
95
96
|
pyatomdb/const.py
|
|
96
97
|
pyatomdb/spectrum.py
|
|
97
98
|
pyatomdb/util.py
|
|
98
|
-
pyatomdb/web.py
|
|
99
99
|
pyatomdb.egg-info/PKG-INFO
|
|
100
100
|
pyatomdb.egg-info/SOURCES.txt
|
|
101
101
|
pyatomdb.egg-info/dependency_links.txt
|
|
@@ -107,6 +107,4 @@ wrappers/IonE_apec_xspec.py
|
|
|
107
107
|
wrappers/apec_xspec.py
|
|
108
108
|
wrappers/bapec_xspec.py
|
|
109
109
|
wrappers/kappa_xspec.py
|
|
110
|
-
wrappers/rsapec_xspec.py
|
|
111
|
-
wrappers/__pycache__/apec_xspec.cpython-312.pyc
|
|
112
|
-
wrappers/__pycache__/rsapec_xspec.cpython-312.pyc
|
|
110
|
+
wrappers/rsapec_xspec.py
|
|
@@ -24,7 +24,9 @@ kappamodelobject.abund_xspectoatomdb['lodd'] = 'Lodd03'
|
|
|
24
24
|
|
|
25
25
|
pykappaInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
|
|
26
26
|
"kappa \"\" 3.0 2.0 2.0 100. 1000. 0.01",
|
|
27
|
-
"abund \"\" 1.0 0.0 0.0 10.0 10.0 0.01"
|
|
27
|
+
"abund \"\" 1.0 0.0 0.0 10.0 10.0 0.01",
|
|
28
|
+
"Redshift \"\" 0.0 0.0 0.0 10.0 10.0 0.01",
|
|
29
|
+
"Velocity \"km/s\" 0.0 0.0 0.0 1000.0 2000.0 0.01")
|
|
28
30
|
|
|
29
31
|
pyvkappaInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
|
|
30
32
|
"kappa \"\" 3.0 2.0 2.0 100. 1000. 0.01",
|
|
@@ -42,7 +44,9 @@ pyvkappaInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
|
|
|
42
44
|
"Ar \"\" 1.0 0.0 0.0 10.0 10.0 -0.01",
|
|
43
45
|
"Ca \"\" 1.0 0.0 0.0 10.0 10.0 -0.01",
|
|
44
46
|
"Fe \"\" 1.0 0.0 0.0 10.0 10.0 -0.01",
|
|
45
|
-
"Ni \"\" 1.0 0.0 0.0 10.0 10.0 -0.01"
|
|
47
|
+
"Ni \"\" 1.0 0.0 0.0 10.0 10.0 -0.01",
|
|
48
|
+
"Redshift \"\" 0.0 0.0 0.0 10.0 10.0 0.01",
|
|
49
|
+
"Velocity \"km/s\" 0.0 0.0 0.0 1000.0 2000.0 0.01")
|
|
46
50
|
|
|
47
51
|
|
|
48
52
|
pyvvkappaInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
|
|
@@ -73,7 +77,9 @@ pyvvkappaInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
|
|
|
73
77
|
"Cr \"\" 1.0 0.0 0.0 10.0 10.0 -0.01",
|
|
74
78
|
"Mn \"\" 1.0 0.0 0.0 10.0 10.0 -0.01",
|
|
75
79
|
"Fe \"\" 1.0 0.0 0.0 10.0 10.0 -0.01",
|
|
76
|
-
"Ni \"\" 1.0 0.0 0.0 10.0 10.0 -0.01"
|
|
80
|
+
"Ni \"\" 1.0 0.0 0.0 10.0 10.0 -0.01",
|
|
81
|
+
"Redshift \"\" 0.0 0.0 0.0 10.0 10.0 0.01",
|
|
82
|
+
"Velocity \"km/s\" 0.0 0.0 0.0 1000.0 2000.0 0.01")
|
|
77
83
|
|
|
78
84
|
|
|
79
85
|
def pykappa(engs, params, flux):
|
|
@@ -104,27 +110,35 @@ def pykappa(engs, params, flux):
|
|
|
104
110
|
|
|
105
111
|
# This is the call that will return everything. So set everything!
|
|
106
112
|
ebins = numpy.array(engs)
|
|
107
|
-
|
|
113
|
+
|
|
108
114
|
# kappa model has the 14 main elements
|
|
115
|
+
|
|
109
116
|
elarray = kappamodelobject.elements
|
|
110
117
|
abund = numpy.zeros(len(elarray))
|
|
111
118
|
|
|
119
|
+
|
|
120
|
+
offset = len(params)-3
|
|
112
121
|
|
|
113
|
-
if len(params)==
|
|
122
|
+
if len(params)==6:
|
|
114
123
|
# kappa case
|
|
115
124
|
elarray=[2,6,7,8,10,12,13,14,16,18,20,26,28]
|
|
116
125
|
abund = float(params[2])
|
|
117
|
-
elif len(params)==
|
|
126
|
+
elif len(params)==20:
|
|
118
127
|
# vkappa case
|
|
119
128
|
elarray=[1,2,6,7,8,9,10,12,13,14,16,18,20,26,28]
|
|
120
129
|
abund = numpy.array(params[2:17])
|
|
121
|
-
elif len(params)==
|
|
130
|
+
elif len(params)==32:
|
|
122
131
|
# vvkappa case
|
|
123
132
|
elarray=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,\
|
|
124
133
|
20,21,22,23,24,25,26,28]
|
|
125
134
|
abund = numpy.array(params[2:29])
|
|
126
|
-
|
|
127
135
|
|
|
136
|
+
redshift = float(params[offset])
|
|
137
|
+
velocity = float(params[offset+1])
|
|
138
|
+
|
|
139
|
+
kappamodelobject.set_response(ebins*(1.0+redshift), raw=True)
|
|
140
|
+
kappamodelobject.set_broadening(True, velocity_broadening=velocity)
|
|
141
|
+
|
|
128
142
|
T = float(params[0])
|
|
129
143
|
k = float(params[1])
|
|
130
144
|
|