├── .gitignore
├── .readthedocs.yaml
├── LICENSE.txt
├── README.rst
└── pyatomdb
├── COPYING.txt
├── MANIFEST.in
├── README.rst
├── README.txt
├── docs
├── Makefile
├── _static
│ └── readme.stuff
├── _templates
│ └── layout.html
├── apec.rst
├── atomdb.rst
├── atomic.rst
├── conf.py
├── const.rst
├── contact.rst
├── examples.rst
├── index.rst
├── installation.rst
├── license.rst
├── modules.rst
├── requirements.txt
├── spectrum.rst
└── util.rst
├── examples
├── Rsapec_hitomi.svg
├── aciss_meg1_cy22.garf
├── aciss_meg1_cy22.grmf
├── ah100040030_sxs_cl2_HP_small.rmf
├── ah100040030sxs_p0px1010_cl2_HP.pi
├── ah100040030sxs_p0px1010_ptsrc.arf
├── apec_example_1_get_ionbal.py
├── apec_examples_1_1.pdf
├── apec_examples_1_1.svg
├── apec_examples_1_2.pdf
├── apec_examples_1_2.svg
├── atomdb_example_1_get_data.py
├── atomdb_example_2_get_maxwell.py
├── atomdb_examples_2_1.pdf
├── atomdb_examples_2_1.svg
├── atomdb_examples_2_2.pdf
├── atomdb_examples_2_2.svg
├── calc_power.py
├── calc_power_examples_1_1.pdf
├── calc_power_examples_1_1.svg
├── calc_power_nei.py
├── calc_power_nei_examples_1_1.pdf
├── calc_power_nei_examples_1_1.svg
├── first_installation.py
├── make_line_list.py
├── make_spectrum.py
├── new_make_spectrum.py
├── osc_str.py
├── output.txt
├── photoionization_data.py
├── rsapec.py
├── spectrum_NEIsession_examples.py
├── spectrum_NEIsession_linelist_examples.py
├── spectrum_session_examples.py
├── spectrum_session_examples_1.py
├── spectrum_session_examples_1_1.pdf
├── spectrum_session_examples_1_1.svg
├── spectrum_session_examples_1b.py
├── spectrum_session_examples_1b_1.pdf
├── spectrum_session_examples_1b_1.svg
├── spectrum_session_examples_2.py
├── spectrum_session_examples_2_1.pdf
├── spectrum_session_examples_2_1.svg
├── spectrum_session_examples_2b.py
├── spectrum_session_examples_2b_1.pdf
├── spectrum_session_examples_2b_1.svg
├── spectrum_session_examples_3_1.pdf
├── spectrum_session_examples_3_1.svg
├── spectrum_session_examples_3_abund.py
├── spectrum_session_examples_4_1.pdf
├── spectrum_session_examples_4_1.svg
├── spectrum_session_examples_4_abund.py
├── spectrum_session_examples_5_linelist.py
├── spectrum_session_examples_6_1.pdf
├── spectrum_session_examples_6_1.svg
├── spectrum_session_examples_6_line_emissivity.py
├── spectrum_session_examples_7_1.pdf
├── spectrum_session_examples_7_1.svg
├── spectrum_session_examples_7_nei.py
├── spectrum_session_examples_8_nei_linelist.py
├── spectrum_session_linelist_examples.py
└── wrapper_xspec_examples.py
├── linear_approx.c
├── make_test_outputs.py
├── pyatomdb
├── __init__.py
├── apec.py
├── atomdb.py
├── atomic.py
├── const.py
├── spectrum.py
└── util.py
├── pyproject.toml
├── setup.py
├── tests
├── __init__.py
├── test1.py
└── testdata
│ ├── aciss_heg1_cy19.garf
│ ├── aciss_heg1_cy19.grmf
│ ├── test_set_response_spec1.npy
│ ├── test_set_response_spec1_309.npy
│ └── test_set_response_spec2_309.npz
└── wrappers
├── IonE_apec_xspec.py
├── apec_xspec.py
├── bapec_xspec.py
└── rsapec_xspec.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 |
5 | # C extensions
6 | *.so
7 |
8 | # Distribution / packaging
9 | .Python
10 | env/
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | *.egg-info/
23 | .installed.cfg
24 | *.egg
25 |
26 | # PyInstaller
27 | # Usually these files are written by a python script from a template
28 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
29 | *.manifest
30 | *.spec
31 |
32 | # Installer logs
33 | pip-log.txt
34 | pip-delete-this-directory.txt
35 |
36 | # Unit test / coverage reports
37 | htmlcov/
38 | .tox/
39 | .coverage
40 | .coverage.*
41 | .cache
42 | nosetests.xml
43 | coverage.xml
44 | *,cover
45 |
46 | # Translations
47 | *.mo
48 | *.pot
49 |
50 | # Django stuff:
51 | *.log
52 |
53 | # Sphinx documentation
54 | pyatomdb/docs/_build/
55 |
56 | # PyBuilder
57 | target/
58 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yaml
2 | # Read the Docs configuration file
3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4 |
5 | # Required
6 | version: 2
7 |
8 | # Set the version of Python and other tools you might need
9 | build:
10 | os: ubuntu-22.04
11 | tools:
12 | python: "3.11"
13 |
14 | # Build documentation in the docs/ directory with Sphinx
15 | sphinx:
16 | configuration: pyatomdb/docs/conf.py
17 |
18 |
19 | # We recommend specifying your dependencies to enable reproducible builds:
20 | # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
21 | python:
22 | install:
23 | - requirements: pyatomdb/docs/requirements.txt
24 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2015-16 Smithsonian Institution. Permission is granted to use, copy,
2 | modify, and distribute this software and its documentation for educational,
3 | research and non-profit purposes, without fee and without a signed
4 | licensing agreement, provided that this notice, including the following
5 | two paragraphs, appear in all copies, modifications and distributions.
6 | For commercial licensing, contact the Office of the Chief Information
7 | Officer, Smithsonian Institution, 380 Herndon Parkway, MRC 1010, Herndon,
8 | VA. 20170, 202-633-5256.
9 |
10 | This software and accompanying documentation is supplied "as is" without
11 | warranty of any kind. The copyright holder and the Smithsonian
12 | Institution: (1) expressly disclaim any warranties, express or implied,
13 | including but not limited to any implied warranties of merchantability,
14 | fitness for a particular purpose, title or non-infringement; (2) do not
15 | assume any legal liability or responsibility for the accuracy,
16 | completeness, or usefulness of the software; (3) do not represent that use
17 | of the software would not infringe privately owned rights; (4) do not
18 | warrant that the software is error-free or will be maintained, supported,
19 | updated or enhanced; (5) will not be liable for any indirect, incidental,
20 | consequential special or punitive damages of any kind or nature,
21 | including but not limited to lost profits or loss of data, on any basis
22 | arising from contract, tort or otherwise, even if any of the parties has
23 | been warned of the possibility of such loss or damage.
24 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | pyatomdb/README.txt
--------------------------------------------------------------------------------
/pyatomdb/COPYING.txt:
--------------------------------------------------------------------------------
1 | Copyright 2015-25 Smithsonian Institution. Permission is granted to use, copy,
2 | modify, and distribute this software and its documentation for educational,
3 | research and non-profit purposes, without fee and without a signed
4 | licensing agreement, provided that this notice, including the following
5 | two paragraphs, appear in all copies, modifications and distributions.
6 | For commercial licensing, contact the Office of the Chief Information
7 | Officer, Smithsonian Institution, 380 Herndon Parkway, MRC 1010, Herndon,
8 | VA. 20170, 202-633-5256.
9 |
10 | This software and accompanying documentation is supplied "as is" without
11 | warranty of any kind. The copyright holder and the Smithsonian
12 | Institution: (1) expressly disclaim any warranties, express or implied,
13 | including but not limited to any implied warranties of merchantability,
14 | fitness for a particular purpose, title or non-infringement; (2) do not
15 | assume any legal liability or responsibility for the accuracy,
16 | completeness, or usefulness of the software; (3) do not represent that use
17 | of the software would not infringe privately owned rights; (4) do not
18 | warrant that the software is error-free or will be maintained, supported,
19 | updated or enhanced; (5) will not be liable for any indirect, incidental,
20 | consequential special or punitive damages of any kind or nature,
21 | including but not limited to lost profits or loss of data, on any basis
22 | arising from contract, tort or otherwise, even if any of the parties has
23 | been warned of the possibility of such loss or damage.
24 |
--------------------------------------------------------------------------------
/pyatomdb/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include COPYING.txt
2 | include pyproject.toml
3 | recursive-include docs *
4 | recursive-include examples *
5 | recursive-include wrappers *
6 | prune docs/_*
7 |
--------------------------------------------------------------------------------
/pyatomdb/README.rst:
--------------------------------------------------------------------------------
1 | README.txt
--------------------------------------------------------------------------------
/pyatomdb/README.txt:
--------------------------------------------------------------------------------
1 | ========
2 | PYATOMDB
3 | ========
4 |
5 | This code is designed to interact with the AtomDB database. It is in active
6 | development but is now approaching feature complete for creating spectra
7 | and interacting with fitting codes like XSPEC and Sherpa.
8 |
9 | Full documentation can be found at http://atomdb.readthedocs.io
10 |
11 | ============
12 | Installation
13 | ============
14 |
15 | Standard python installation.
16 |
17 | #. From `PyPI `_ , using the simple ``pip install pyatomdb`` command.
18 | #. From `GitHub `_ , using the command ``git clone https://github.com/AtomDB/pyatomdb.git`` to get the source, then ``pip install -e python ``.
19 | #. If using ``Conda``: Pyatomdb is not packaged with Conda as it requires compiling of some C code and (as far as I can tell) Conda cannot handle this. I recommend installing the dependencies independently, e.g.: ``conda install requests wget "numpy>=1.9.0" "scipy>=1.9.0" joblib mock astropy pycurl``, then install pip within conda (``conda install pip``), and then ``pip install -e python ``.
20 | #. Using ``setuptools`` (deprecated): python setup.py install
21 |
22 |
23 |
24 |
25 |
26 | ===============
27 | Version History
28 | ===============
29 |
30 | 0.0.0.1
31 | July 17th 2015: initial release
32 |
33 | 0.0.0.2
34 | July 21st 2015: added ``dummyfirst`` keyword to
35 | ``pyatomdb.spectrum.make_spectrum``
36 |
37 | 0.0.0.3
38 | August 12th 2015: fixed some errors in spectrum.py. Updated readme.
39 |
40 | 0.0.0.4
41 | August 12th 2015: fixed example script in manual.
42 |
43 | 0.0.0.5
44 | August 17th 2015: added PI cross section graphing data.
45 | Updated get_data to fetch files from remote server
46 |
47 | 0.0.0.6
48 | August 18th 2015: Fixed bug with documentation
49 |
50 | 0.0.1.0
51 | September 23rd 2015: Added significant documentation. Converted all 'z0' to 'Z' and 'rmJ' to 'z1' throught the code for consistency.
52 |
53 | 0.0.1.1
54 | September 25th 2015: Major documentation revamp.
55 | Separated datacache from settings keyword
56 | Introduced automatic install and update into util package.
57 |
58 | 0.0.1.2
59 | October 13th 2015: More documentation improvements
60 | Removed use of "curl" library, as apparently is non-standard. Replaced with
61 | wget, ftplib and requests.
62 |
63 | 0.0.1.3
64 | November 5th 2015: Many minor bugfixes. Added "switch_version" to util package
65 | to allow looking at older AtomDB version data. Added use option to get total RRC
66 | emission using integral to infinity.
67 |
68 | 0.0.1.5
69 | February 12th 2016: As ever, bugfixes. Also added ability to calculate
70 | ionization balance to apec module.
71 |
72 | 0.0.1.6
73 | April 22nd 2016: Bugfixes! Also:
74 | Major change to get_maxwell_rate interface
75 | Added ability to apply RMF and ARF to spectra in spectrum module
76 | Fixed hydrogenic RRC calculation
77 |
78 | 0.0.1.7
79 | May 23rd 2016: Bugfix:update switch_version to get NEI files too.
80 |
81 | 0.0.1.8
82 | October 07th 2016: Bugfixes! Also:
83 | APEC now included in apec.py. Can create a full apec run from a par file.
84 |
85 | 0.0.1.9
86 | October 13th 2016: Bugfixes! wget was causing problems during file download due to bugs, Now fixed
87 |
88 | 0.0.2.0
89 | November 01st 2016: Removed use of sparse algebra. Wasn't accurate enough, causing issues with suprious lines in low ionization states.
90 |
91 | Implemented faster ionization balance calculations in "apec.solve_ionbal_eigen"
92 |
93 |
94 | 0.0.2.1
95 | November 16th 2016: Bugfix to the level population calculation for recombination. For ions with level resolved rates and PI cross sections, we were double counting. Fixed now.
96 |
97 | 0.0.2.2
98 | November 30th 2016: Bugfix to download of new files: urllib.urlcleanup now called more often.
99 |
100 | 0.0.2.3
101 | December 8th 2016: Updated to handle 3.0.7.
102 |
103 | 0.0.2.4
104 | January 16th 2017: Bugfix for installation, include joblib as a requirement
105 |
106 | 0.0.2.5
107 | January 17th 2017: Bugfix for installation, include mock as a requirement
108 |
109 | 0.0.3.0
110 | February 21st 2017: Introduced new way to calculated spectra, using the Session
111 | and Spec objects in spectrum.py. It is intended to make this the main way to
112 | calculate spectra, as it should lead to significant speed enhancements by
113 | avoiding lots of unnecessary recalculation of the same numbers.
114 |
115 | 0.0.3.1
116 | February 21st 2017: A series of bug fixes to installation and spectral calculation routines. Closes bugs #1, 2, 5 from github
117 |
118 | 0.0.3.2
119 | March 21st 2017: Several bug fixes and enhancements to the spectrum module. Updated setup.py to handle import of mock more gracefully
120 |
121 | 0.0.3.3
122 | May 5th 2017: Several bug fixes and initial inclusion of charge exchange model
123 |
124 | 0.0.3.4
125 | May 23rd 2017: Bug fix to spectrum.apply_response, now handles response files
126 | indexed from zero (thank you Lia Corrales for finding this issue)
127 |
128 | 0.5.0
129 | January 9th 2018: Major updates to include CX models. Increased version number to something relevant to 3 decimal style.
130 |
131 | 0.5.1
132 | February 14th 2018: Bugfix to use 64bit floats for ionization fraction calculation, which was occasionally causing issues.
133 |
134 | 0.5.2
135 | May 10th 2018: Bugfixes, including one where angstrom spectra where generated backwards.
136 |
137 | 0.5.3
138 | June 14th 2018: Bugfixes: NEI spectrum session fixed to assign bin units correctly when using a response file
139 |
140 | 0.5.4
141 | September 03rd 2018: Bugfix: NEI spectrum.Session.set_specbins now correctly resets the spectra when changed. Thanks to Shinya Nakashima for discovering this bug.
142 |
143 |
144 | 0.6.0
145 | November 20th 2018: Switch to python 3 support only. Python 2.7 support available for now through Github
146 |
147 | 0.7.0
148 | Bug fixes aplenty, mostly due to python 3 conversion.
149 |
150 | 0.7.1
151 | April 22nd 2019: Fixed bug occuring with spectrum continuum broadening.
152 |
153 | 0.7.2
154 | May 6th 2019: Add option 'ALL' to get_data to download all the data files for
155 | an ion at once
156 |
157 | 0.8.0
158 | January 27th 2020: Major overhaul of Spectrum module.
159 | Updated paths for the FTP server due to file move.
160 |
161 | 0.8.1
162 | February 5th 2020: Corrections to NEISpectrum. Spectrum summation much faster and
163 | bugs in logic fixed.
164 |
165 | 0.9.0
166 | March 20th 2020: Added PShockSession class to specturm module, mimicking XSPEC pshock (parallel shock) model. Other minor bugfixes.
167 |
168 | 0.10.0
169 | May 12th 2020: Major update to documentation, spectrum and atomdb modules. Significant rationalization of routines, making many non-public in the documentation. This should help new users understand what is going on. I apologise if it breaks whatever you were doing, please get in touch if the fix is not obvious.
170 |
171 | 0.10.1
172 | May 12th 2020: Minor packaging fixes
173 |
174 | 0.10.2
175 | May 27th 2020: Bugfix to read_data
176 |
177 | 0.10.3
178 | July 14th 2020: Added force keyword to switch_version. Amended make_linelist to handle non-51 temperature files
179 |
180 | 0.10.4
181 | July 20th 2020: Fixed PShockSession initialization error. Added automatic removal of old pickle files generated from fits files when detected.
182 |
183 | 0.10.5
184 | September 4th 2020: Fixed issue when handling temperatures above or below the maximum and minimum values in the APEC emissivity files. Added Electron-electron bremsstrahlung emission into APEC model.
185 |
186 | 0.10.6
187 | September 9th 2020: Fixed missing filename in build - README.txt had been renamed README.rst. Also included pycurl in requirements list
188 |
189 | 0.10.7
190 | October 12th 2020: Fixed a series of bugs - 28 and 29 on Github, and merged in ionization balance storage information pull request from Jim Slavin.
191 |
192 | 0.10.8
193 | November 9th 2020: Minor changes for compatibility with changes to kappa module.
194 |
195 | 0.10.9
196 | June 16th 2022: Several quality of life issues overdue for inclusion
197 |
198 | - Spectrum session now has a verbosity switch
199 | - Added more to the wrappers folder
200 | - Added the ability to update wavelengths on the fly in spectrum objects
201 | - Fixed errors when forcing use of older Mazzotta data for ionization
202 |
203 | 0.10.10
204 | July 22nd 2022: Updated spectrum.py set_response to handle 0keV minimum energy responses
205 |
206 | 0.10.11
207 | August 2nd 2022: Added "sparse" option to set_response, which uses sparse matrices in the RMF, allowing for large responses (e.g. XRISM) to be handled with limited memory usage.
208 |
209 | 0.10.12
210 | December 13th 2022
211 | Fixed(?) issues with curl library
212 | Corrected bug with return_spectrum leading to overestimate in E-E brems of ~20%
213 |
214 | 0.10.13
215 | February 6th 2023
216 | Another attempt to fix issues with curl library
217 |
218 | 0.11.0
219 | October 5th 2023
220 | Added rsapec model
221 |
222 | 0.11.1
223 | November 13th 2023
224 | Bugfix to atomic.elsymb_to_Z. Thank you to Guan-Fu Liu for spotting this.
225 |
226 | 0.11.2
227 | November 22nd 2023
228 | Added formatting to level list print outs, in spectrum.CIESession.format_linelist
229 |
230 | 0.11.3
231 | December 5th 2023
232 | Bugfix to spectrum.py, resolving issue 47
233 |
234 | 0.11.4
235 | January 17th 2024
236 | Updated atomic.py to hold uniform L shell labels up to L=27
237 |
238 | 0.11.5
239 | May 15th 2024
240 | Updated rmf handling routines in spectrum.py to handle RMF with inconsistent F_CHAN and EBOUNDS indexing.
241 |
242 | 0.11.6-7
243 | July 3rd 2024
244 | Documentation issues with Mock and ReadTheDocs being addressed.
245 |
246 | 0.11.8
247 | August 8th 2024
248 | Updates to replace deprecated keywords/functions in numpy, astropy and scipy.
249 | Should now work with scipy v1.14 and greater.
250 |
251 | 0.12.0
252 | October 1st 2024
253 | Updated to allow access to AtomDB v3.1.0 files. These differ due to variable length continuum arrays, and required a re-write to the spectrum module and apec modules for reading/writing the files.
254 |
255 | 1.0.0
256 | January 3rd 2025
257 | Updated to allow access to all AtomDB v3.1.0 files (couldn't do equilibrium previously). This version was used to compile AtomDB v3.1.0.
258 |
259 | 1.0.1
260 | January 31st 2025
261 | Updated to allow access to all AtomDB v3.1.x eigenvector files (path was hardcoded so v3.1.1 couldn't read them).
262 |
263 | 1.0.2
264 | January 31st 2025
265 | Removed debug output erroneously added to spectrum.py calls.
266 |
267 | 1.0.3
268 | March 7th 2025
269 | Repaired util.py check_version command, along with other bug fixes.
270 |
271 | 1.0.4
272 | March 13th 2025
273 | Improved check_version to print currently used database version.
274 | Added clean_pickle_cache routine to clean out cache of pickle files
275 | Changed spectrum Session objects to handle .dopseudo, .docont and .dopickle
276 | attributes correctly and consistently.
277 |
278 | 1.0.5
279 | April 8th 2025
280 | Remade and updated examples to work with AtomDB 3.1.X
281 | Fixed bug with return_spectrum when initial population was specified in K.
282 | Finally purged all use of pycurl
283 |
--------------------------------------------------------------------------------
/pyatomdb/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = _build
9 |
10 | # User-friendly check for sphinx-build
11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13 | endif
14 |
15 | # Internal variables.
16 | PAPEROPT_a4 = -D latex_paper_size=a4
17 | PAPEROPT_letter = -D latex_paper_size=letter
18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
19 | # the i18n builder cannot share the environment and doctrees with the others
20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
21 |
22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
23 |
24 | help:
25 | @echo "Please use \`make ' where is one of"
26 | @echo " html to make standalone HTML files"
27 | @echo " dirhtml to make HTML files named index.html in directories"
28 | @echo " singlehtml to make a single large HTML file"
29 | @echo " pickle to make pickle files"
30 | @echo " json to make JSON files"
31 | @echo " htmlhelp to make HTML files and a HTML help project"
32 | @echo " qthelp to make HTML files and a qthelp project"
33 | @echo " applehelp to make an Apple Help Book"
34 | @echo " devhelp to make HTML files and a Devhelp project"
35 | @echo " epub to make an epub"
36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
37 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
39 | @echo " text to make text files"
40 | @echo " man to make manual pages"
41 | @echo " texinfo to make Texinfo files"
42 | @echo " info to make Texinfo files and run them through makeinfo"
43 | @echo " gettext to make PO message catalogs"
44 | @echo " changes to make an overview of all changed/added/deprecated items"
45 | @echo " xml to make Docutils-native XML files"
46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes"
47 | @echo " linkcheck to check all external links for integrity"
48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
49 | @echo " coverage to run coverage check of the documentation (if enabled)"
50 |
51 | clean:
52 | rm -rf $(BUILDDIR)/*
53 |
54 | html:
55 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
56 | @echo
57 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
58 |
59 | dirhtml:
60 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
61 | @echo
62 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
63 |
64 | singlehtml:
65 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
66 | @echo
67 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
68 |
69 | pickle:
70 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
71 | @echo
72 | @echo "Build finished; now you can process the pickle files."
73 |
74 | json:
75 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
76 | @echo
77 | @echo "Build finished; now you can process the JSON files."
78 |
79 | htmlhelp:
80 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
81 | @echo
82 | @echo "Build finished; now you can run HTML Help Workshop with the" \
83 | ".hhp project file in $(BUILDDIR)/htmlhelp."
84 |
85 | qthelp:
86 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
87 | @echo
88 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
89 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
90 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PyAtomDB.qhcp"
91 | @echo "To view the help file:"
92 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PyAtomDB.qhc"
93 |
94 | applehelp:
95 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
96 | @echo
97 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
98 | @echo "N.B. You won't be able to view it unless you put it in" \
99 | "~/Library/Documentation/Help or install it in your application" \
100 | "bundle."
101 |
102 | devhelp:
103 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
104 | @echo
105 | @echo "Build finished."
106 | @echo "To view the help file:"
107 | @echo "# mkdir -p $$HOME/.local/share/devhelp/PyAtomDB"
108 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PyAtomDB"
109 | @echo "# devhelp"
110 |
111 | epub:
112 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
113 | @echo
114 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
115 |
116 | latex:
117 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
118 | @echo
119 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
120 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
121 | "(use \`make latexpdf' here to do that automatically)."
122 |
123 | latexpdf:
124 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
125 | @echo "Running LaTeX files through pdflatex..."
126 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
127 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
128 |
129 | latexpdfja:
130 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
131 | @echo "Running LaTeX files through platex and dvipdfmx..."
132 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
133 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
134 |
135 | text:
136 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
137 | @echo
138 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
139 |
140 | man:
141 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
142 | @echo
143 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
144 |
145 | texinfo:
146 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
147 | @echo
148 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
149 | @echo "Run \`make' in that directory to run these through makeinfo" \
150 | "(use \`make info' here to do that automatically)."
151 |
152 | info:
153 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
154 | @echo "Running Texinfo files through makeinfo..."
155 | make -C $(BUILDDIR)/texinfo info
156 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
157 |
158 | gettext:
159 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
160 | @echo
161 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
162 |
163 | changes:
164 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
165 | @echo
166 | @echo "The overview file is in $(BUILDDIR)/changes."
167 |
168 | linkcheck:
169 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
170 | @echo
171 | @echo "Link check complete; look for any errors in the above output " \
172 | "or in $(BUILDDIR)/linkcheck/output.txt."
173 |
174 | doctest:
175 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
176 | @echo "Testing of doctests in the sources finished, look at the " \
177 | "results in $(BUILDDIR)/doctest/output.txt."
178 |
179 | coverage:
180 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
181 | @echo "Testing of coverage in the sources finished, look at the " \
182 | "results in $(BUILDDIR)/coverage/python.txt."
183 |
184 | xml:
185 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
186 | @echo
187 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
188 |
189 | pseudoxml:
190 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
191 | @echo
192 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
193 |
--------------------------------------------------------------------------------
/pyatomdb/docs/_static/readme.stuff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/docs/_static/readme.stuff
--------------------------------------------------------------------------------
/pyatomdb/docs/_templates/layout.html:
--------------------------------------------------------------------------------
1 | {% extends "!layout.html" %}
2 |
3 | {% block menu %}
4 | {{ super() }}
5 | Index
6 | {% endblock %}
7 |
--------------------------------------------------------------------------------
/pyatomdb/docs/apec.rst:
--------------------------------------------------------------------------------
1 | apec module
2 | ===========
3 |
4 | This modules contains the APEC code. It calls many different subroutines from throughout the PyAtomDB module.
5 |
6 | It is expected (as of May 2020) that this code will go through a major rewrite to make it more pythonic and to make
7 | many helper routines private to declutter the module. Be wary of embedding too
8 | many links to this module in your code.
9 |
10 | .. automodule:: pyatomdb.apec
11 | :members:
12 | :undoc-members:
13 | :inherited-members:
14 | :show-inheritance:
15 |
--------------------------------------------------------------------------------
/pyatomdb/docs/atomdb.rst:
--------------------------------------------------------------------------------
1 | atomdb module
2 | =============
3 |
4 | This modules is designed to interact with the main atomic database, extracting real values of coefficients and so on.
5 |
6 | .. automodule:: pyatomdb.atomdb
7 | :members:
8 | :undoc-members:
9 | :inherited-members:
10 | :show-inheritance:
11 |
--------------------------------------------------------------------------------
/pyatomdb/docs/atomic.rst:
--------------------------------------------------------------------------------
1 | atomic module
2 | =============
3 |
4 | This module contains basic atomic parameters (i.e. atomic numbers, element symbols)
5 |
6 | .. automodule:: pyatomdb.atomic
7 | :members:
8 | :undoc-members:
9 | :inherited-members:
10 | :show-inheritance:
11 |
--------------------------------------------------------------------------------
/pyatomdb/docs/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # PyAtomDB documentation build configuration file, created by
4 | # sphinx-quickstart on Fri Sep 18 17:07:36 2015.
5 | #
6 | # This file is execfile()d with the current directory set to its
7 | # containing dir.
8 | #
9 | # Note that not all possible configuration values are present in this
10 | # autogenerated file.
11 | #
12 | # All configuration values have a default; values that are commented out
13 | # serve to show the default.
14 |
15 | import sys
16 | import os
17 | import shlex
18 | #import numpydoc
19 |
20 | try:
21 | from unittest.mock import MagicMock
22 | except ImportError:
23 | from mock import Mock as MagicMock
24 |
25 | class Mock(MagicMock):
26 | @classmethod
27 | def __getattr__(cls, name):
28 | return Mock()
29 |
30 | MOCK_MODULES=['liblinapprox']
31 |
32 |
33 | def get_version(relpath):
34 | """read version info from file without importing it"""
35 | from os.path import dirname, join
36 | for line in open(join(dirname(__file__), relpath)):
37 | if '__version__' in line:
38 | if '"' in line:
39 | # __version__ = "0.9"
40 | return line.split('"')[1]
41 | elif "'" in line:
42 | return line.split("'")[1]
43 |
44 | # If extensions (or modules to document with autodoc) are in another directory,
45 | # add these directories to sys.path here. If the directory is relative to the
46 | # documentation root, use os.path.abspath to make it absolute, like shown here.
47 | #sys.path.insert(0, os.path.abspath('.'))
48 | sys.path.insert(0,os.path.abspath('.'))
49 | sys.path.insert(0,os.path.abspath('..'))
50 | #for i in sys.path:
51 | # print i
52 | # -- General configuration ------------------------------------------------
53 |
54 | # If your documentation needs a minimal Sphinx version, state it here.
55 | #needs_sphinx = '1.0'
56 |
57 | # Add any Sphinx extension module names here, as strings. They can be
58 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
59 | # ones.
60 | extensions = [
61 | 'sphinx.ext.autodoc',
62 | 'sphinx.ext.coverage',
63 | 'sphinx.ext.autosummary',
64 | 'numpydoc',
65 | 'sphinx.ext.todo',
66 | 'sphinx.ext.mathjax',
67 | 'sphinx.ext.viewcode',
68 | 'sphinx_rtd_theme',
69 | ]
70 |
71 | # Add any paths that contain templates here, relative to this directory.
72 | templates_path = ['_templates']
73 |
74 | # The suffix(es) of source filenames.
75 | # You can specify multiple suffix as a list of string:
76 | # source_suffix = ['.rst', '.md']
77 | source_suffix = '.rst'
78 |
79 | # The encoding of source files.
80 | #source_encoding = 'utf-8-sig'
81 |
82 | # The master toctree document.
83 | master_doc = 'index'
84 |
85 | # General information about the project.
86 | project = u'PyAtomDB'
87 | copyright = u'2015-2023, Adam Foster'
88 | author = u'Adam Foster'
89 |
90 | # The version info for the project you're documenting, acts as replacement for
91 | # |version| and |release|, also used in various other places throughout the
92 | # built documents.
93 | #
94 | # The short X.Y version.
95 | version = get_version('../pyatomdb/__init__.py')
96 | # The full version, including alpha/beta/rc tags.
97 | release = get_version('../pyatomdb/__init__.py')
98 |
99 | # The language for content autogenerated by Sphinx. Refer to documentation
100 | # for a list of supported languages.
101 | #
102 | # This is also used if you do content translation via gettext catalogs.
103 | # Usually you set "language" from the command line for these cases.
104 | language = 'en'
105 |
106 | # There are two options for replacing |today|: either, you set today to some
107 | # non-false value, then it is used:
108 | #today = ''
109 | # Else, today_fmt is used as the format for a strftime call.
110 | #today_fmt = '%B %d, %Y'
111 |
112 | # List of patterns, relative to source directory, that match files and
113 | # directories to ignore when looking for source files.
114 | exclude_patterns = ['_build']
115 |
116 | # The reST default role (used for this markup: `text`) to use for all
117 | # documents.
118 | #default_role = None
119 |
120 | # If true, '()' will be appended to :func: etc. cross-reference text.
121 | #add_function_parentheses = True
122 |
123 | # If true, the current module name will be prepended to all description
124 | # unit titles (such as .. function::).
125 | #add_module_names = True
126 |
127 | # If true, sectionauthor and moduleauthor directives will be shown in the
128 | # output. They are ignored by default.
129 | #show_authors = False
130 |
131 | # The name of the Pygments (syntax highlighting) style to use.
132 | pygments_style = 'sphinx'
133 |
134 | # A list of ignored prefixes for module index sorting.
135 | #modindex_common_prefix = []
136 |
137 | # If true, keep warnings as "system message" paragraphs in the built documents.
138 | #keep_warnings = False
139 |
140 | # If true, `todo` and `todoList` produce output, else they produce nothing.
141 | todo_include_todos = True
142 |
143 |
144 | # -- Options for HTML output ----------------------------------------------
145 |
146 | # The theme to use for HTML and HTML Help pages. See the documentation for
147 | # a list of builtin themes.
148 | on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
149 | html_theme = 'sphinx_rtd_theme'
150 |
151 | if not on_rtd: # only import and set the theme if we're building docs locally
152 | import sphinx_rtd_theme
153 | html_theme = 'sphinx_rtd_theme'
154 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
155 |
156 | # Theme options are theme-specific and customize the look and feel of a theme
157 | # further. For a list of options available for each theme, see the
158 | # documentation.
159 | html_theme_options = {
160 | 'navigation_depth': 4,
161 | 'collapse_navigation': False,
162 | }
163 |
164 | # Add any paths that contain custom themes here, relative to this directory.
165 | #html_theme_path = []
166 |
167 | # The name for this set of Sphinx documents. If None, it defaults to
168 | # " v documentation".
169 | #html_title = None
170 |
171 | # A shorter title for the navigation bar. Default is the same as html_title.
172 | #html_short_title = None
173 |
174 | # The name of an image file (relative to this directory) to place at the top
175 | # of the sidebar.
176 | #html_logo = None
177 |
178 | # The name of an image file (within the static path) to use as favicon of the
179 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
180 | # pixels large.
181 | #html_favicon = None
182 |
183 | # Add any paths that contain custom static files (such as style sheets) here,
184 | # relative to this directory. They are copied after the builtin static files,
185 | # so a file named "default.css" will overwrite the builtin "default.css".
186 | html_static_path = ['_static']
187 |
188 | # Add any extra paths that contain custom files (such as robots.txt or
189 | # .htaccess) here, relative to this directory. These files are copied
190 | # directly to the root of the documentation.
191 | #html_extra_path = []
192 |
193 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
194 | # using the given strftime format.
195 | #html_last_updated_fmt = '%b %d, %Y'
196 |
197 | # If true, SmartyPants will be used to convert quotes and dashes to
198 | # typographically correct entities.
199 | #html_use_smartypants = True
200 |
201 | # Custom sidebar templates, maps document names to template names.
202 | #html_sidebars = {}
203 |
204 | # Additional templates that should be rendered to pages, maps page names to
205 | # template names.
206 | #html_additional_pages = {}
207 |
208 | # If false, no module index is generated.
209 | #html_domain_indices = True
210 |
211 | # If false, no index is generated.
212 | #html_use_index = True
213 |
214 | # If true, the index is split into individual pages for each letter.
215 | #html_split_index = False
216 |
217 | # If true, links to the reST sources are added to the pages.
218 | #html_show_sourcelink = True
219 |
220 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
221 | #html_show_sphinx = True
222 |
223 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
224 | #html_show_copyright = True
225 |
226 | # If true, an OpenSearch description file will be output, and all pages will
227 | # contain a tag referring to it. The value of this option must be the
228 | # base URL from which the finished HTML is served.
229 | #html_use_opensearch = ''
230 |
231 | # This is the file name suffix for HTML files (e.g. ".xhtml").
232 | #html_file_suffix = None
233 |
234 | # Language to be used for generating the HTML full-text search index.
235 | # Sphinx supports the following languages:
236 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
237 | # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
238 | #html_search_language = 'en'
239 |
240 | # A dictionary with options for the search language support, empty by default.
241 | # Now only 'ja' uses this config value
242 | #html_search_options = {'type': 'default'}
243 |
244 | # The name of a javascript file (relative to the configuration directory) that
245 | # implements a search results scorer. If empty, the default will be used.
246 | #html_search_scorer = 'scorer.js'
247 |
248 | # Output file base name for HTML help builder.
249 | htmlhelp_basename = 'PyAtomDBdoc'
250 |
251 | # -- Options for LaTeX output ---------------------------------------------
252 |
253 | latex_elements = {
254 | # The paper size ('letterpaper' or 'a4paper').
255 | #'papersize': 'letterpaper',
256 |
257 | # The font size ('10pt', '11pt' or '12pt').
258 | #'pointsize': '10pt',
259 |
260 | # Additional stuff for the LaTeX preamble.
261 | #'preamble': '',
262 |
263 | # Latex figure (float) alignment
264 | #'figure_align': 'htbp',
265 | }
266 |
267 | # Grouping the document tree into LaTeX files. List of tuples
268 | # (source start file, target name, title,
269 | # author, documentclass [howto, manual, or own class]).
270 | latex_documents = [
271 | (master_doc, 'PyAtomDB.tex', u'PyAtomDB Documentation',
272 | u'Adam Foster', 'manual'),
273 | ]
274 |
275 | # The name of an image file (relative to this directory) to place at the top of
276 | # the title page.
277 | #latex_logo = None
278 |
279 | # For "manual" documents, if this is true, then toplevel headings are parts,
280 | # not chapters.
281 | #latex_use_parts = False
282 |
283 | # If true, show page references after internal links.
284 | #latex_show_pagerefs = False
285 |
286 | # If true, show URL addresses after external links.
287 | #latex_show_urls = False
288 |
289 | # Documents to append as an appendix to all manuals.
290 | #latex_appendices = []
291 |
292 | # If false, no module index is generated.
293 | #latex_domain_indices = True
294 |
295 |
296 | # -- Options for manual page output ---------------------------------------
297 |
298 | # One entry per manual page. List of tuples
299 | # (source start file, name, description, authors, manual section).
300 | man_pages = [
301 | (master_doc, 'pyatomdb', u'PyAtomDB Documentation',
302 | [author], 1)
303 | ]
304 |
305 | # If true, show URL addresses after external links.
306 | #man_show_urls = False
307 |
308 |
309 | # -- Options for Texinfo output -------------------------------------------
310 |
311 | # Grouping the document tree into Texinfo files. List of tuples
312 | # (source start file, target name, title, author,
313 | # dir menu entry, description, category)
314 | texinfo_documents = [
315 | (master_doc, 'PyAtomDB', u'PyAtomDB Documentation',
316 | author, 'PyAtomDB', 'Python interface to AtomDB.',
317 | 'Miscellaneous'),
318 | ]
319 |
320 | # Documents to append as an appendix to all manuals.
321 | #texinfo_appendices = []
322 |
323 | # If false, no module index is generated.
324 | #texinfo_domain_indices = True
325 |
326 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
327 | #texinfo_show_urls = 'footnote'
328 |
329 | # If true, do not generate a @detailmenu in the "Top" node's menu.
330 | #texinfo_no_detailmenu = False
331 |
332 |
333 | numpydoc_show_class_members = False
334 |
--------------------------------------------------------------------------------
/pyatomdb/docs/const.rst:
--------------------------------------------------------------------------------
1 | const module
2 | ============
3 |
4 | A series of physical constants and constants relevant to running the APEC code.
5 |
6 | .. automodule:: pyatomdb.const
7 | :members:
8 | :undoc-members:
9 | :inherited-members:
10 | :show-inheritance:
11 |
--------------------------------------------------------------------------------
/pyatomdb/docs/contact.rst:
--------------------------------------------------------------------------------
1 | =======
2 | Contact
3 | =======
4 |
5 | This module is still in very active development. If you have feature requests, bug
6 | reports or any other questions, please contact us through the project's
7 | `GitHub `_ page.
8 |
--------------------------------------------------------------------------------
/pyatomdb/docs/examples.rst:
--------------------------------------------------------------------------------
1 | ========================
2 | PyAtomDB Example Scripts
3 | ========================
4 |
5 |
6 |
7 | ----------------
8 | Module Structure
9 | ----------------
10 |
11 | These are examples of using the PyAtomDB module in your projects. They can all be found in the examples subdirectory of your PyAtomDB installation.
12 |
13 | The examples here are separated by the module in which they are implemented. Generally speaking, the roles of these modules can be split into the following areas:
14 |
15 | spectrum
16 | Obtaining emissivities from the AtomDB emissivity files (e.g. the ``apec`` model). This module is used to create spectra as required.
17 |
18 | apec
19 | Related to the APEC code - creating the AtomDB emissivity files from the underlying atomic database
20 |
21 | atomdb
22 | Accessing the atomic database - returning rates and coefficients, fetching files
23 |
24 | atomic
25 | Basic atomic functions - getting atomic masses, converting to element symbols etc.
26 |
27 | util
28 | File utilities (not generally interesting to end users)
29 |
30 | const
31 | List of physical constants and code-related constants used throughout PyAtomDB (again, not generally interesting to end users)
32 |
33 |
34 |
35 |
36 | -------
37 | Spectra
38 | -------
39 | The spectrum.py module contains routines for taking the spectrum generated from the
40 | apec model and extracting line emissivities or continuum emission, applying responses,
41 | changing abundances, etc. In these examples, we will use the
42 | `Chandra ACIS-S MEG +1 `_
43 | order grating responses as examples where one is required, but you can use any.
44 |
45 | Similarly, we use ``pylab`` for plotting. You can of course use whatever system you
46 | like for plotting, this is just what we did. It is included in matplotlib and
47 | therefore hopefully present on most systems.
48 |
49 | ++++++++++++++++
50 | CIESession Class
51 | ++++++++++++++++
52 |
53 | The heart of the spectral analysis is the spectrum.py class. This reads in the results of an apec run (by default, $ATOMDB/apec_line.fits and $ATOMDB/apec_coco.fits) and allows the user to obtain spectra at a range of temperatures accounting for instrument responses, thermal and velocity broadening, abundance changes and other issues.
54 |
55 | ~~~~~~~~~~~~~~~~~
56 | Making a Spectrum
57 | ~~~~~~~~~~~~~~~~~
58 |
59 | .. literalinclude:: ../examples/spectrum_session_examples_1.py
60 |
61 | .. figure:: ../examples/spectrum_session_examples_1_1.svg
62 | :align: center
63 | :alt: Spectrum Example 1
64 | :figclass: align-center
65 |
66 | A kT=0.4keV simple spectrum created with and without an instrument response
67 |
68 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
69 | Handling Large Response Matrices
70 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71 |
72 | Some missions, for example XRISM, have a large number of bins in their response files (XRISM has 50,000). Creating a 50,000x50,000 response matrix would require of order 16GB of memory, most of which would be zeros. Setting ``sparse=True`` when setting the response will use `sparse matrices `_ to save memory. The code below shows how to do this and also how to compare any innacuracies caused (testing so far has shown nothing larger than numerical rounding errors, 1 part in 10 :sup:`15`)
73 |
74 | .. literalinclude:: ../examples/spectrum_session_examples_1b.py
75 |
76 | .. figure:: ../examples/spectrum_session_examples_1b_1.svg
77 | :align: center
78 | :alt: Spectrum Example 1(b) - sparse matrices for large responses
79 | :figclass: align-center
80 |
81 | A kT=0.4keV simple spectrum created with regular and sparse instrument responses. The same code can be used to compare the accuracy of the two methods for different response matrices, but will require large amounts of memory if using large responses.
82 |
83 | ~~~~~~~~~~~~~~~
84 | Line Broadening
85 | ~~~~~~~~~~~~~~~
86 |
87 | By default, line broadening is off. The command ``session.set_broadening`` allows you to turn on thermal broadening and, if desired, add additional turbulent velocity broadening too.
88 |
89 | .. literalinclude:: ../examples/spectrum_session_examples_2.py
90 |
91 | .. figure:: ../examples/spectrum_session_examples_2_1.svg
92 | :align: center
93 | :alt: Spectrum Example 2
94 | :figclass: align-center
95 |
96 | A kT=3.0keV spectrum unbroadened, thermally broadened and then additionally velocity broadend.
97 |
98 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99 | Line Broadening of Weak Lines
100 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101 |
102 | When line broadening is enabled, it by default only broadens lines with an emissivity :math:`>10^{-18}` :math:`ph ~ cm^3 s^{-1}`. This can sometimes lead to "spikes" in the spectrum. This can be changed by adjusting the ``broaden_limit`` parameter when calling ``session.set_broadening``, as shown below.
103 |
104 | .. literalinclude:: ../examples/spectrum_session_examples_2b.py
105 |
106 | .. figure:: ../examples/spectrum_session_examples_2b_1.svg
107 | :align: center
108 | :alt: Spectrum Example 2b
109 | :figclass: align-center
110 |
111 | A kT=10.0keV spectrum unbroadened, thermally and velocity broadend, and then with the limit lowered so weak features are also broadened.
112 |
113 | ~~~~~~~~~~~~~~~~~~~
114 | Changing Abundances
115 | ~~~~~~~~~~~~~~~~~~~
116 |
117 | There are several ways to change the abundances. By default, all are set to 1.0 times the solar value of `Anders and Grevesse `_.
118 | The ``session.set_abund`` command implements this.
119 |
120 | .. literalinclude:: ../examples/spectrum_session_examples_3_abund.py
121 |
122 | .. figure:: ../examples/spectrum_session_examples_3_1.svg
123 | :align: center
124 | :alt: Spectrum Example 3
125 | :figclass: align-center
126 |
127 | A kT=1.0keV spectrum with assorted different abundances applied.
128 |
129 |
130 | You can also change the entire abundance set in use using ``session.set_abundset``.
131 |
132 | .. literalinclude:: ../examples/spectrum_session_examples_4_abund.py
133 |
134 | .. figure:: ../examples/spectrum_session_examples_4_1.svg
135 | :align: center
136 | :alt: Spectrum Example 4
137 | :figclass: align-center
138 |
139 | A kT=1.0keV spectrum with assorted different abundance sets applied.
140 |
141 | ~~~~~~~~~~~~~~~~
142 | Return line list
143 | ~~~~~~~~~~~~~~~~
144 |
145 | To obtain a list of lines and their emissivities in a spectral range, use ``session.return_linelist``. This
146 | returns the data as a numpy array of the lines in the region, applying all current abundance information
147 | to the linelist. It also interpolates in temperature between the two nearest points. Note
148 | that since AtomDB cuts off lines with emissivities below :math:`10^{-20}` :math:`ph ~ cm^3 s^{-1}`, lines
149 | will diappear below this emissivity. Lines beyond the last temperature point at which they are tabulated will
150 | not be included in the returned linelist.
151 |
152 | .. literalinclude:: ../examples/spectrum_session_examples_5_linelist.py
153 |
154 | ~~~~~~~~~~~~~~~~~~~~~~
155 | Return line emissivity
156 | ~~~~~~~~~~~~~~~~~~~~~~
157 |
158 | To calculate the emissvitiy of a specific line, you can use ``session.return_line_emissivity`` along
159 | with the ion, element, upper and lower levels of the transition. You can supply a single or a range
160 | of temperatures, and a dictionary will be returned containing much of the information along with
161 | emissivity (epsilon) you requested.
162 |
163 | .. literalinclude:: ../examples/spectrum_session_examples_6_line_emissivity.py
164 |
165 | .. figure:: ../examples/spectrum_session_examples_6_1.svg
166 | :align: center
167 | :alt: Spectrum Example 6
168 | :figclass: align-center
169 |
170 | Emissivity of the resonance line of O VII.
171 |
172 | ++++++++++++++++
173 | NEISession Class
174 | ++++++++++++++++
175 |
176 | Derived from the CIESession class, this handles non-equilibrium spectra. As such, all of the calls to it are
177 | exactly the same. Adding response, setting abundances obtaining spectra, etc all work the same way.
178 | Therefore I will only outline what is different.
179 |
180 | The main difference is that a non equilibrium plasma requires 2 more pieces of information to define it. The
181 | current electron temperature is as with the CIE case. The other two are:
182 |
183 | tau
184 | The ionization timescale (:math:`n_e t`) in |cm-3s| since the plasma left its previous
185 | equilibrium
186 | init_pop
187 | The initial population the plasma was in at tau=0.
188 |
189 | Tau is a single number in all cases. init_pop can be be defined in a range of ways:
190 |
191 | float
192 | If it is a single number, this is assumed to be an electron temperature. The ionization fraction will
193 | be calculated at this :math:`T_e`.
194 |
195 | dict
196 | If a dictionary is provided, it should be an explicit ionization fraction for each element.
197 | So dict[6]= [0.0, 0.1, 0.2, 0.3, 0.3, 0.1, 0.0] would be the ionization fraction for carbon,
198 | dict[8]= [0.0, 0.0, 0.1, 0.1, 0.1, 0.15,0.3,0.2,0.05] would be for oxygen etc.
199 |
200 | 'ionizing'
201 | If the string ionizing is provided, set all elements to be entirely neutral. This is the default.
202 |
203 | 'recombining'
204 | If the string recombining is provided, set all elements to be fully ionized.
205 |
206 | ~~~~~~~~~~~~~~~~~
207 | Making a Spectrum
208 | ~~~~~~~~~~~~~~~~~
209 |
210 | As an example, this will plot a simple recombining spectrum within initial temperature of 1.0keV.
211 |
212 | .. literalinclude:: ../examples/spectrum_session_examples_7_nei.py
213 |
214 | .. figure:: ../examples/spectrum_session_examples_7_1.svg
215 | :align: center
216 | :alt: Spectrum Example 7
217 | :figclass: align-center
218 |
219 | Recombining spectrum specified by an initial temperature
220 |
221 | ~~~~~~~~~~~~~~~~~
222 | Making a Linelist
223 | ~~~~~~~~~~~~~~~~~
224 |
225 | This is again exactly the same as the CIESession case, except with extra parameters ``tau`` and ``init_pop``.
226 | The only additional option is the ability to separate the linelist by driving ion. This is the ion which gives
227 | rise to the emission. For example, if the emission is largely from ionization into an excited state and then
228 | subsequent cascade, then that part of the emissivity has a different driving ion than that driven by
229 | excitation of the ion's ground state.
230 |
231 | Separating out these features can be turned on and off using the ``by_ion_drv`` keyword,
232 |
233 | .. literalinclude:: ../examples/spectrum_session_examples_8_nei_linelist.py
234 |
235 |
236 | -------------------
237 | Getting Atomic Data
238 | -------------------
239 | The ``atomdb`` module is designed to read data from the database and either
240 | return raw opened files (e.g. all the energy levels of an ion) or
241 | individual useful data (e.g. a rate coefficient).
242 |
243 | AtomDB stores data sorted by ion in a series of files in the ``$ATOMDB/APED``. There are several files for
244 | each ion, covering different data types:
245 |
246 | * 'IR' - ionization and recombination
247 | * 'LV' - energy levels
248 | * 'LA' - radiative transition data (lambda and A-values)
249 | * 'EC' - electron collision data
250 | * 'PC' - proton collision data
251 | * 'DR' - dielectronic recombination satellite line data
252 | * 'PI' - XSTAR photoionization data
253 | * 'AI' - autoionization data
254 | * 'ALL' - reads all of the above. Does not return anything. Used for bulk downloading.
255 |
256 | Or, for non-ion-specific data (abundances and bremstrahlung coeffts):
257 |
258 | * 'ABUND' - abundance tables
259 | * 'HBREMS' - Hummer bremstrahlung coefficients
260 | * 'RBREMS' - relativistic bremstrahlung coefficitients
261 | * 'IONBAL' - ionization balance tables
262 | * 'EIGEN' - eigenvalue files (for non-equilibrium ionization)
263 |
264 | The raw atomic data files can be downloaded using ``atomdb.get_data``.
265 |
266 | .. note:: Datacache
267 |
268 | Often, when using AtomDB data you will want to use the same file over and over again. However,
269 | the whole database is too large to be loaded into memory as a matter of course. To get around this,
270 | the ``datacache`` keyword is used in several routines. This is a dictionary which is populated
271 | with any data files that you have to open. The atomdb function which ultimately opens the raw
272 | data files, ``get_data``, will always check for an already existing data file here before
273 | going to the disk to open the file anew. If there is no data there, then the file is opened
274 | and its data is stored in the datacache so that next time the routine is called it will
275 | already be there.
276 |
277 | If you need to save memory, you can empty the cache by declaring the datacache as a
278 | new dictionary, i.e. ``datacache={}``.
279 |
280 |
281 |
282 | .. literalinclude:: ../examples/atomdb_example_1_get_data.py
283 |
284 | +++++++++++++++++++++++++
285 | Getting Rate Coefficients
286 | +++++++++++++++++++++++++
287 |
288 | Ionization, recombination, and excitation rate coefficients can all be
289 | obtained using ``get_maxwell_rate``.
290 |
291 | .. literalinclude:: ../examples/atomdb_example_2_get_maxwell.py
292 |
293 | .. figure:: ../examples/atomdb_examples_2_1.svg
294 | :align: center
295 | :alt: AtomDB Example 2.1
296 | :figclass: align-center
297 |
298 | Excitation rates for O\ :sup:`6+`.
299 |
300 |
301 | .. figure:: ../examples/atomdb_examples_2_2.svg
302 | :align: center
303 | :alt: AtomDB Example 2.2
304 | :figclass: align-center
305 |
306 | Ionization and recombination rates for O\ :sup:`6+` to O\ :sup:`7+`.
307 | Note that for the components breakdown, there is no excitation autionization
308 | contribution in the files.
309 |
310 |
311 |
312 | -----------------------------
313 | Calculating Plasma Conditions
314 | -----------------------------
315 | The ``apec`` module is used for calculating plasma related phenomena. For example,
316 | ionization fractions, non-equilibrium ionization, level populations, emission spectra.
317 | Currently, it is mostly written in such a way that it is difficult to use it outside
318 | of running the entire APEC code. A rewrite will happen soon. However, for now,
319 | here are a couple of useful routines which should be useable.
320 |
321 | +++++++++++++++++++++++++++++++++
322 | Getting Charge State Distribution
323 | +++++++++++++++++++++++++++++++++
324 |
325 |
326 |
327 | .. literalinclude:: ../examples/apec_example_1_get_ionbal.py
328 |
329 | .. figure:: ../examples/apec_examples_1_1.svg
330 | :align: center
331 | :alt: APEC Example 1.1
332 | :figclass: align-center
333 |
334 | Ionization balance for oxygen
335 |
336 |
337 | .. figure:: ../examples/apec_examples_1_2.svg
338 | :align: center
339 | :alt: APEC Example 1.2
340 | :figclass: align-center
341 |
342 | Charge state distribution calculated many different ways for
343 | non equilibrium ionization.
344 |
345 | --------------------------------
346 | Including APEC models in PyXSPEC
347 | --------------------------------
348 |
349 | .. literalinclude:: ../examples/wrapper_xspec_examples.py
350 |
351 | There are other wrapper files which work in the same way for a model with
352 | a separate temperature set for line broadening, and others will be added in
353 | the ``wrapper`` directory.
354 |
355 |
356 | ----------------------------------
357 | Resonant Scattering (rsapec) model
358 | ----------------------------------
359 |
360 | The RSapec model can be used to model line emissivities of optically thick lines. The following code shows an application of the resonance scattering model on the Hitomi spectrum of Perseus cluster.
361 |
362 | ++++++++++++++++++++++++++++++++++++++++++++
363 | Example script using rsapec model in PyXSPEC
364 | ++++++++++++++++++++++++++++++++++++++++++++
365 |
366 | .. literalinclude:: ../examples/rsapec.py
367 |
368 | .. figure:: ../examples/Rsapec_hitomi.svg
369 | :align: center
370 | :alt: rsapec example
371 | :figclass: align-center
372 |
373 | The rsapec model plotted over the Hitomi observation of Perseus outer core
374 |
375 | --------------------
376 | Individual Use Cases
377 | --------------------
378 |
379 | These are typically scripts created to answer user's questions which might be interesting. As a result,
380 | sometimes the exact response files etc may not be available to you. Please swap in what you need to.
381 |
382 | +++++++++++++++++++++
383 | Get PI Cross Sections
384 | +++++++++++++++++++++
385 |
386 | Extract the PI cross section data: ``photoionization_data.py``
387 |
388 | .. literalinclude:: ../examples/photoionization_data.py
389 |
390 | ++++++++++++++++++
391 | Make Cooling Curve
392 | ++++++++++++++++++
393 |
394 | Make a cooling curve, total emissivity in keV cm3 s-1, for each element
395 | in a specfied spectral range (e.g. 2 to 10 keV).
396 |
397 | .. literalinclude:: ../examples/calc_power.py
398 |
399 | .. figure:: ../examples/calc_power_examples_1_1.svg
400 | :align: center
401 | :alt: Calc Power Example 1.1
402 | :figclass: align-center
403 |
404 | The total emissivity of the plasma between 0.001 and 100 keV.
405 |
406 | .. |cm3| replace:: cm\ :sup:`3`
407 | .. |cm-3| replace:: cm\ :sup:`-3`
408 | .. |cm-3s| replace:: cm\ :sup:`-3` s\ :sup:`1`
409 | .. |cm3s-1| replace:: cm\ :sup:`3` s\ :sup:`-1`
410 |
411 |
--------------------------------------------------------------------------------
/pyatomdb/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. PyAtomDB documentation master file, created by
2 | sphinx-quickstart on Fri Sep 18 17:07:36 2015.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | =================
7 | PyAtomDB & AtomDB
8 | =================
9 |
10 | The `AtomDB Project `_ consists of a large atomic database
11 | designed for creating spectra of collisionally excited plasmas in the UV and
12 | X-ray wavebands for use in astronomy and astrophysics research.
13 | It has been successfully used for some time within several
14 | different spectral analysis suites, such as `XSPEC `_
15 | and `Sherpa `_.
16 |
17 | There are two main parts to AtomDB:
18 |
19 | The Astrophysical Plasma Emission Database (APED)
20 | A series of `FITS `_
21 | files which store the atomic data necessary for modelling emission from collisional plasmas
22 | from elements from H through to Zn.
23 |
24 | The Astrophysical Plasma Emission Code (APEC)
25 | Code which takes the APED and uses it to model a collisional
26 | plasma, creating emissivity files for line and continuum emission. These output files are
27 | then used in a range of models such as the ``apec``, ``nei`` and ``pshock`` models amongst others.
28 |
29 | Starting in 2015, PyAtomDB was developed to achieve a number of goals:
30 |
31 | #. To replace the APEC code (formerly in C) with a more flexible tool for larger data sets
32 | #. To allow interactive user access to the underlying database, which was always freely
33 | available but sometimes difficult to use
34 | #. To enable creating more flexible spectra based on the outputs of AtomDB
35 | #. To enhance the types of spectra which can be modeled in AtomDB, and astronomer interaction
36 | with these models
37 | #. To facililtate inclusion of AtomDB models in other software (often python based).
38 |
39 |
40 |
41 | ========
42 | Contents
43 | ========
44 |
45 | .. contents::
46 | :depth: 2
47 | :backlinks: entry
48 |
49 | .. toctree::
50 | :maxdepth: 4
51 |
52 | installation
53 | examples
54 | modules
55 | license
56 | contact
57 |
58 |
59 |
60 | =======
61 | Outline
62 | =======
63 |
64 |
65 | PyAtomDB is a selection of utilities designed to interact with the `AtomDB
66 | database `_ . These utilities are under constant development. Please get in touch with any issues that arise.
67 |
68 |
69 | There are several different modules currently. These are:
70 |
71 | :doc:`atomdb `
72 | A series of codes for interacting with the AtomDB atomic database
73 | :doc:`atomic `
74 | Basic atomic data routines - e.g. converting element symbols to atomic number, etc.
75 | :doc:`const `
76 | Physical and code related constants
77 | :doc:`spectrum `
78 | Routines for generating spectra from the published AtomDB line and continuum emissivity files
79 | :doc:`util `
80 | Utility codes (sorting etc) that pyatomdb relies on.
81 | :doc:`apec `
82 | The full APEC code
83 |
84 | To report bugs or make feature requests, email the code authors or raise an issue at the `github page `_
85 |
86 |
87 |
88 |
89 | ==================
90 | Indices and tables
91 | ==================
92 |
93 | * :ref:`genindex`
94 | * :ref:`modindex`
95 | * :ref:`search`
96 |
97 |
--------------------------------------------------------------------------------
/pyatomdb/docs/installation.rst:
--------------------------------------------------------------------------------
1 | ============
2 | Installation
3 | ============
4 |
5 | .. warning::
6 | PyAtomDB runs only under Python 3. It will not work on Python 2. If you
7 | need to install Python 3 in your system, you can use your package manager
8 | or there are many other sources which
9 | can help you including `Anaconda `_.
10 |
11 | Once you have Python 3 installed, you may (depending on your system)
12 | have to add a ``3`` to many
13 | of the command line commands, e.g. ``python`` becomes ``python3``, or
14 | ``pip`` becomes ``pip3``. Commands in this guide omit the ``3``. Note
15 | that actual Python code is unaffected.
16 |
17 |
18 |
19 | PyAtomDB can be installed in two ways:
20 |
21 | #. From `PyPI `_ , using the simple ``pip install pyatomdb`` command.
22 | #. From `GitHub `_ , using the command ``git clone https://github.com/AtomDB/pyatomdb.git`` to get the source, then ``pip install -e python ``.
23 | #. If using ``Conda``: Pyatomdb is not packaged with Conda as it requires compiling of some C code and (as far as I can tell) Conda cannot handle this. I recommend installing the dependencies independently, e.g.: ``conda install requests wget "numpy>=1.9.0" "scipy>=1.9.0" joblib mock astropy pycurl``, then install pip within conda (``conda install pip``), and then ``pip install -e python ``.
24 | #. Using ``setuptools`` (deprecated): python setup.py install
25 |
26 | Note that for the PyPI and setuptools options the ``--user`` option can be useful, as it will install software in your local path if you do not have administrator priviledges on your machine.
27 |
28 | You can check that the installation was successful by running:
29 |
30 | .. code-block:: python
31 |
32 | >>> import pyatomdb
33 |
34 | If it does not immediately throw out an error, it has been successful. It will
35 | then start asking about installing the AtomDB files, see the next section. Note
36 | that there is no longer a need to run the initialize script.
37 |
38 |
39 | .. warning::
40 | pycURL issues can arise when installing. If your install above worked without
41 | errors, then you are fine. If you encountered errors, and they are related to
42 | pycurl, you will need to consult your system's package manager (or conda if
43 | that is what you are using) and install pycurl separately -
44 | e.g. ``conda install pycurl``.
45 |
46 | I'm not sure why this refuses to install directly with pip sometimes, but it seems to be a recurring feature.
47 |
48 |
49 | ----------------
50 | ATOMDB Directory
51 | ----------------
52 | Whenever you import the PyAtomDB module, it performs a check for the $ATOMDB directory.
53 | This directory is where the AtomDB data files will be stored. These are not
54 | distributed with the python package as they are large and most people will only need
55 | a few. PyAtomDB will download the APED data files on demand as you require them, and
56 | they are then stored in this directory until you manually delete them. If you need to
57 | recover disk space, you can delete anything in the $ATOMDB/APED directory without
58 | repercussions - PyAtomDB will re-download the files if it needs them in the future.
59 |
60 | You will be asked to select a directory for installation and then whether to download
61 | the emissivity files. It is important that this directory is one where you have write
62 | access, as in the future further files will be added there by the code automatically.
63 |
64 | Once installation is complete, ensure that you add the ATOMDB variable to your
65 | shell startup file. Assuming you have installed into /home/username/atomdb,
66 | in bash, add this line to your ~/.bashrc or ~/.bash_profile files
67 | (depends on which one is sourced by your system):
68 |
69 | .. code-block:: bash
70 |
71 | export ATOMDB=/home/username/atomdb
72 |
73 | or for csh, add this to your ~/.cshrc or ~/.cshrc.login:
74 |
75 | .. code-block:: csh
76 |
77 | setenv ATOMDB /home/username/atomdb
78 |
79 | Recent version of Mac OS have moved to zsh, in which case modify your ~/.zshrc file as for bash above.
80 |
81 | ---------------------
82 | Usage Data Collection
83 | ---------------------
84 |
85 | You will also be asked about anonymous usage data. In order to track roughly how many
86 | people are using PyAtomDB, a randomly generated number is created when you install
87 | PyAtomDB and stored in your ``$ATOMDB/userdata`` file. Whenever PyAtomDB has to fetch
88 | a new file this number, the filename and the current timestamp is stored on our
89 | system so we can estimate how many users there are. We have no way to connect this
90 | to actual individuals, it simply tells us roughly how many unique active users
91 | there are.
92 |
93 | If you decline, this number is set to 00000000, and otherwise PyAtomDB functions
94 | as normal.
95 |
--------------------------------------------------------------------------------
/pyatomdb/docs/license.rst:
--------------------------------------------------------------------------------
1 | License
2 | =======
3 |
4 | .. include:: ../COPYING.txt
5 |
--------------------------------------------------------------------------------
/pyatomdb/docs/modules.rst:
--------------------------------------------------------------------------------
1 | ====================
2 | Module Documentation
3 | ====================
4 |
5 |
6 | .. toctree::
7 | :maxdepth: 1
8 |
9 | apec
10 | atomic
11 | atomdb
12 | const
13 | spectrum
14 | util
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/pyatomdb/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | astropy
2 | wget
3 | sphinx
4 | scipy
5 | requests
6 | joblib
7 | numpydoc
8 | sphinx_rtd_theme
9 |
--------------------------------------------------------------------------------
/pyatomdb/docs/spectrum.rst:
--------------------------------------------------------------------------------
1 | spectrum module
2 | ====================================
3 |
4 | This module contains codes for creating spectra from the AtomDB emissivity files
5 |
6 | .. automodule:: pyatomdb.spectrum
7 | :members:
8 | :undoc-members:
9 | :inherited-members:
10 | :show-inheritance:
11 |
--------------------------------------------------------------------------------
/pyatomdb/docs/util.rst:
--------------------------------------------------------------------------------
1 | util module
2 | ===========
3 |
4 | This modules contains simple utility codes (sorting, file handling etc) that pyatomdb relies on.
5 |
6 | .. automodule:: pyatomdb.util
7 | :members:
8 | :undoc-members:
9 | :inherited-members:
10 | :show-inheritance:
11 |
--------------------------------------------------------------------------------
/pyatomdb/examples/aciss_meg1_cy22.garf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/aciss_meg1_cy22.garf
--------------------------------------------------------------------------------
/pyatomdb/examples/aciss_meg1_cy22.grmf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/aciss_meg1_cy22.grmf
--------------------------------------------------------------------------------
/pyatomdb/examples/ah100040030_sxs_cl2_HP_small.rmf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/ah100040030_sxs_cl2_HP_small.rmf
--------------------------------------------------------------------------------
/pyatomdb/examples/ah100040030sxs_p0px1010_cl2_HP.pi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/ah100040030sxs_p0px1010_cl2_HP.pi
--------------------------------------------------------------------------------
/pyatomdb/examples/ah100040030sxs_p0px1010_ptsrc.arf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/ah100040030sxs_p0px1010_ptsrc.arf
--------------------------------------------------------------------------------
/pyatomdb/examples/apec_example_1_get_ionbal.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, numpy, pylab
2 |
3 | # Calculate an equilibrium ionization balance for an element
4 | kT = 0.5
5 | Z = 8
6 |
7 | # going to declare a datacache to speed up the calculations as we
8 | # will be repeating things
9 | datacache = {}
10 |
11 | ionfrac_fast = pyatomdb.apec.return_ionbal(Z, kT, teunit='keV', datacache=datacache)
12 |
13 | # The "fast" keyword makes the code open up a precalculated set of
14 | # ionization balance data, a grid os 1251 values from 10^4K <= T <= 10^9K.
15 | # By default it is true. Here, we turn it off for comparison
16 | ionfrac_slow = pyatomdb.apec.return_ionbal(Z, kT, teunit='keV', datacache=datacache,
17 | fast=False)
18 |
19 | fig = pylab.figure()
20 | fig.show()
21 | ax = fig.add_subplot(111)
22 |
23 | ax.semilogy(range(0,Z+1), ionfrac_fast, 'o', label='fast')
24 | ax.semilogy(range(0,Z+1), ionfrac_slow, '^', label='slow')
25 | ax.set_ylim([1e-6,1])
26 | ax.set_xlabel('Ion Charge')
27 | ax.set_ylabel('Fraction')
28 | ax.legend(loc=0)
29 |
30 | pylab.draw()
31 | zzz=input("Press enter to continue")
32 | # save image files
33 | fig.savefig('apec_examples_1_1.pdf')
34 | fig.savefig('apec_examples_1_1.svg')
35 |
36 |
37 | # now to do the same for several different ways of defining non-equilbrium:
38 | tau = 1e11
39 | # 1: from neutral
40 | init_pop='ionizing' # this is the default
41 | nei1 = pyatomdb.apec.return_ionbal(Z, kT, tau = tau, init_pop = init_pop,
42 | teunit='keV', datacache=datacache)
43 |
44 |
45 | # 2: from fully stripped
46 | init_pop='recombining'
47 | nei2 = pyatomdb.apec.return_ionbal(Z, kT, tau = tau, init_pop = init_pop,
48 | teunit='keV', datacache=datacache)
49 |
50 |
51 | # 3: from a given Temperature
52 | init_pop=0.1
53 | nei3 = pyatomdb.apec.return_ionbal(Z, kT, tau = tau, init_pop = init_pop,
54 | teunit='keV', datacache=datacache)
55 |
56 |
57 | # 4: from a given array
58 | init_pop=numpy.array([0.1, #O0+
59 | 0.1, #O1+
60 | 0.1, #O2+
61 | 0.1, #etc
62 | 0.3,
63 | 0.1,
64 | 0.1,
65 | 0.1,
66 | 0.0])
67 | nei4 = pyatomdb.apec.return_ionbal(Z, kT, tau = tau, init_pop = init_pop,
68 | teunit='keV', datacache=datacache)
69 |
70 | # 5: from a dict of arrays
71 | # (this is useful if you have lots of elements to do)
72 | init_pop = {}
73 | init_pop[8] = numpy.array([0.5, #O0+
74 | 0.0, #O1+
75 | 0.0, #O2+
76 | 0.0, #etc
77 | 0.0,
78 | 0.0,
79 | 0.0,
80 | 0.0,
81 | 0.5])
82 | nei5 = pyatomdb.apec.return_ionbal(Z, kT, tau = tau, init_pop = init_pop,
83 | teunit='keV', datacache=datacache)
84 |
85 | ax.cla()
86 | ax.semilogy(range(Z+1), nei1, 'o', label='ionizing')
87 | ax.semilogy(range(Z+1), nei2, '<', label='recombining')
88 | ax.semilogy(range(Z+1), nei3, 's', label='0.1keV')
89 | ax.semilogy(range(Z+1), nei4, '^', label='array')
90 | ax.semilogy(range(Z+1), nei5, 'x', label='dict')
91 |
92 | ax.set_ylim([1e-6,1])
93 | ax.set_xlabel('Ion Charge')
94 | ax.set_ylabel('Fraction')
95 | ax.legend(loc=0)
96 |
97 | pylab.draw()
98 | zzz=input("Press enter to continue")
99 | # save image files
100 | fig.savefig('apec_examples_1_2.pdf')
101 | fig.savefig('apec_examples_1_2.svg')
102 |
--------------------------------------------------------------------------------
/pyatomdb/examples/apec_examples_1_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/apec_examples_1_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/apec_examples_1_2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/apec_examples_1_2.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/atomdb_example_1_get_data.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, time
2 |
3 | # Example of using get data. I am going to get a range of different atomic data
4 | #
5 | # This routine returns the raw opened FITS data. No other processing is done.
6 |
7 | Z = 8
8 | z1 = 7
9 |
10 | # get the energy levels of O VII
11 |
12 | a = pyatomdb.atomdb.get_data(Z,z1,'LV')
13 |
14 | # print out the first few lines
15 | # note that for all the atomic data files, the useful data is in HDU 1.
16 |
17 | print(a[1].data.names)
18 |
19 | print(a[1].data[:5])
20 |
21 | # get radiative transition information
22 | b = pyatomdb.atomdb.get_data(Z,z1,'LA')
23 |
24 | # find the transitions from level 7
25 |
26 | bb = b[1].data[ (b[1].data['UPPER_LEV']==7)]
27 | print()
28 | print(bb.names)
29 | print(bb)
30 |
31 | # and so on.
32 |
33 | # For non ion-specific data, Z and z1 are ignored.
34 |
35 | abund = pyatomdb.atomdb.get_data(0,0,'ABUND')
36 | print()
37 | print(abund[1].data.names)
38 | print(abund[1].data[:2])
39 |
40 |
41 | # How the datacache works
42 | # The datacache variable stores opened files in memory, preventing
43 | # having to go and re-open them each time. This reduces disk access.
44 |
45 | # make sure file is downloaded for a fair test:
46 | a = pyatomdb.atomdb.get_data(Z,z1,'EC')
47 |
48 | # case 1: no datacache
49 | t1 = time.time()
50 | for i in range(10):
51 | a = pyatomdb.atomdb.get_data(Z,z1,'EC')
52 | t2 = time.time()
53 |
54 | # case 2: using datacache
55 | datacache = {}
56 | t3 = time.time()
57 | for i in range(10):
58 | a = pyatomdb.atomdb.get_data(Z,z1,'EC', datacache=datacache)
59 | t4 = time.time()
60 |
61 | print("Time without / with datacache: %f / %f seconds"%(t2-t1, t4-t3))
62 |
--------------------------------------------------------------------------------
/pyatomdb/examples/atomdb_example_2_get_maxwell.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, numpy, pylab
2 |
3 | # We will get some maxwellian rates for a O 6+ 7->1
4 |
5 | Z = 8
6 | z1 = 7
7 | up = 7
8 | lo = 1
9 |
10 | # excitation
11 |
12 | Te = numpy.logspace(6, 7, 15)
13 |
14 | # >>> # (1) Get excitation rates for row 12 of an Fe XVII file
15 | # >>> colldata = pyatomdb.atomdb.get_data(26,17,'EC')
16 | # >>> exc, dex = get_maxwell_rate(Te, colldata=colldata, index=12)
17 |
18 | # >>> # (2) Get excitation rates for row 12 of an Fe XVII file
19 | # >>> exc, dex = get_maxwell_rate(Te, Z=26,z1=17, index=12)
20 |
21 | # >>> (3) Get excitation rates for transitions from level 1 to 15 of FE XVII
22 | # >>> exc, dex = get_maxwell_rate(Te, Z=26, z1=17, dtype='EC', finallev=15, initlev=1)
23 |
24 | datacache = {}
25 |
26 | # get data by specifying ion, upper and lower levels
27 | exc, dexc = pyatomdb.atomdb.get_maxwell_rate(Te, Z=Z, z1=z1, initlev = lo, finallev=up, dtype='EC', datacache=datacache)
28 |
29 | fig= pylab.figure()
30 | fig.show()
31 | ax = fig.add_subplot(111)
32 | ax.loglog(Te, exc, label='excitation')
33 | ax.loglog(Te, dexc, label = 'deexcitation')
34 |
35 |
36 | # preload data and find a specific transition
37 | ecdat = pyatomdb.atomdb.get_data(8,7,'EC', datacache=datacache)
38 |
39 | i = numpy.where( (ecdat[1].data['Upper_Lev']==up) &\
40 | (ecdat[1].data['Lower_Lev']==lo))[0][0]
41 |
42 | exc, dex = pyatomdb.atomdb.get_maxwell_rate(Te,colldata=ecdat, index=i, datacache=datacache)
43 |
44 | ax.loglog(Te, exc, 'o', label='excitation')
45 | ax.loglog(Te, dexc, 'o', label = 'deexcitation')
46 |
47 | ax.legend(loc=0)
48 | ax.set_xlabel("Temperature (K)")
49 | ax.set_ylabel("Rate Coefficient (cm$^3$ s$^{-1}$)")
50 |
51 | pylab.draw()
52 | zzz=input("Press enter to continue")
53 | # save image files
54 | fig.savefig('atomdb_examples_2_1.pdf')
55 | fig.savefig('atomdb_examples_2_1.svg')
56 |
57 | # you can also obtain ionization or recombination rates (see get_maxwell_rates writeup for options)
58 | # in most cases you need to specify initlev and finallev as 1 to get the ion to ion rates.
59 |
60 | ion= pyatomdb.atomdb.get_maxwell_rate(Te,Z=Z, z1=z1, initlev=1, finallev=1, dtype='CI', datacache=datacache)
61 | print(ion)
62 | #
63 | # However it is recommended that you use get_ionrec_rate instead - it gives you everythign in one go
64 |
65 | # combining the different types
66 | ion, rec = pyatomdb.atomdb.get_ionrec_rate(Te, Z=Z, z1=z1, datacache=datacache)
67 |
68 | # as separate entities
69 | CI, EA, RR, DR=pyatomdb.atomdb.get_ionrec_rate(Te, Z=Z, z1=z1, datacache=datacache, separate=True)
70 |
71 | print("Collisional ionization: ",CI)
72 | print("Excitation Autoionization: ",EA)
73 | print("Radiative Recombination: ",RR)
74 | print("Dielectroni Recombination: ",DR)
75 | ax.cla()
76 |
77 | ax.loglog(Te, ion, label='Ionization')
78 | ax.loglog(Te, rec, label='Recombination')
79 |
80 | ax.loglog(Te, CI, '--',label='CI')
81 | ax.loglog(Te, EA, '--',label='EA')
82 | ax.loglog(Te, RR, '--',label='RR')
83 | ax.loglog(Te, DR, '--',label='DR')
84 |
85 | ax.legend(loc=0)
86 | ax.set_xlabel("Temperature (K)")
87 | ax.set_ylabel("Rate Coefficient (cm$^3$ s$^{-1}$)")
88 |
89 | pylab.draw()
90 | zzz=input("Press enter to continue")
91 | # save image files
92 | fig.savefig('atomdb_examples_2_2.pdf')
93 | fig.savefig('atomdb_examples_2_2.svg')
94 |
95 |
96 | #get_maxwell_rate(Te, colldata=False, index=-1, lvdata=False, Te_unit='K', \
97 | # lvdatap1=False, ionpot = False, \
98 | # force_extrap=False, silent=True,\
99 | # finallev=False, initlev=False,\
100 | # Z=-1, z1=-1, dtype=False, exconly=False,\
101 | # datacache=False, settings=False, ladat=False):
102 |
--------------------------------------------------------------------------------
/pyatomdb/examples/atomdb_examples_2_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/atomdb_examples_2_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/atomdb_examples_2_2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/atomdb_examples_2_2.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/calc_power.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, numpy, os, pylab
2 |
3 | """
4 | This code is an example of generating a cooling curve: the total power
5 | radiated in keV cm3 s-1 by each element at each temperature. It will
6 | generate a text file with the emission per element at each temperature
7 | from 1e4 to 1e9K.
8 |
9 | This is similar to the atomdb.lorentz_power function, but with a few
10 | normalizations removed to run a little quicker.
11 |
12 | Note that the Anders and Grevesse (1989) abundances are built in to
13 | this. These can be looked up using atomdb.get_abundance(abundset='AG89'),
14 | or the 'angr' column of the table at
15 | https://heasarc.nasa.gov/xanadu/xspec/xspec11/manual/node33.html#SECTION00631000000000000000
16 |
17 | Adjustable parameters (energy range, element choice) are in the block
18 | marked #### ADJUST THINGS HERE
19 |
20 | Note that any warnings of the nature:
21 | "kT = 0.000862 is below minimum range of 0.000862. Returning lowest kT spectrum available"
22 | should be ignored. This is returning the temperature at our lowest tabulated value but is
23 | a rounding error making it think it is outside our range.
24 |
25 | Usage: python3 calc_power.py
26 | """
27 |
28 | def calc_power(Zlist, cie, Tlist):
29 |
30 | """
31 | Zlist : [int]
32 | List of element nuclear charges
33 | cie : CIESession
34 | The CIEsession object with all the relevant data predefined.
35 | Tlist : array(float)
36 | The temperatures at which to calculate the power (in K)
37 | """
38 |
39 | res = {}
40 | res['power'] = {}
41 | res['temperature'] = []
42 | cie.set_abund(numpy.arange(1,31), 0.0)
43 | kTlist = Tlist*pyatomdb.const.KBOLTZ
44 | en = (cie.ebins_out[1:]+cie.ebins_out[:-1])/2
45 | for i, kT in enumerate(kTlist):
46 |
47 |
48 | print("Doing temperature iteration %i of %i"%(i, len(kTlist)))
49 | T = Tlist[i]
50 |
51 | res['temperature'].append(T)
52 | res['power'][i] = {}
53 |
54 | for Z in Zlist:
55 |
56 | if Z==0:
57 | # This is the electron-electron bremstrahlung component alone
58 |
59 | #set all abundances to 1 (I need a full census of electrons in the plasma for e-e brems)
60 | cie.set_abund(Zlist[1:], 1.0)
61 | # turn on e-e bremsstrahlung, turn off everything else:
62 | cie.dolines = False # Exclude lines in spectrum
63 | cie.docont = False # Exclude continuum in spectrum
64 | cie.dopseudo = False # Exclude pseudo continuum in spectrum
65 | cie.do_eebrems = True # Do electron-electron bremsstrahlung
66 |
67 | spec = cie.return_spectrum(kT)
68 |
69 | # Turn them back on
70 | # Turn off eebrems
71 | cie.dolines = True
72 | cie.docont = True
73 | cie.dopseudo = True
74 | cie.do_eebrems = False
75 |
76 | else:
77 | # This is everything else, element by element.
78 |
79 | # turn off all the elements
80 | cie.set_abund(Zlist[1:], 0.0)
81 | # turn back on this element
82 | cie.set_abund(Z, 1.0)
83 |
84 | spec = cie.return_spectrum(kT)
85 | # if Z = 1, do the eebrems (only want to calculate this once)
86 | # if Z == 1:
87 | # cie.set_eebrems(True)
88 | # else:
89 | # cie.set_eebrems(False)
90 |
91 |
92 | # get spectrum in ph cm3 s-1
93 | #spec = cie.return_spectrum(kT)
94 |
95 | # convert to keV cm3 s-1, sum
96 | res['power'][i][Z] = sum(spec*en)
97 |
98 | return res
99 |
100 | if __name__=='__main__':
101 |
102 | ############################
103 | #### ADJUST THINGS HERE ####
104 | ############################
105 |
106 | # Elements to include
107 | #Zlist = range(31) <- all the elements
108 | Zlist = [0,1,2,6,7,8,10,12,13,14,16,18,20,26,28] #<- just a few
109 | # Note that for this purpose, Z=0 is the electron-electron bremsstrahlung
110 | # continuum. This is not a general AtomDB convention, just what I've done here
111 | # to make this work.
112 |
113 | # specify photon energy range you want to integrate over (min = 0.001keV, max=100keV)
114 | Elo = 0.001 #keV
115 | Ehi = 100.0 #
116 |
117 | # temperatures at which to calculate curve (K)
118 | Tlist = numpy.logspace(4,9,51)
119 |
120 | # specify output file name (default output.txt)
121 | outfile = 'output.txt'
122 |
123 | ################################
124 | #### END ADJUST THINGS HERE ####
125 | ################################
126 |
127 | # set up the spectrum
128 | cie = pyatomdb.spectrum.CIESession()
129 | ebins = numpy.linspace(Elo, Ehi, 10001)
130 | cie.set_response(ebins, raw=True)
131 | cie.set_eebrems(True)
132 | # crunch the numbers
133 | k = calc_power(Zlist, cie, Tlist)
134 |
135 | # output generation
136 | o = open(outfile, 'w')
137 |
138 | # header row
139 | s = '# Temperature log10(K)'
140 | for i in range(len(Zlist)):
141 | s += ' %12i'%(Zlist[i])
142 | o.write(s+'\n')
143 |
144 | # for each temperature
145 | k['totpower'] = numpy.zeros(len(k['temperature']))
146 |
147 | for i in range(len(k['temperature'])):
148 | s = '%22e'%(numpy.log10(k['temperature'][i]))
149 | for Z in Zlist:
150 | s+=' %12e'%(k['power'][i][Z])
151 | k['totpower'][i]+=k['power'][i][Z]
152 | o.write(s+'\n')
153 |
154 | # notes
155 | o.write("# Total Emissivity in keV cm^3 s^-1 for each element with AG89 abundances, between %e and %e keV\n"%(Elo, Ehi))
156 | o.write("# To get cooling power, multiply by Ne NH")
157 | o.write("# Z=0 component is electron-electron bremsstrahlung component, only significant at high T")
158 | o.close
159 |
160 | fig = pylab.figure()
161 | fig.show()
162 | ax = fig.add_subplot(111)
163 |
164 | ax.loglog(k['temperature'], k['totpower']*pyatomdb.const.ERG_KEV)
165 |
166 | ax.set_xlabel('Temperature (K)')
167 | ax.set_ylabel('Radiated Power (erg cm$^3$ s$^{-1}$)')
168 |
169 | ax.set_xlim(min(Tlist), max(Tlist))
170 |
171 | # draw graphs
172 | pylab.draw()
173 |
174 | zzz=input("Press enter to continue")
175 |
176 | # save image files
177 | fig.savefig('calc_power_examples_1_1.pdf')
178 | fig.savefig('calc_power_examples_1_1.svg')
179 |
180 |
--------------------------------------------------------------------------------
/pyatomdb/examples/calc_power_examples_1_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/calc_power_examples_1_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/calc_power_nei.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, numpy, os, pylab
2 | import astropy.io.fits as pyfits
3 |
4 | """
5 | This code is an example of generating a cooling curve: the total power
6 | radiated in keV cm3 s-1 by each element at each temperature. It will
7 | generate a text file with the emission per element at each temperature
8 | from 1e4 to 1e9K. This has been modified for a non-equilibrium plasma.
9 |
10 | This is similar to the atomdb.lorentz_power function, but with a few
11 | normalizations removed to run a little quicker.
12 |
13 | Note that the Anders and Grevesse (1989) abundances are built in to
14 | this. These can be looked up using atomdb.get_abundance(abundset='AG89'),
15 | or the 'angr' column of the table at
16 | https://heasarc.nasa.gov/xanadu/xspec/xspec11/manual/node33.html#SECTION00631000000000000000
17 |
18 | Adjustable parameters (energy range, element choice) are in the block
19 | marked #### ADJUST THINGS HERE
20 |
21 | Usage: python3 calc_power_nei.py
22 | """
23 |
24 |
25 | def calc_power(Zlist, nei, Tlist, Taulist):
26 | init_pop = 'ionizing'
27 | res = {}
28 | res['power'] = numpy.zeros([len(Tlist), len(Taulist)])
29 | res['temperature'] = []
30 | res['tau'] = []
31 |
32 | # get photon energy of each bin
33 | en = nei.ebins_out
34 | en = (en[1:]+en[:-1])/2
35 |
36 | for i, T in enumerate(Tlist):
37 | kT = T/(1000*11604.5)
38 | res['temperature'].append(kT)
39 | for j, Tau in enumerate(Taulist):
40 | print("Doing temperature iteration %i of %i"%(i, len(Tlist)))
41 |
42 | res['tau'].append(Tau)
43 |
44 |
45 | # This code would go through each element 1 by 1.
46 | # We will do all elements at the same time to simplify
47 |
48 | # for Z in Zlist:
49 | # if Z==0:
50 | # # This is the electron-electron bremstrahlung component alone
51 | #
52 | # #set all abundances to 1 (I need a full census of electrons in the plasma for e-e brems)
53 | # nei.set_abund(Zlist[1:], 1.0)
54 | # # turn on e-e bremsstrahlung
55 | # nei.set_eebrems(True)
56 | # spec = nei.return_spectrum(kT, Tau, init_pop=init_pop, \
57 | # dolines=False, docont=False, dopseudo=False)
58 | # else:
59 | # # This is everything else, element by element.
60 | #
61 | # # turn off all the elements
62 | # nei.set_abund(Zlist[1:], 0.0)
63 | # # turn back on this element
64 | # nei.set_abund(Z, 1.0)
65 | # # turn off e-e bremsstrahlung (avoid double counting)
66 | # nei.set_eebrems(False)
67 | #
68 | # spec = nei.return_spectrum(kT, Tau, init_pop=init_pop)
69 | #
70 |
71 | spec = nei.return_spectrum(kT, Tau, init_pop=init_pop)
72 | E = spec*en
73 | res['power'][i][j] = sum(E)
74 | return(res)
75 |
76 | if __name__=='__main__':
77 |
78 |
79 | ############################
80 | #### ADJUST THINGS HERE ####
81 | ############################
82 |
83 | # Elements to include
84 | #Zlist = range(31) <- all the elements
85 | Zlist = [0,1,2,6,7,8,10,12,13,14,16,18,20,26,28] #<- just a few
86 | # Note that for this purpose, Z=0 is the electron-electron bremsstrahlung
87 | # continuum. This is not a general AtomDB convention, just what I've done here
88 | # to make this work.
89 |
90 | # specify photon energy range you want to integrate over (min = 0.001keV, max=100keV)
91 | Elo = 0.001 #keV
92 | Ehi = 100.0 #
93 |
94 | # temperatures at which to calculate curve (K)
95 | Tlist = numpy.logspace(4,9,51)
96 |
97 | # specify output file name (default output.txt)
98 | outfile = 'output.txt'
99 |
100 | ################################
101 | #### END ADJUST THINGS HERE ####
102 | ################################
103 |
104 | # set up the spectrum
105 | Zlist = numpy.array([0,1,2,6,7,8,10,12,13,14,16,18,20,26,28]) #<- just a few
106 |
107 | nei = pyatomdb.spectrum.NEISession(elements=Zlist[Zlist>0])
108 | if 0 in Zlist:
109 | nei.set_eebrems(True)
110 | ebins = numpy.linspace(Elo, Ehi, 10001)
111 | nei.set_response(ebins, raw=True)
112 | nei.set_eebrems(True)
113 | # crunch the numbers
114 | Taulist = [1e8, 1e10, 1e14]
115 | k = calc_power(Zlist, nei, Tlist, Taulist)
116 |
117 |
118 | fig = pylab.figure()
119 | fig.show()
120 | ax = fig.add_subplot(111)
121 |
122 | for i, tau in enumerate(Taulist):
123 | ax.loglog(k['temperature'], k['power'][:,i]*pyatomdb.const.ERG_KEV, label=repr(int(numpy.log10(tau))))
124 | ax.legend(loc=0)
125 | pylab.draw()
126 |
127 | ax.set_xlabel("Temperature (keV)")
128 | ax.set_ylabel("Radiated Power 0.001-100keV\n(erg cm$^{3}$ s$^{-1}$)")
129 |
130 |
131 | zzz=input("Press enter to continue")
132 | fig.savefig('calc_power_nei_examples_1_1.pdf')
133 | fig.savefig('calc_power_nei_examples_1_1.svg')
134 |
--------------------------------------------------------------------------------
/pyatomdb/examples/calc_power_nei_examples_1_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/calc_power_nei_examples_1_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/first_installation.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 |
3 | """
4 | This script shows the commands you should run when you first download pyatomdb.
5 |
6 | It is recommended that you choose the location you want to install the
7 | AtomDB data files (not the same as the python module) and set your
8 | ATOMDB environment variable to point to it.
9 |
10 |
11 | Parameters
12 | ------
13 | none
14 |
15 | Returns
16 | -------
17 | none
18 |
19 | """
20 |
21 | # call the setup routine
22 | pyatomdb.util.initialize()
23 |
24 | # this routine downloads a bunch of files and sets things up for you. It will
25 | # take a few minutes, depending on your internet connection.
26 |
27 | print("Install complete!")
28 |
29 | #and that's it!
30 |
31 | # If you want to switch versions of atomdb (in this case to 3.0.2) later, call:
32 | # pyatomdb.util.switch_version('3.0.2')
33 |
34 |
--------------------------------------------------------------------------------
/pyatomdb/examples/make_line_list.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 |
3 | """
4 | This code will produce a list of lines in a given wavelength range at a
5 | given temperature. It also shows the use of an NEI version, where you
6 | have to additionally specify the initial ionization temperature (or the
7 | ionization fraction directly) and the elapsed Ne*t.
8 |
9 | The results of the list_lines codes are numpy arrays which can be sorted any
10 | way you wish. You can, of course, extract the lines easily at this point. There
11 | is also a print_lines routine for a fixed format output.
12 |
13 | Parameters
14 | ----------
15 | none
16 |
17 | Returns
18 | -------
19 | none
20 |
21 | """
22 |
23 | # Adam Foster 2015-12-02
24 | # version 0.1
25 |
26 | #specify wavelength range, in Angstroms
27 | wl = [8.0,9.0]
28 |
29 | # electron temperature in K
30 | Te = 1e7
31 |
32 | # get equilibrium line list
33 | CIE = pyatomdb.spectrum.CIESession()
34 |
35 | res = CIE.return_linelist(Te, wl, specunit = 'A', teunit='K')
36 |
37 | #trim off the weaker lines
38 | res = res[res['Epsilon']> 1e-18]
39 |
40 | # reprocess lines for printing
41 | print("Unsorted line list:")
42 | print(CIE.format_linelist(res))
43 |
44 | # re-sort lines
45 | # for more information, look up numpy.sort: res is a numpy array.
46 | # http://docs.scipy.org/doc/numpy/reference/generated/numpy.sort.html
47 |
48 | res.sort(order=['Epsilon'])
49 | res=res[::-1]
50 | print("Top 10 sorted by Emissivity:")
51 | print(CIE.format_linelist(res[:10]))
52 |
53 | # re-sort by element, ion then emissivity
54 | res.sort(order=['Element','Ion','Epsilon'])
55 | print("Top 10 sorted by Element, Ion, Emissivity:")
56 | print(CIE.format_linelist(res[:10]))
57 |
58 |
59 | # now do an NEI version. This is slow at the moment, but functional.
60 | Te_init = 1e4
61 | tau = 1e11
62 | NEI = pyatomdb.spectrum.NEISession()
63 | res_nei = NEI.return_linelist(Te, tau, wl, teunit='K', \
64 | specunit='A',\
65 | init_pop=Te_init)
66 | res_nei = res_nei[res_nei['Epsilon']> 1e-19]
67 | print("NEI linelist:")
68 | print(NEI.format_linelist(res_nei[:10]))
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/pyatomdb/examples/make_spectrum.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, numpy, pylab
2 |
3 | # set up a grid of energy bins to model the spectrum on:
4 | ebins=numpy.linspace(0.3,10,10000)
5 |
6 | # define a broadening, in keV, for the lines
7 | de = 0.01
8 |
9 | # define the temperature at which to plot (keV)
10 | te = 3.0
11 |
12 | # declare a CIESession
13 | CIE = pyatomdb.spectrum.CIESession()
14 |
15 | # set the response. Raw keyword makes it a diagonal response
16 | # (no line spread or effective area)
17 |
18 | CIE.set_response(ebins, raw=True)
19 |
20 | # create both a broadened and an unbroadened spectrum
21 | a = CIE.return_spectrum(te)
22 |
23 | # turn on broadening
24 | CIE.set_broadening(True)
25 | b = CIE.return_spectrum(te)
26 |
27 | # plot the results
28 | fig = pylab.figure()
29 | fig.show()
30 | ax = fig.add_subplot(111)
31 |
32 | ax.loglog(ebins, numpy.append(a[0], a), drawstyle='steps', label='Unbroadened')
33 | ax.loglog(ebins, numpy.append(b[0],b), drawstyle='steps', label='Thermal')
34 | ax.set_xlabel('Energy (keV)')
35 | ax.set_ylabel('Emissivity (ph cm$^{3}$ s$^{-1}$ bin$^{-1}$)')
36 | ax.legend(loc=0)
37 | pylab.draw()
38 | zzz = input("Press enter to continue")
39 |
40 | print("Listing lines between 1 and 2 A")
41 | # now list the lines in a wavelength region
42 | llist = CIE.return_linelist(te, [1,2.0])
43 | # print these to screen
44 | # print to screen, listing the energy, not the wavelength
45 | print("Listing lines between 1 and 2 A, first 10 lines only.")
46 |
47 | print(CIE.format_linelist(llist[:10]))
48 |
49 |
--------------------------------------------------------------------------------
/pyatomdb/examples/new_make_spectrum.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, pylab, numpy, time
2 |
3 |
4 | rmf = 'aciss_meg1_cy22.grmf'
5 | arf = 'aciss_meg1_cy22.garf'
6 |
7 |
8 | # create a session object. This contains the apec files, response files,
9 | # and any previously calculated spectrs so that simple multiplication
10 | # can be used to get the results without recalculating everything from scratch
11 |
12 | data = pyatomdb.spectrum.CIESession()
13 |
14 | # If you want to specify custom energy bins:
15 | ebins = numpy.linspace(1,2,1001)
16 | data.set_response(ebins, raw=True)
17 |
18 | # alternative method: just load the response and use its binning. Note
19 | # that this will always be in keV currently, because reasons.
20 |
21 | data.set_response(rmf, arf=arf)
22 | ebins = data.ebins_out
23 |
24 | # now get the spectrum at 4keV. This calculates (and stores) the
25 | # spectrum at each temperature nearby (~3.7, 4.3 keV)
26 | # then linearly interpolates between the result
27 | #
28 | # vector is stored for each element at each temperature
29 | # so if you change temperature/abundance, it's a simple multiplication and
30 | # interpolation instead of a total recalculation
31 |
32 | t0 = time.time()
33 | s=data.return_spectrum(4.0, teunit='keV')
34 | t1 = time.time()
35 | # let's change the abundance
36 | data.set_abund([1,2,3,4,26],0.5)
37 |
38 | # and see how fast this goes this time, changing temperature and abund
39 | s2=data.return_spectrum(4.1, teunit='keV')
40 | t2 = time.time()
41 |
42 | print("first spectrum took %g seconds" %(t1-t0))
43 | print("second spectrum took %g seconds" %(t2-t1))
44 | print("note how much faster the second one was as I didn't recalculate everything from scratch!")
45 |
46 |
47 | #linedata = pyatomdb.pyfits.open('/export1/atomdb_latest/apec_v3.0.8_line.fits')
48 |
49 |
50 | #spec = speclo*rlo + specup*rup
51 |
52 | # some plotting of things
53 |
54 | fig = pylab.figure()
55 | fig.show()
56 | ax = fig.add_subplot(111)
57 | #ax2 = fig.add_subplot(212, sharex=ax)
58 | s = numpy.append(0,s)
59 | s += 1e-40
60 |
61 | s2 = numpy.append(0,s2)
62 | s2 += 1e-40
63 | #spec = numpy.append(0,spec)
64 | #spec += 1e-40
65 |
66 | ax.plot(ebins, s, drawstyle='steps')
67 | ax.plot(ebins, s2, drawstyle='steps')
68 | #ax.plot(elo, spec, drawstyle='steps')
69 |
70 |
71 | #ax2.plot(elo, s/spec, drawstyle='steps')
72 |
73 |
74 | zzz=input('Press enter to exit')
75 |
--------------------------------------------------------------------------------
/pyatomdb/examples/osc_str.py:
--------------------------------------------------------------------------------
1 | ## Author: Priyanka Chakraborty 07/30/2022
2 | ## Description: this code add an extra column for oscillator strength to apec_v3.0.9_line.fits
3 |
4 |
5 | import numpy as np
6 | from astropy.io import fits
7 | import pandas as pd
8 | import time
9 | from itertools import compress
10 | import math
11 | #import pyatomdb
12 | import os
13 | #import atomdb,apec
14 |
15 | t = time.process_time()
16 |
17 |
18 |
19 | if os.path.exists(os.path.expandvars('$ATOMDB/apec_v3.0.9_osc.fits')) == False:
20 |
21 | emi_file = fits.open(os.path.expandvars('$ATOMDB/apec_v3.0.9_line.fits')) ## opening fits file
22 |
23 | for j in range(2,len(emi_file)): ### running loops on emissivity extension ##
24 |
25 | emi_lambda = emi_file[j].data['Lambda']
26 | emi_elem = emi_file[j].data['Element']
27 | emi_ion = emi_file[j].data['Ion']
28 | emi_ulev = emi_file[j].data['UpperLev']
29 | emi_llev = emi_file[j].data['LowerLev']
30 |
31 |
32 | fij = []
33 | datacache={}
34 |
35 | settings=apec.parse_par_file(os.path.expandvars('$ATOMDB/apec.par'))
36 |
37 |
38 | for i in range (len(emi_elem)):
39 | index = 0.1
40 | Z = emi_elem[i]
41 | z1 = emi_ion[i]
42 |
43 | ### fetching upperlevel and lower level from ladat and lvdat
44 | ladat = atomdb.get_data(Z,z1,'LA', datacache=datacache, settings=settings)
45 | lvdat = atomdb.get_data(Z,z1,'LV', datacache=datacache, settings=settings)
46 |
47 | if ladat != False:
48 |
49 | upper_lev = ladat[1].data['upper_lev']
50 | lower_lev = ladat[1].data['lower_lev']
51 |
52 | #### fetiching indices for matched upper and lower level
53 | get_indecies = lambda xx, xxs: [iii for (yy, iii) in zip(xxs, range(len(xxs))) if xx == yy]
54 |
55 | index_up = get_indecies(emi_ulev[i],upper_lev)
56 | index_lo = get_indecies(emi_llev[i],lower_lev)
57 |
58 | for ii in range(len(index_up)):
59 | if index_up[ii] in index_lo:
60 | index = index_up[ii]
61 | break
62 |
63 | if index != 0.1:
64 |
65 | #### estimating oscillator strength ####
66 | larate = ladat[1].data['EINSTEIN_A'][index]
67 | wavelength = ladat[1].data['wavelen'][index]
68 |
69 | stat_weight = lvdat[1].data['lev_deg'][upper_lev[index]-1]/(lvdat[1].data['lev_deg'][lower_lev[index]-1])
70 | fij.append(1.4992e-8*larate*1e-8*(wavelength**2)*stat_weight)
71 |
72 | else:
73 | larate = 0.0
74 | wavelength = 0.0
75 |
76 | stat_weight = 0.0
77 | fij.append(0.0)
78 |
79 | print(j,i,Z,z1,emi_ulev[i],emi_llev[i])
80 |
81 | #### writing oscillator strength to fits file as a new column ####
82 | osc_st = fits.Column(name='Oscil_str', array=fij,format='1E')
83 | new_column = emi_file[j].columns + osc_st
84 | new_hdu = fits.BinTableHDU.from_columns(new_column)
85 | emi_file[j].data = new_hdu.data
86 | emi_file.writeto('apec_v3.0.9_osc.fits',overwrite=True)
87 |
88 | print('elapsed time for',j,'th extension',time.process_time() - t)
89 |
90 |
91 |
92 | print('time for entire run',time.process_time() - t)
93 |
94 | emi_file.close()
95 |
96 | else:
97 |
98 | ## limiting upper wavelength limit to 40 angstorm
99 |
100 | linefile = "$ATOMDB/apec_v3.0.9_osc.fits"
101 |
102 | lfile = os.path.expandvars(linefile)
103 | linedata = fits.open(lfile)
104 |
105 | linedata[1].header['COMMENTS'] = 'The upper-limit of wavelength is 40 angstrom'
106 |
107 | ext_num = len(linedata[1].data['kT']) ## number of temperature parameters
108 |
109 | for i in range(2, ext_num):
110 |
111 | wlambda = linedata[i].data['Lambda']
112 | wlambda_err = linedata[i].data['Lambda_Err']
113 | epsilon = linedata[i].data['Epsilon']
114 | epsilon_err = linedata[i].data['Epsilon_Err']
115 | element = linedata[i].data['Element']
116 | ion = linedata[i].data['Ion']
117 | upperlev = linedata[i].data['UpperLev']
118 | lowerlev = linedata[i].data['LowerLev']
119 | oscil_str = linedata[i].data['Oscil_str']
120 |
121 | ## getting the index where lambda > 40 ang
122 |
123 | index = np.where(wlambda < 40)[0]
124 |
125 | wlambda_new = fits.Column(name='Lambda', array=wlambda[index],format='1E')
126 | wlambda_err_new = fits.Column(name='Lambda_Err', array=wlambda_err[index],format='1E')
127 | epsilon_new = fits.Column(name='Epsilon', array=epsilon[index],format='1E')
128 | epsilon_err_new = fits.Column(name='Epsilon_Err', array=epsilon_err[index],format='1E')
129 | element_new = fits.Column(name='Element', array=element[index],format='1J')
130 | ion_new = fits.Column(name='Ion', array=ion[index],format='1J')
131 | upperlev_new = fits.Column(name='UpperLev', array=upperlev[index],format='1J')
132 | lowerlev_new = fits.Column(name='LowerLev', array=lowerlev[index],format='1J')
133 | oscil_str_new = fits.Column(name='Oscil_str', array=oscil_str[index],format='1E')
134 |
135 | new_hdu = fits.BinTableHDU.from_columns([wlambda_new, wlambda_err_new, epsilon_new, epsilon_err_new, element_new, ion_new, upperlev_new, lowerlev_new, oscil_str_new])
136 | linedata[i].data = new_hdu.data
137 |
138 |
139 |
140 | linedata.writeto(os.path.expandvars('$ATOMDB/apec_v3.0.9_osc.fits'), overwrite=True)
141 |
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/pyatomdb/examples/output.txt:
--------------------------------------------------------------------------------
1 | # Temperature log10(K) 0 1 2 6 7 8 10 12 13 14 16 18 20 26 28
2 | 4.000000e+00 0.000000e+00 2.195959e-15 5.261469e-21 4.523786e-14 5.407950e-17 3.347558e-14 6.363935e-21 5.648319e-15 3.320730e-17 6.142661e-15 4.189772e-15 1.396110e-20 1.212614e-16 8.121514e-15 9.522474e-17
3 | 4.100000e+00 0.000000e+00 2.379262e-14 6.483396e-19 4.053404e-14 2.412571e-16 4.592931e-14 1.653105e-19 6.590210e-15 8.210325e-17 1.463061e-15 3.275290e-15 1.956645e-19 2.823361e-16 9.455144e-15 1.209662e-16
4 | 4.200000e+00 0.000000e+00 8.487070e-14 3.057073e-17 1.491507e-14 1.706225e-15 3.167218e-14 2.215953e-18 7.116494e-15 1.875367e-16 9.484036e-16 3.714312e-15 1.113854e-18 2.920430e-16 1.068787e-14 1.644499e-16
5 | 4.300000e+00 0.000000e+00 6.978293e-14 6.713104e-16 7.677669e-15 4.418319e-15 2.396890e-14 1.635206e-17 3.372379e-15 3.726760e-16 1.501606e-15 4.362858e-15 2.466714e-18 1.040153e-16 8.030644e-15 1.869592e-16
6 | 4.400000e+00 0.000000e+00 3.977845e-14 6.921377e-15 9.228002e-15 6.053239e-15 2.967312e-14 3.788214e-17 7.756705e-16 6.492158e-16 2.751824e-15 4.544359e-15 2.723287e-17 2.965747e-17 7.504755e-15 1.853446e-16
7 | 4.500000e+00 0.000000e+00 2.342998e-14 2.574437e-14 1.599300e-14 7.483791e-15 3.845682e-14 2.888141e-17 1.985610e-16 9.707860e-16 4.762501e-15 4.128916e-15 1.947034e-16 9.773225e-18 7.914278e-15 2.044016e-16
8 | 4.600000e+00 0.000000e+00 1.478446e-14 2.278605e-14 3.171295e-14 8.903714e-15 4.945423e-14 9.703458e-17 6.343667e-17 9.090477e-16 7.560151e-15 4.126068e-15 3.456402e-16 6.585472e-18 4.926309e-15 2.219130e-16
9 | 4.700000e+00 0.000000e+00 9.920347e-15 2.030359e-14 6.237693e-14 1.087040e-14 6.449884e-14 5.864157e-16 2.467847e-17 2.709168e-16 1.114469e-14 4.830316e-15 4.747119e-16 1.491276e-17 2.992966e-15 2.252101e-16
10 | 4.800000e+00 0.000000e+00 7.014237e-15 3.473816e-14 1.063634e-13 1.527021e-14 8.682272e-14 1.956662e-15 1.300999e-17 6.306839e-17 1.485882e-14 6.229224e-15 7.093201e-16 4.550725e-17 3.341292e-15 2.123360e-16
11 | 4.900000e+00 0.000000e+00 5.200220e-15 6.214042e-14 1.537850e-13 2.259194e-14 1.184434e-13 4.123644e-15 1.919092e-17 1.884960e-17 1.124295e-14 8.681712e-15 1.114727e-15 1.180792e-16 4.331414e-15 1.692964e-16
12 | 5.000000e+00 0.000000e+00 4.026130e-15 4.997439e-14 1.576903e-13 3.224212e-14 1.617901e-13 7.614470e-15 7.325795e-17 7.548654e-18 2.837977e-15 1.195943e-14 1.668858e-15 2.593129e-16 5.358048e-15 1.282324e-16
13 | 5.100000e+00 0.000000e+00 3.239060e-15 2.978967e-14 5.567488e-14 4.273280e-14 2.201737e-13 1.329159e-14 2.746179e-16 5.771556e-18 6.770713e-16 1.470368e-14 2.338679e-15 4.939399e-16 6.037933e-15 9.230286e-17
14 | 5.200000e+00 0.000000e+00 2.706216e-15 1.786532e-14 1.190646e-14 4.694527e-14 2.858023e-13 2.030703e-14 8.147993e-16 1.337471e-17 2.294897e-16 1.589466e-14 3.050145e-15 8.485639e-16 6.454971e-15 8.535107e-17
15 | 5.300000e+00 0.000000e+00 2.338926e-15 1.130942e-14 3.317182e-15 2.399501e-14 3.448630e-13 2.850150e-14 1.996075e-15 4.424592e-17 1.659653e-16 8.528958e-15 3.810216e-15 1.321806e-15 7.731081e-15 1.253471e-16
16 | 5.400000e+00 0.000000e+00 2.085772e-15 7.556607e-15 1.213071e-15 5.593975e-15 3.733613e-13 3.784446e-14 3.747795e-15 1.180525e-16 3.641595e-16 1.582745e-15 4.571530e-15 1.862882e-15 1.170315e-14 2.282291e-16
17 | 5.500000e+00 0.000000e+00 1.916401e-15 5.312333e-15 5.443221e-16 1.515455e-15 2.301839e-13 4.659649e-14 5.758403e-15 2.450500e-16 1.069277e-15 4.332986e-16 4.550832e-15 2.430615e-15 1.939321e-14 3.761546e-16
18 | 5.600000e+00 0.000000e+00 1.812090e-15 3.913869e-15 3.121876e-16 5.513114e-16 7.233421e-14 5.342084e-14 7.915959e-15 4.255338e-16 2.530950e-15 3.340753e-16 1.315883e-15 2.935095e-15 2.967825e-14 5.953101e-16
19 | 5.700000e+00 0.000000e+00 1.756744e-15 3.009040e-15 3.279648e-16 2.525029e-16 2.339497e-14 5.416175e-14 1.031831e-14 6.563420e-16 4.634576e-15 5.927858e-16 2.632437e-16 2.995773e-15 4.146163e-14 9.693602e-16
20 | 5.800000e+00 3.025610e-19 1.733704e-15 2.411872e-15 6.798999e-16 1.568052e-16 9.191744e-15 3.344187e-14 1.253453e-14 8.720664e-16 7.055122e-15 1.219487e-15 1.350332e-16 1.060280e-15 5.357773e-14 1.467626e-15
21 | 5.900000e+00 3.994178e-19 1.744344e-15 2.010624e-15 1.398881e-15 1.813787e-16 4.428682e-15 1.085051e-14 1.392244e-14 1.023310e-15 9.379979e-15 2.141594e-15 1.739253e-16 2.552298e-16 6.442704e-14 2.002882e-15
22 | 6.000000e+00 5.321634e-19 1.784231e-15 1.738996e-15 2.068970e-15 3.419525e-16 2.970596e-15 3.626929e-15 1.172409e-14 1.098452e-15 1.105517e-14 3.086812e-15 3.140962e-16 1.532428e-16 7.103855e-14 2.469777e-15
23 | 6.100000e+00 7.153373e-19 1.850225e-15 1.559387e-15 2.075043e-15 6.053914e-16 3.331247e-15 1.547710e-15 5.042194e-15 9.354862e-16 1.163159e-14 3.928473e-15 5.341154e-16 1.791248e-16 7.039511e-14 2.757680e-15
24 | 6.200000e+00 9.694808e-19 1.941808e-15 1.445179e-15 1.498622e-15 8.192659e-16 5.009997e-15 8.763318e-16 1.703939e-15 4.478828e-16 9.806054e-15 4.717260e-15 7.669647e-16 2.712235e-16 5.182363e-14 2.677989e-15
25 | 6.300000e+00 1.323618e-18 2.054391e-15 1.379869e-15 9.889731e-16 7.859856e-16 7.068597e-15 7.354449e-16 7.146037e-16 1.659671e-16 4.926053e-15 5.189007e-15 9.565393e-16 4.072711e-16 1.648796e-14 2.110907e-15
26 | 6.400000e+00 1.818656e-18 2.192191e-15 1.347184e-15 6.682266e-16 5.818859e-16 7.916200e-15 9.036461e-16 4.062575e-16 7.290563e-17 1.957260e-15 4.180396e-15 1.092467e-15 5.465034e-16 8.959194e-15 7.981524e-16
27 | 6.500000e+00 2.512512e-18 2.355815e-15 1.345031e-15 4.729967e-16 4.020012e-16 6.584158e-15 1.259540e-15 3.321463e-16 4.205815e-17 9.219877e-16 1.961184e-15 1.088918e-15 6.490998e-16 8.588184e-15 3.592110e-16
28 | 6.600000e+00 3.486918e-18 2.546398e-15 1.368873e-15 3.518178e-16 2.827107e-16 4.688537e-15 1.575536e-15 3.779031e-16 3.368980e-17 5.713324e-16 8.146731e-16 7.511087e-16 6.979473e-16 1.025796e-14 3.068325e-16
29 | 6.700000e+00 4.857786e-18 2.765690e-15 1.415888e-15 2.739061e-16 2.070704e-16 3.269336e-15 1.539579e-15 4.941534e-16 3.628599e-17 4.809133e-16 4.262546e-16 3.442246e-16 5.973832e-16 1.280994e-14 3.336016e-16
30 | 6.800000e+00 6.789176e-18 3.021123e-15 1.485232e-15 2.224246e-16 1.583793e-16 2.348873e-15 1.212917e-15 6.116169e-16 4.465527e-17 5.197750e-16 3.004914e-16 1.626566e-16 3.256128e-16 1.537506e-14 4.028480e-16
31 | 6.900000e+00 9.513259e-18 3.310679e-15 1.572537e-15 1.877794e-16 1.262966e-16 1.766761e-15 8.793106e-16 6.320902e-16 5.265170e-17 6.220229e-16 2.785384e-16 9.901991e-17 1.525211e-16 1.688100e-14 4.841186e-16
32 | 7.000000e+00 1.335866e-17 3.637298e-15 1.680157e-15 1.644667e-16 1.046359e-16 1.393156e-15 6.394130e-16 5.411664e-16 5.293728e-17 7.078017e-16 3.073347e-16 7.935219e-17 8.689384e-17 1.597647e-14 5.387067e-16
33 | 7.100000e+00 1.879025e-17 4.003487e-15 1.808541e-15 1.491995e-16 8.982836e-17 1.147388e-15 4.835421e-16 4.183824e-16 4.494935e-17 6.977571e-16 3.525086e-16 7.870788e-17 6.442521e-17 1.151777e-14 5.279518e-16
34 | 7.200000e+00 2.646473e-17 4.415475e-15 1.958410e-15 1.398645e-16 7.979235e-17 9.838373e-16 3.831530e-16 3.175622e-16 3.477763e-17 5.935182e-16 3.780068e-16 8.629635e-17 5.968196e-17 6.277477e-15 3.987296e-16
35 | 7.300000e+00 3.731060e-17 4.890784e-15 2.130895e-15 1.347563e-16 7.323810e-17 8.762774e-16 3.172436e-16 2.475526e-16 2.657658e-17 4.653735e-16 3.591968e-16 9.408735e-17 6.289412e-17 3.536296e-15 2.297049e-16
36 | 7.400000e+00 5.264196e-17 5.422834e-15 2.332542e-15 1.328842e-16 6.923541e-17 8.078013e-16 2.735152e-16 2.003721e-16 2.094143e-17 3.623441e-16 3.055894e-16 9.515313e-17 6.832958e-17 2.420201e-15 1.357736e-16
37 | 7.500000e+00 7.431721e-17 6.017826e-15 2.561199e-15 1.339344e-16 6.705183e-17 7.679992e-16 2.459774e-16 1.683160e-16 1.718684e-17 2.907066e-16 2.472106e-16 8.703890e-17 7.105685e-17 1.984878e-15 9.651773e-17
38 | 7.600000e+00 1.049641e-16 6.693581e-15 2.819173e-15 1.374713e-16 6.653305e-17 7.475962e-16 2.267938e-16 1.465284e-16 1.468167e-17 2.423416e-16 2.009526e-16 7.416069e-17 6.792702e-17 1.844014e-15 8.040041e-17
39 | 7.700000e+00 1.482980e-16 7.455090e-15 3.108271e-15 1.433393e-16 6.745830e-17 7.447419e-16 2.155880e-16 1.318760e-16 1.303294e-17 2.100105e-16 1.679052e-16 6.204564e-17 6.021882e-17 1.834884e-15 7.517490e-17
40 | 7.800000e+00 2.095716e-16 8.313383e-15 3.433260e-15 1.512835e-16 6.965014e-17 7.569305e-16 2.105581e-16 1.223877e-16 1.197714e-17 1.888523e-16 1.451721e-16 5.259303e-17 5.165696e-17 1.861706e-15 7.537059e-17
41 | 7.900000e+00 2.962102e-16 9.282109e-15 3.811912e-15 1.612570e-16 7.304170e-17 7.822831e-16 2.102852e-16 1.167220e-16 1.134875e-17 1.756066e-16 1.301015e-16 4.577824e-17 4.437528e-17 1.853952e-15 7.663321e-17
42 | 8.000000e+00 4.187062e-16 1.037481e-14 4.236088e-15 1.733334e-16 7.753892e-17 8.202541e-16 2.140990e-16 1.141345e-16 1.103797e-17 1.680480e-16 1.205019e-16 4.116331e-17 3.890649e-17 1.792991e-15 7.704950e-17
43 | 8.100000e+00 5.918429e-16 1.161115e-14 4.710514e-15 1.875669e-16 8.312575e-17 8.707057e-16 2.214540e-16 1.141677e-16 1.098475e-17 1.648568e-16 1.149101e-16 3.819793e-17 3.514933e-17 1.689415e-15 7.588704e-17
44 | 8.200000e+00 8.361838e-16 1.300953e-14 5.253591e-15 2.040176e-16 8.978478e-17 9.329583e-16 2.323617e-16 1.164595e-16 1.115130e-17 1.652940e-16 1.123370e-16 3.646832e-17 3.273169e-17 1.568531e-15 7.316249e-17
45 | 8.300000e+00 1.179319e-15 1.459495e-14 5.869250e-15 2.236086e-16 9.748313e-17 1.006598e-15 2.464652e-16 1.207517e-16 1.149961e-17 1.687366e-16 1.122255e-16 3.566307e-17 3.132029e-17 1.459439e-15 6.955278e-17
46 | 8.400000e+00 1.655842e-15 1.636658e-14 6.557277e-15 2.465393e-16 1.062433e-16 1.090129e-15 2.643128e-16 1.268314e-16 1.200979e-17 1.746004e-16 1.140433e-16 3.558770e-17 3.064120e-17 1.373649e-15 6.618114e-17
47 | 8.500000e+00 2.305236e-15 1.831714e-14 7.313903e-15 2.712166e-16 1.169691e-16 1.180628e-15 2.841981e-16 1.345705e-16 1.263949e-17 1.823862e-16 1.172452e-16 3.603332e-17 3.049975e-17 1.312002e-15 6.339508e-17
48 | 8.600000e+00 3.168178e-15 2.040350e-14 8.122274e-15 2.964207e-16 1.280499e-16 1.294235e-15 3.048509e-16 1.434286e-16 1.340849e-17 1.914685e-16 1.213714e-16 3.680856e-17 3.070877e-17 1.269352e-15 6.114450e-17
49 | 8.700000e+00 4.282981e-15 2.257137e-14 8.954221e-15 3.208997e-16 1.387785e-16 1.406805e-15 3.249387e-16 1.521445e-16 1.420103e-17 2.023485e-16 1.259041e-16 3.777861e-17 3.112444e-17 1.240897e-15 5.918169e-17
50 | 8.800000e+00 5.683943e-15 2.515604e-14 9.784500e-15 3.465285e-16 1.485948e-16 1.510242e-15 3.518179e-16 1.599940e-16 1.491856e-17 2.123193e-16 1.317295e-16 3.881849e-17 3.163756e-17 1.222281e-15 5.758230e-17
51 | 8.900000e+00 7.402199e-15 2.754837e-14 1.058806e-14 3.729451e-16 1.574386e-16 1.598147e-15 3.755969e-16 1.691000e-16 1.551020e-17 2.205925e-16 1.367746e-16 4.033215e-17 3.219996e-17 1.209987e-15 5.623359e-17
52 | 9.000000e+00 1.063311e-14 2.962537e-14 1.135211e-14 3.947383e-16 1.684811e-16 1.667012e-15 3.951145e-16 1.799965e-16 1.644053e-17 2.277097e-16 1.406516e-16 4.164305e-17 3.331075e-17 1.203620e-15 5.511429e-17
53 | # Total Emissivity in keV cm^3 s^-1 for each element with AG89 abundances, between 1.000000e-03 and 1.000000e+02 keV
54 | # To get cooling power, multiply by Ne NH# Z=0 component is electron-electron bremsstrahlung component, only significant at high T
--------------------------------------------------------------------------------
/pyatomdb/examples/photoionization_data.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, numpy,os, pylab
2 | try:
3 | import astropy.io.fits as pyfits
4 | except:
5 | import pyfits
6 |
7 | # This is a sample routine that reads in the photoionization data
8 | # It also demonstrates using get_data, which should download the data you
9 | # need automagically from the AtomDB site.
10 | #
11 | # It also shows how to get the raw XSTAR PI cross sections.
12 |
13 | # going to get PI cross section from iron 16+ to 17+ (Fe XVII-XVIII)
14 | Z = 26
15 | z1 = 17
16 |
17 | # get the AtomDB level data
18 | lvdata = pyatomdb.atomdb.get_data(Z, z1, 'LV')
19 |
20 | # get the XSTAR PI data from AtomDB
21 | pidata = pyatomdb.atomdb.get_data(Z, z1, 'PI')
22 |
23 | # set up the figure
24 | fig = pylab.figure()
25 | fig.show()
26 | ax = fig.add_subplot(111)
27 |
28 |
29 | # to calculate the cross section (in cm^2) at a given single energy E (in keV)
30 | # does not currently work with vector input, so have to call in a loop if you
31 | # want multiple energies [I will fix this]
32 |
33 | E = 10.
34 |
35 | # get the ground level (the 0th entry in LV file) data
36 | lvd = lvdata[1].data[0]
37 |
38 | # This is the syntax for calculating the PI cross section of a given line
39 | # This will work for non XSTAR data too.
40 | sigma = pyatomdb.atomdb.sigma_photoion(E, Z, z1,lvd['phot_type'], lvd['phot_par'], \
41 | xstardata=pidata, xstarfinallev=1)
42 |
43 |
44 | # To get the raw XSTAR cross sections (units: energy = keV, cross sections = Mb)
45 | # for level 1 -> 1 (ground to ground)
46 | pixsec = pyatomdb.atomdb.__sort_pi_data(pidata, 1,1)
47 | ax.loglog(pixsec['energy'], pixsec['pi_param']*1e-18, label='raw xstar data')
48 |
49 | # label the plot
50 | ax.set_title('Plotting raw XSTAR PI cross sections. Fe XVII gnd to Fe XVIII gnd')
51 | ax.set_xlabel("Energy (keV)")
52 | ax.set_ylabel("PI cross section (cm$^{2}$)")
53 |
54 | pylab.draw()
55 | zzz=input('press enter to continue')
56 |
--------------------------------------------------------------------------------
/pyatomdb/examples/rsapec.py:
--------------------------------------------------------------------------------
1 | # temporarily add the wrappers folder to the path
2 | import sys
3 | sys.path.append('../wrappers')
4 |
5 |
6 | # import relevant models
7 | # inital import creates rsapec, rsvapec, rsvvapec, analagous to apec, vapec, vvapec but resonance scattered
8 |
9 |
10 | from xspec import *
11 | import rsapec_xspec
12 | import pylab
13 | import matplotlib.pyplot as plt
14 |
15 |
16 | #import the response and spectrum file of Hitomi observation of Perseus core
17 | s = Spectrum('../examples/ah100040030sxs_p0px1010_cl2_HP.pi')
18 | s.response = '../examples/ah100040030_sxs_cl2_HP_small.rmf'
19 | s.response.arf = '../examples/ah100040030sxs_p0px1010_ptsrc.arf'
20 |
21 | #set the energy range for the fitting
22 | s.ignore('**-6.0,7.0-**')
23 |
24 |
25 | # declare a new model and initiate the model parameters
26 | m1 = Model('tbabs*pyapecrs')
27 | m1.TBabs.nH=0.138
28 | m1.TBabs.nH.frozen=True
29 | m1.pyapecrs.kT=4.07740
30 | m1.pyapecrs.nL=1.22260E+22
31 | m1.pyapecrs.Velocity= 172.116
32 | m1.pyapecrs.Abundanc=0.389900
33 | m1.pyapecrs.Redshift=1.72391E-02
34 | m1.pyapecrs.Redshift.frozen=True
35 | m1.pyapecrs.norm=0.960000
36 | Fit.statMethod = "cstat"
37 |
38 | # let's overplot the model and the spectrum
39 |
40 | Plot.device='/null'
41 | Plot.xAxis = "keV"
42 | Plot.setRebin(5,10)
43 | Plot('data')
44 | chans = Plot.x()
45 | rates = Plot.y()
46 | xErrs = Plot.xErr()
47 | yErrs = Plot.yErr()
48 | folded= Plot.model(1)
49 | plt.xlim(6.5,6.6)
50 | plt.plot(chans,folded, color='orange', linewidth=2, label='rsapec model')
51 | plt.errorbar(chans, rates, xerr=xErrs,yerr=yErrs, label='Hitomi observation', fmt=",", color='blue')
52 | plt.xlabel('Energy(keV)')
53 | plt.ylabel('counts/s/keV')
54 | plt.legend(loc='upper left')
55 | pylab.draw()
56 |
57 | # save image files
58 | plt.savefig('Rsapec_hitomi.pdf')
59 | plt.savefig('Rsapec_hitomi.svg')
60 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_NEIsession_examples.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, numpy, pylab
2 |
3 |
4 | # declare the Non-Equilibrium Ionization session
5 | sess = pyatomdb.spectrum.NEISession()
6 |
7 | # set the response (here, a dummy response)
8 | ebins = numpy.linspace(0.6,12.4,1000)
9 | sess.set_response(ebins, raw=True)
10 |
11 | # alternatively, could set to real RMF, ARF files using:
12 | # sess.set_response(rmf, arf=arf)
13 | # where rmf and arf are the file names
14 |
15 | # Turn on (or off) thermal broadening, and if desired velocity broadening
16 | # in this case turn on thermal broadening, and set velocity broadening to 500 km/s
17 |
18 | sess.set_broadening(True, velocity_broadening=500.0)
19 |
20 | # return spectrum at given temperature
21 | kT = 0.8 # temperature in keV
22 | tau = 1e11 # n_e*t cm^-3 s
23 | kT_init=0.01 # initial temperature (for initial ion distribution)
24 |
25 | spec = sess.return_spectrum(kT, tau, init_pop=kT_init)
26 |
27 | # note returned spectrum has units of photons cm^5 s^-1 bin^-1, and has 1 less
28 | # value than the energy bin grid. Prepend a 0 to it for plotting purposes
29 | fig = pylab.figure()
30 | fig.show()
31 | ax = fig.add_subplot(111)
32 | ax.plot(sess.ebins_out, numpy.append(0, spec), drawstyle='steps', label='dummy response')
33 |
34 | #label the figure
35 | ax.set_xlabel('Energy (keV)')
36 | ax.set_ylabel('Intensity (ph cm$^3$ s$^{-1}$ bin$^{-1}$)')
37 |
38 | # now do the same thing but with an instrument response
39 | sess.set_response('../tests/testdata/aciss_heg1_cy19.grmf', \
40 | arf='../tests/testdata/aciss_heg1_cy19.garf')
41 |
42 | # return the spectrum
43 | spec = sess.return_spectrum(kT, tau, init_pop=kT_init)
44 | ax.plot(sess.ebins_out, numpy.append(0, spec), drawstyle='steps', label='HEG Ioniz')
45 |
46 | # same again, but for a recombining spectrum - set initial temperature > kT
47 | kT_init=10.0
48 | spec = sess.return_spectrum(kT, tau, init_pop=kT_init)
49 |
50 | # plot the results
51 | ax.plot(sess.ebins_out, numpy.append(0, spec), drawstyle='steps', label='HEG Recomb')
52 | ax.legend(loc=0)
53 | pylab.draw()
54 |
55 | zzz=input("Press enter to exit")
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_NEIsession_linelist_examples.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, numpy, pylab
2 |
3 |
4 | # declare the Non-Equilibrium Ionization session
5 | sess = pyatomdb.spectrum.NEISession()
6 |
7 | kT = 0.8 # temperature in keV
8 | tau = 1e11 # n_e*t cm^-3 s
9 | kT_init=0.01 # initial temperature (for initial ion distribution)
10 |
11 | waverange = [21,27]
12 |
13 | # find the lines in a certain wavelength range
14 | llist = sess.return_linelist(kT,tau, waverange)
15 |
16 | # filter out to get only lines within 10% of the strongest
17 | llist = llist[ llist['Epsilon'] > max(llist['Epsilon'])*0.1]
18 |
19 | # print the results:
20 |
21 | # column names
22 | print(llist.dtype.names)
23 |
24 | # data
25 | print(llist)
26 |
27 |
28 | # now let's see how one of the lines varies as a function of temperature. Let's look
29 | # at the O VII resonance line (7 -> 1)
30 |
31 | # list of temperatures to look at
32 | kTlist = numpy.linspace(0.05,3.0,20)
33 |
34 | # get the emissivity as a function of temperature (returned in a dict)
35 | ldata = sess.return_line_emissivity(kTlist, tau, 8, 7, 7, 1)
36 |
37 | # print out the data
38 | for i in range(len(kTlist)):
39 | print("%.3f keV %e ph cm^3 s^-1"%(ldata['Te'][i], ldata['epsilon'][i]))
40 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 |
6 | # declare the Collisional Ionization Equilibrium session
7 | sess = pyatomdb.spectrum.CIESession()
8 |
9 | # create a set of energy bins (in keV) for the response. Note these are
10 | # the n edges of the n-1 bins.
11 | ebins = numpy.linspace(0.6,12.4,1000)
12 |
13 | # set the response (raw keyword tells pyatomdb it is not a real response file)
14 | sess.set_response(ebins, raw=True)
15 |
16 | kT = 0.4 # temperature in keV
17 | spec = sess.return_spectrum(kT)
18 |
19 |
20 | # alternatively, could set to real RMF, ARF files using:
21 | # sess.set_response(rmf, arf=arf)
22 | # where rmf and arf are the file names
23 |
24 | # Turn on (or off) thermal broadening, and if desired velocity broadening
25 | # in this case turn on thermal broadening, and set velocity broadening to 500 km/s
26 |
27 | sess.set_broadening(True, velocity_broadening=500.0)
28 |
29 | # return spectrum at given temperature
30 | kT = 0.8 # temperature in keV
31 | spec = sess.return_spectrum(kT)
32 |
33 | # note returned spectrum has units of photons cm^5 s^-1 bin^-1, and has 1 less
34 | # value than the energy bin grid. Prepend a 0 to it for plotting purposes
35 | fig = pylab.figure()
36 | fig.show()
37 | ax = fig.add_subplot(111)
38 | ax.plot(sess.ebins_out, numpy.append(0, spec), drawstyle='steps', label='dummy response')
39 |
40 | #label the figure
41 | ax.set_xlabel('Energy (keV)')
42 | ax.set_ylabel('Intensity (ph cm$^3$ s$^{-1}$ bin$^{-1}$)')
43 |
44 | # now do the same thing but with an instrument response
45 | sess.set_response('../tests/testdata/aciss_heg1_cy19.grmf', \
46 | arf='../tests/testdata/aciss_heg1_cy19.garf')
47 |
48 | # return the spectrum
49 | spec = sess.return_spectrum(kT)
50 | ax.plot(sess.ebins_out, numpy.append(0, spec), drawstyle='steps', label='HEG')
51 |
52 | # change abundance set
53 | sess.set_abundset('Feldman')
54 | spec = sess.return_spectrum(kT)
55 | ax.plot(sess.ebins_out, numpy.append(0, spec), drawstyle='steps', label='HEG+Feldman')
56 | ax.legend(loc=0)
57 | pylab.draw()
58 |
59 | zzz=input("Press enter to exit")
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_1.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 |
6 | # declare the Collisional Ionization Equilibrium session
7 | sess = pyatomdb.spectrum.CIESession()
8 |
9 | # create a set of energy bins (in keV) for the response. Note these are
10 | # the n edges of the n-1 bins.
11 | ebins = numpy.linspace(0.3,1.0,10000)
12 |
13 | # set the response (raw keyword tells pyatomdb it is not a real response file)
14 | sess.set_response(ebins, raw=True)
15 |
16 | kT = 0.4 # temperature in keV
17 | spec = sess.return_spectrum(kT)
18 |
19 | # we now have a spectrum and the energy bins,
20 |
21 | # prepend a zero to the spectrum so that energy bins and spectrum have
22 | # the same length. If you use a different plotting system you may
23 | # need to add this to the end.
24 | spec = numpy.append(0, spec)
25 |
26 | # Returned spectrum has units of photons cm^5 s^-1 bin^-1
27 | fig = pylab.figure()
28 | fig.show()
29 | ax = fig.add_subplot(211)
30 | ax.plot(sess.ebins_out, spec, drawstyle='steps', label='dummy response')
31 |
32 | # label the figure
33 | ax.set_xlabel('Energy (keV)')
34 | ax.set_ylabel('Intensity (ph cm$^5$ s$^{-1}$ bin$^{-1}$)')
35 |
36 | # zoom in a bit
37 | #ax.set_xlim([0.8,0.85])
38 |
39 | # make plot appear
40 |
41 | # now repeat the process with a real response
42 | # set response
43 | sess.set_response('aciss_meg1_cy22.grmf', arf = 'aciss_meg1_cy22.garf')
44 |
45 | # get spectrum, prepend zero
46 | spec = sess.return_spectrum(kT)
47 | spec = numpy.append(0, spec)
48 |
49 | ax2 = fig.add_subplot(212)
50 | ax2.plot(sess.ebins_out, spec, drawstyle='steps', label='Chandra MEG')
51 |
52 | # add legends
53 | ax.legend(loc=0)
54 | ax2.legend(loc=0)
55 |
56 | # zoom in on small sections of the spectrum
57 | ax.set_xlim([0.7, 0.9])
58 | ax2.set_xlim([0.7, 0.9])
59 |
60 | # set axes
61 | ax2.set_xlabel('Energy (keV)')
62 | ax2.set_ylabel('Intensity (ph cm$^5$ s$^{-1}$ bin$^{-1}$)')
63 |
64 | # adjust plot spacing so labels are visible
65 | pylab.matplotlib.pyplot.subplots_adjust(hspace = 0.34)
66 |
67 | # draw graphs
68 | pylab.draw()
69 |
70 | zzz=input("Press enter to continue")
71 |
72 | # save image files
73 | fig.savefig('spectrum_session_examples_1_1.pdf')
74 | fig.savefig('spectrum_session_examples_1_1.svg')
75 |
76 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_1_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/spectrum_session_examples_1_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_1b.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 |
6 | # declare the Collisional Ionization Equilibrium session
7 | sess = pyatomdb.spectrum.CIESession()
8 |
9 |
10 | kT = 0.4 # temperature in keV
11 |
12 | # Returned spectrum has units of photons cm^5 s^-1 bin^-1
13 |
14 | # create figure
15 | gs = pylab.matplotlib.gridspec.GridSpec(2, 1, height_ratios=[2, 1])
16 | fig = pylab.figure()
17 | fig.show()
18 | ax1 = fig.add_subplot(gs[0]) # for data
19 | ax2 = fig.add_subplot(gs[1], sharex=ax1) # for ratio
20 |
21 | # label the figure
22 | ax2.set_xlabel('Energy (keV)')
23 | ax1.set_ylabel('Intensity (ph cm$^5$ s$^{-1}$ bin$^{-1}$)')
24 | ax2.set_ylabel('Ratio')
25 |
26 | # set response - using a regular matrix
27 | sess.set_response('aciss_meg1_cy22.grmf', arf = 'aciss_meg1_cy22.garf')
28 |
29 | # get spectrum, prepend zero
30 | spec = sess.return_spectrum(kT)
31 | spec = numpy.append(spec[0], spec)
32 |
33 | ax1.plot(sess.ebins_out, spec, drawstyle='steps', label='Regular')
34 |
35 | # change the response to a sparse one
36 | sess.set_response('aciss_meg1_cy22.grmf', arf = 'aciss_meg1_cy22.garf',
37 | sparse=True)
38 | spec_sparse = sess.return_spectrum(kT)
39 | spec_sparse = numpy.append(spec_sparse[0], spec_sparse)
40 |
41 | ax1.plot(sess.ebins_out, spec_sparse, '--', drawstyle='steps', label='Sparse')
42 |
43 | # plot the ratio
44 | ax2.plot(sess.ebins_out, spec/spec_sparse, drawstyle='steps',\
45 | label='Regular/Sparse')
46 |
47 | # add legend
48 | ax1.legend(loc=0)
49 | ax2.legend(loc=0)
50 |
51 | # zoom in on small sections of the spectrum
52 | ax1.set_xlim([0.5, 2.0])
53 |
54 | # adjust plot spacing so labels are visible
55 | pylab.matplotlib.pyplot.subplots_adjust(hspace = 0)
56 |
57 | # draw graphs
58 | pylab.draw()
59 |
60 | zzz=input("Press enter to continue")
61 |
62 | # save image files
63 | fig.savefig('spectrum_session_examples_1b_1.pdf')
64 | fig.savefig('spectrum_session_examples_1b_1.svg')
65 |
66 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_1b_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/spectrum_session_examples_1b_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_2.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 |
6 | # declare the Collisional Ionization Equilibrium session
7 | sess = pyatomdb.spectrum.CIESession()
8 |
9 | # create a set of energy bins (in keV) for the response. Note these are
10 | # the n edges of the n-1 bins.
11 | ebins = numpy.linspace(1.0,1.2,501)
12 |
13 | # set the response (raw keyword tells pyatomdb it is not a real response file)
14 | sess.set_response(ebins, raw=True)
15 |
16 | kT = 4.0 # temperature in keV
17 | vel = 400.0 # velocity to broaden with when using velocity broadening (km/s)
18 |
19 | spec = sess.return_spectrum(kT)
20 |
21 | # we now have a spectrum and the energy bins,
22 |
23 | # prepend a zero to the spectrum so that energy bins and spectrum have
24 | # the same length. If you use a different plotting system you may
25 | # need to add this to the end.
26 | spec = numpy.append(0, spec)
27 |
28 | # Returned spectrum has units of photons cm^5 s^-1 bin^-1
29 | fig = pylab.figure()
30 | fig.show()
31 | ax = fig.add_subplot(211)
32 | ax.plot(sess.ebins_out, spec, drawstyle='steps', label='dummy response')
33 |
34 | # label the figure
35 | ax.set_xlabel('Energy (keV)')
36 | ax.set_ylabel('Intensity (ph cm$^5$ s$^{-1}$ bin$^{-1}$)')
37 |
38 |
39 |
40 | sess.set_broadening(True)
41 | spec = sess.return_spectrum(kT)
42 | spec = numpy.append(0, spec)
43 | ax.plot(sess.ebins_out, spec, drawstyle='steps', label='thermal')
44 |
45 | sess.set_broadening(True, velocity_broadening=vel)
46 | spec = sess.return_spectrum(kT)
47 | spec = numpy.append(0, spec)
48 | ax.plot(sess.ebins_out, spec, drawstyle='steps', label='%.0f km/s'%(vel))
49 |
50 | # make plot appear
51 |
52 | # now repeat the process with a real response
53 |
54 | # reset broadening to off.
55 | sess.set_broadening(False)
56 |
57 | # set response
58 | sess.set_response('aciss_meg1_cy22.grmf', arf = 'aciss_meg1_cy22.garf')
59 |
60 | # get spectrum, prepend zero
61 | spec = sess.return_spectrum(kT)
62 | spec = numpy.append(0, spec)
63 |
64 | ax2 = fig.add_subplot(212)
65 | ax2.plot(sess.ebins_out, spec, drawstyle='steps', label='Chandra MEG')
66 |
67 | # add legends
68 | ax.legend(loc=0)
69 | ax2.legend(loc=0)
70 |
71 | # zoom in on small sections of the spectrum
72 | ax.set_xlim([1.150, 1.180])
73 | ax2.set_xlim([1.150, 1.180])
74 |
75 | # set axes
76 | ax2.set_xlabel('Energy (keV)')
77 | ax2.set_ylabel('Intensity (ph cm$^5$ s$^{-1}$ bin$^{-1}$)')
78 |
79 | sess.set_broadening(True)
80 | spec = sess.return_spectrum(kT)
81 | spec = numpy.append(0, spec)
82 | ax2.plot(sess.ebins_out, spec, drawstyle='steps', label='thermal')
83 |
84 | sess.set_broadening(True, velocity_broadening=vel)
85 | spec = sess.return_spectrum(kT)
86 | spec = numpy.append(0, spec)
87 | ax2.plot(sess.ebins_out, spec, drawstyle='steps', label='%.0f km/s'%(vel))
88 |
89 |
90 | # adjust plot spacing so labels are visible
91 | pylab.matplotlib.pyplot.subplots_adjust(hspace = 0.34)
92 |
93 | # draw graphs
94 | pylab.draw()
95 |
96 | zzz=input("Press enter to continue")
97 |
98 | # save image files
99 | fig.savefig('spectrum_session_examples_2_1.pdf')
100 | fig.savefig('spectrum_session_examples_2_1.svg')
101 |
102 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_2_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/spectrum_session_examples_2_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_2b.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 | # line broadening of weak features
6 |
7 | # declare an CIESession
8 |
9 | sess = pyatomdb.spectrum.CIESession()
10 |
11 | # create a set of energy bins (in keV) for the response. Note these are
12 | # the n edges of the n-1 bins.
13 | ebins = numpy.linspace(6.9,7.0,501)
14 |
15 | # set the response (raw keyword tells pyatomdb it is not a real response file)
16 | sess.set_response(ebins, raw=True)
17 |
18 | kT = 10.0 # temperature in keV
19 | vel = 400.0 # velocity to broaden with when using velocity broadening (km/s)
20 |
21 | spec = sess.return_spectrum(kT)
22 |
23 | # we now have a spectrum and the energy bins,
24 |
25 | # prepend a zero to the spectrum so that energy bins and spectrum have
26 | # the same length. If you use a different plotting system you may
27 | # need to add this to the end.
28 | spec = numpy.append(0, spec)
29 |
30 | # Returned spectrum has units of photons cm^5 s^-1 bin^-1
31 | fig = pylab.figure()
32 | fig.show()
33 | ax = fig.add_subplot(111)
34 | ax.plot(sess.ebins_out, spec, drawstyle='steps', label='dummy response')
35 |
36 | # label the figure
37 | ax.set_xlabel('Energy (keV)')
38 | ax.set_ylabel('Intensity (ph cm$^5$ s$^{-1}$ bin$^{-1}$)')
39 | ax.set_yscale('log')
40 |
41 |
42 | sess.set_broadening(True, velocity_broadening=vel)
43 | spec = sess.return_spectrum(kT)
44 | spec = numpy.append(0, spec)
45 | ax.plot(sess.ebins_out, spec, drawstyle='steps', label='%.0f km/s'%(vel))
46 |
47 | # Some features from weak lines aren't broadened. Let's fix that
48 | # by setting the minimum emissivity limit to a lower value
49 | # (default is 1e-18 ph cm^3 s^-1)
50 |
51 | sess.set_broadening(True, velocity_broadening=vel, broaden_limit=1e-30)
52 | spec = sess.return_spectrum(kT)
53 | spec = numpy.append(0, spec)
54 | ax.plot(sess.ebins_out, spec, drawstyle='steps', label='Low Limit, %.0f km/s'%(vel))
55 |
56 | # make plot appear
57 |
58 | # now repeat the process with a real response
59 | # add legends
60 | ax.legend(loc=0)
61 |
62 | # zoom in on small sections of the spectrum
63 | #ax.set_xlim([1.150, 1.180])
64 |
65 | # draw graphs
66 | pylab.draw()
67 |
68 | zzz=input("Press enter to continue")
69 |
70 | # save image files
71 | fig.savefig('spectrum_session_examples_2b_1.pdf')
72 | fig.savefig('spectrum_session_examples_2b_1.svg')
73 |
74 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_2b_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/spectrum_session_examples_2b_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_3_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/spectrum_session_examples_3_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_3_abund.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 |
6 | # declare the Collisional Ionization Equilibrium session
7 | sess = pyatomdb.spectrum.CIESession()
8 |
9 | # set response
10 | sess.set_response('aciss_meg1_cy22.grmf', arf = 'aciss_meg1_cy22.garf')
11 |
12 | # for plotting
13 | fig = pylab.figure()
14 | fig.show()
15 | ax = fig.add_subplot(111)
16 |
17 | # make a spectrum at 1keV
18 | s1 = sess.return_spectrum(1.0)
19 |
20 | # change the abundance of Iron
21 | sess.set_abund(26,2.0)
22 | s2 = sess.return_spectrum(1.0)
23 | # change the abundance of Magnesium and Silicon
24 | sess.set_abund([12,14],0.5)
25 | s3 = sess.return_spectrum(1.0)
26 | # change the abundance of Neon and Iron separately
27 | sess.set_abund([10,26],[2.0,0.5])
28 | s4 = sess.return_spectrum(1.0)
29 | # plot all this
30 | offset = max(s1)
31 | ax.plot(sess.ebins_out, numpy.append(0,s1), drawstyle='steps', label='Original')
32 | ax.plot(sess.ebins_out, numpy.append(0,s2)+offset, drawstyle='steps', label='Fex2')
33 | ax.plot(sess.ebins_out, numpy.append(0,s3)+offset*2, drawstyle='steps', label='Mg, Six0.5')
34 | ax.plot(sess.ebins_out, numpy.append(0,s4)+offset*3, drawstyle='steps', label='Nex2, Fex0.5')
35 | ax.legend(ncol=4, loc=0)
36 | ax.set_xlim([0.8,1.5])
37 | ax.set_xlabel('Energy (keV)')
38 | ax.set_ylabel('Intensity (ph cm$^5$ s$^{-1}$ bin$^{-1}$)')
39 | pylab.draw()
40 | zzz=input("Press enter to continue")
41 | # save image files
42 | fig.savefig('spectrum_session_examples_3_1.pdf')
43 | fig.savefig('spectrum_session_examples_3_1.svg')
44 |
45 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_4_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/spectrum_session_examples_4_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_4_abund.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 |
6 | # declare the Collisional Ionization Equilibrium session
7 | sess = pyatomdb.spectrum.CIESession()
8 |
9 | # set response
10 | sess.set_response('aciss_meg1_cy22.grmf', arf = 'aciss_meg1_cy22.garf')
11 |
12 | # for plotting
13 | fig = pylab.figure()
14 | fig.show()
15 | ax = fig.add_subplot(111)
16 |
17 | # get a list of the available abundance sets
18 | sess.set_abundset()
19 | # this prints them to screen.
20 |
21 |
22 |
23 | for iabset, abset in enumerate(['Allen', 'AG89', 'GA88', 'Feldman', 'GA10', 'Lodd09']):
24 |
25 | # set abundset
26 | sess.set_abundset(abset)
27 |
28 | # get spectrum at 1keV
29 | s1 = sess.return_spectrum(1.0)
30 | if iabset == 0:
31 | baseoffset = max(s1)
32 |
33 | offset = iabset*baseoffset
34 |
35 |
36 | #plot
37 | ax.plot(sess.ebins_out, numpy.append(0,s1)+offset, drawstyle='steps', label=abset)
38 |
39 | ax.set_xlim([0.8,2.1])
40 |
41 | ax.set_xlabel('Energy (keV)')
42 | ax.set_ylabel('Intensity (ph cm$^5$ s$^{-1}$ bin$^{-1}$)')
43 | ax.legend(loc=0, ncol=4)
44 | pylab.draw()
45 | zzz=input("Press enter to continue")
46 | # save image files
47 | fig.savefig('spectrum_session_examples_4_1.pdf')
48 | fig.savefig('spectrum_session_examples_4_1.svg')
49 |
50 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_5_linelist.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 |
6 | # declare the Collisional Ionization Equilibrium session
7 | sess = pyatomdb.spectrum.CIESession()
8 |
9 | # set response
10 | sess.set_response('aciss_meg1_cy22.grmf', arf = 'aciss_meg1_cy22.garf')
11 |
12 | # get a linelist between 1.85 and 1.88 Angstroms for a kT=4keV plasma
13 |
14 | llist = sess.return_linelist(4.0,[1.85,1.88])
15 |
16 | # select only the strongest 10 lines
17 | llist.sort(order='Epsilon')
18 | llist = llist[-10:]
19 |
20 | # show the column names
21 | print(llist.dtype.names)
22 |
23 | # expected output:
24 | # ('Lambda', 'Lambda_Err', 'Epsilon', 'Epsilon_Err', 'Element', 'Ion', 'UpperLev', 'LowerLev')
25 |
26 | # print the data
27 | print(llist)
28 |
29 | # expected output:
30 | #[(1.8635 , nan, 8.8202775e-19, nan, 26, 24, 47, 1)
31 | # (1.8532 , nan, 1.0113579e-18, nan, 26, 24, 10089, 6)
32 | # (1.8622 , nan, 1.0681659e-18, nan, 26, 24, 10242, 3)
33 | # (1.863 , nan, 2.5785468e-18, nan, 26, 24, 10247, 2)
34 | # (1.8611 , nan, 2.8751725e-18, nan, 26, 24, 48, 1)
35 | # (1.8659 , nan, 3.8414809e-18, nan, 26, 24, 10248, 3)
36 | # (1.8554125, nan, 7.2097873e-18, nan, 26, 25, 6, 1)
37 | # (1.8595169, nan, 7.7184372e-18, nan, 26, 25, 5, 1)
38 | # (1.8681941, nan, 1.2001933e-17, nan, 26, 25, 2, 1)
39 | # (1.8503995, nan, 3.5732330e-17, nan, 26, 25, 7, 1)]
40 |
41 | # we can then do the same thing, but including the effective area of the instrument.
42 | # So the Epsilon columnw will be multiplied by the effective area at the line's energy
43 | llist = sess.return_linelist(4.0,[1.85,1.88], apply_aeff=True)
44 |
45 | llist.sort(order='Epsilon')
46 | llist = llist[-10:]
47 |
48 | print('After apply effective area:')
49 | print(llist)
50 | #[(1.8635 , nan, 1.6238816e-18, nan, 26, 24, 47, 1)
51 | # (1.8532 , nan, 1.7191134e-18, nan, 26, 24, 10089, 6)
52 | # (1.8622 , nan, 1.9665764e-18, nan, 26, 24, 10242, 3)
53 | # (1.863 , nan, 4.7473049e-18, nan, 26, 24, 10247, 2)
54 | # (1.8611 , nan, 5.2934158e-18, nan, 26, 24, 48, 1)
55 | # (1.8659 , nan, 7.3193854e-18, nan, 26, 24, 10248, 3)
56 | # (1.8554125, nan, 1.2779108e-17, nan, 26, 25, 6, 1)
57 | # (1.8595169, nan, 1.3680673e-17, nan, 26, 25, 5, 1)
58 | # (1.8681941, nan, 2.2867946e-17, nan, 26, 25, 2, 1)
59 | # (1.8503995, nan, 6.0738072e-17, nan, 26, 25, 7, 1)]
60 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_6_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/spectrum_session_examples_6_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_6_line_emissivity.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 |
6 | # declare the Collisional Ionization Equilibrium session
7 | sess = pyatomdb.spectrum.CIESession()
8 |
9 | # set response
10 | sess.set_response('aciss_meg1_cy22.grmf', arf = 'aciss_meg1_cy22.garf')
11 |
12 | # get the emissivity of the resonance line of O VII at 5 different temperatures
13 |
14 | kTlist = numpy.array([0.1,0.3,0.5,0.7,0.9])
15 | Z=8
16 | z1=7
17 | up=7
18 | lo = 1
19 | ldata = sess.return_line_emissivity(kTlist, Z, z1, up, lo)
20 |
21 | fig = pylab.figure()
22 | fig.show()
23 | ax= fig.add_subplot(111)
24 |
25 | ax.semilogy(ldata['Te'], ldata['epsilon'])
26 |
27 | ax.set_xlabel("Temperature (keV)")
28 | ax.set_ylabel("Epsilon ph cm$^3$ s$^{-1}$")
29 |
30 | pylab.draw()
31 | zzz=input("Press enter to continue")
32 | # save image files
33 | fig.savefig('spectrum_session_examples_6_1.pdf')
34 | fig.savefig('spectrum_session_examples_6_1.svg')
35 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_7_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/examples/spectrum_session_examples_7_1.pdf
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_7_nei.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 |
6 | # declare the Non-Equilibrium Ionization session. I am only using
7 | # oxygen and neon for simplicity
8 | sess = pyatomdb.spectrum.NEISession(elements=[8,10])
9 |
10 | # set the response (raw keyword tells pyatomdb it is not a real response file)
11 | sess.set_response('aciss_meg1_cy22.grmf', arf = 'aciss_meg1_cy22.garf')
12 |
13 | kT = 0.4 # temperature in keV
14 | tau = 1e10 # n_e * t in cm^-3 s
15 | spec = sess.return_spectrum(kT, tau, init_pop=1.0)
16 |
17 | # Returned spectrum has units of photons cm^5 s^-1 bin^-1
18 | fig = pylab.figure()
19 | fig.show()
20 | ax = fig.add_subplot(111)
21 |
22 | offset = max(spec)
23 | ax.plot(sess.ebins_out, numpy.append(0,spec), drawstyle='steps', label='mild recombining')
24 |
25 |
26 | spec = sess.return_spectrum(kT, tau, init_pop='ionizing')
27 | ax.plot(sess.ebins_out, offset+numpy.append(0,spec), drawstyle='steps', label='ionizing')
28 |
29 | spec = sess.return_spectrum(kT, tau, init_pop='recombining')
30 | ax.plot(sess.ebins_out, 2*offset+numpy.append(0,spec), drawstyle='steps', label='recombining')
31 |
32 |
33 |
34 | # manually specified initial population
35 | init_pop_dict = {}
36 | init_pop_dict[8] = numpy.zeros(9) # 9 stages of oxygen (include neutral an fully stripped)
37 | init_pop_dict[10] = numpy.zeros(11)
38 | #put everything in the H-like stage
39 | init_pop_dict[8][8] = 1.0
40 | init_pop_dict[10][10] = 1.0
41 |
42 |
43 | spec = sess.return_spectrum(kT, tau, init_pop=init_pop_dict)
44 | ax.plot(sess.ebins_out, 3*offset+numpy.append(0,spec), drawstyle='steps', label='all H-like')
45 |
46 |
47 | # label the figure
48 | ax.set_xlabel('Energy (keV)')
49 | ax.set_ylabel('Intensity (ph cm$^5$ s$^{-1}$ bin$^{-1}$)')
50 |
51 | # zoom in a bit
52 | ax.set_xlim([0.6,1.2])
53 | ax.legend(loc=0)
54 | # make plot appear
55 | pylab.draw()
56 |
57 | zzz=input("Press enter to continue")
58 |
59 | # save image files
60 | fig.savefig('spectrum_session_examples_7_1.pdf')
61 | fig.savefig('spectrum_session_examples_7_1.svg')
62 |
63 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_examples_8_nei_linelist.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 | import numpy
3 | import pylab
4 |
5 |
6 | # declare the Non-Equilibrium Ionization session. I am only using
7 | # oxygen and neon for simplicity
8 | sess = pyatomdb.spectrum.NEISession()
9 |
10 | # set the response (raw keyword tells pyatomdb it is not a real response file)
11 | sess.set_response('aciss_meg1_cy22.grmf', arf = 'aciss_meg1_cy22.garf')
12 |
13 | kT = 4.0 # temperature in keV
14 | tau = 1e11 # n_e * t in cm^-3 s
15 | llist = sess.return_linelist(kT, tau, [1.7,1.9],init_pop=1.0)
16 |
17 | # filter lines to strongest 20
18 | llist.sort(order='Epsilon')
19 | llist= llist[-20:]
20 |
21 | print("strongest 20 lines")
22 | print(llist.dtype.names)
23 | print(llist)
24 |
25 | llist = sess.return_linelist(kT, tau, [1.7,1.9],by_ion_drv=True,init_pop=1.0)
26 |
27 | # filter lines to strongest 20
28 | llist.sort(order='Epsilon')
29 | llist= llist[-20:]
30 |
31 | print("Strongest 20 lines, separated by driving ion")
32 | print(llist.dtype.names)
33 | print(llist)
34 |
35 |
36 | # Expected output
37 | # strongest 20 lines
38 | # ('Lambda', 'Lambda_Err', 'Epsilon', 'Epsilon_Err', 'Element', 'Ion', 'UpperLev', 'LowerLev')
39 | # [(1.8827 , nan, 4.3892664e-19, nan, 26, 22, 20009, 1)
40 | # (1.8622 , nan, 4.5014698e-19, nan, 26, 24, 10242, 3)
41 | # (1.8824 , nan, 4.8421002e-19, nan, 26, 22, 483, 1)
42 | # (1.8825 , nan, 5.8088691e-19, nan, 26, 22, 482, 1)
43 | # (1.8851 , nan, 5.9669826e-19, nan, 26, 22, 20008, 2)
44 | # (1.8747 , nan, 6.6686722e-19, nan, 26, 24, 44, 1)
45 | # (1.8737 , nan, 6.9597891e-19, nan, 26, 23, 20126, 3)
46 | # (1.863 , nan, 1.0866564e-18, nan, 26, 24, 10247, 2)
47 | # (1.8756001, nan, 1.0874650e-18, nan, 26, 23, 20122, 4)
48 | # (1.8706 , nan, 1.3853237e-18, nan, 26, 24, 46, 1)
49 | # (1.8738 , nan, 1.4878691e-18, nan, 26, 24, 45, 1)
50 | # (1.8659 , nan, 1.6188786e-18, nan, 26, 24, 10248, 3)
51 | # (1.857 , nan, 1.9076071e-18, nan, 26, 24, 50, 1)
52 | # (1.8554125, nan, 2.3919818e-18, nan, 26, 25, 6, 1)
53 | # (1.8595169, nan, 2.8080335e-18, nan, 26, 25, 5, 1)
54 | # (1.8635 , nan, 3.6176967e-18, nan, 26, 24, 47, 1)
55 | # (1.8704 , nan, 7.2666667e-18, nan, 26, 23, 309, 1)
56 | # (1.8681941, nan, 8.8379641e-18, nan, 26, 25, 2, 1)
57 | # (1.8611 , nan, 1.1892281e-17, nan, 26, 24, 48, 1)
58 | # (1.8503995, nan, 1.4463351e-17, nan, 26, 25, 7, 1)]
59 | # Strongest 20 lines, separated by driving ion
60 | # ('Lambda', 'Lambda_Err', 'Epsilon', 'Epsilon_Err', 'Element', 'Elem_drv', 'Ion', 'Ion_drv', 'UpperLev', 'LowerLev')
61 | # [(1.8622 , nan, 4.5014698e-19, nan, 26, 26, 24, 25, 10242, 3)
62 | # (1.8824 , nan, 4.8421002e-19, nan, 26, 26, 22, 22, 483, 1)
63 | # (1.8825 , nan, 5.6233666e-19, nan, 26, 26, 22, 22, 482, 1)
64 | # (1.8851 , nan, 5.9669826e-19, nan, 26, 26, 22, 23, 20008, 2)
65 | # (1.8747 , nan, 6.5364458e-19, nan, 26, 26, 24, 24, 44, 1)
66 | # (1.8737 , nan, 6.9597891e-19, nan, 26, 26, 23, 24, 20126, 3)
67 | # (1.863 , nan, 1.0866564e-18, nan, 26, 26, 24, 25, 10247, 2)
68 | # (1.8756001, nan, 1.0874650e-18, nan, 26, 26, 23, 24, 20122, 4)
69 | # (1.8706 , nan, 1.3512313e-18, nan, 26, 26, 24, 24, 46, 1)
70 | # (1.8738 , nan, 1.4619381e-18, nan, 26, 26, 24, 24, 45, 1)
71 | # (1.8659 , nan, 1.6188786e-18, nan, 26, 26, 24, 25, 10248, 3)
72 | # (1.857 , nan, 1.8978882e-18, nan, 26, 26, 24, 24, 50, 1)
73 | # (1.8554125, nan, 2.3303760e-18, nan, 26, 26, 25, 25, 6, 1)
74 | # (1.8595169, nan, 2.7651213e-18, nan, 26, 26, 25, 25, 5, 1)
75 | # (1.8681941, nan, 3.3107048e-18, nan, 26, 26, 25, 25, 2, 1)
76 | # (1.8635 , nan, 3.6059715e-18, nan, 26, 26, 24, 24, 47, 1)
77 | # (1.8681941, nan, 5.3853784e-18, nan, 26, 26, 25, 24, 2, 1)
78 | # (1.8704 , nan, 7.2068723e-18, nan, 26, 26, 23, 23, 309, 1)
79 | # (1.8611 , nan, 1.1865456e-17, nan, 26, 26, 24, 24, 48, 1)
80 | # (1.8503995, nan, 1.4405425e-17, nan, 26, 26, 25, 25, 7, 1)]
81 | #
82 |
--------------------------------------------------------------------------------
/pyatomdb/examples/spectrum_session_linelist_examples.py:
--------------------------------------------------------------------------------
1 | import pyatomdb, numpy, pylab
2 |
3 |
4 | # declare the Collisional Ionization Equilibrium session
5 | sess = pyatomdb.spectrum.CIESession()
6 |
7 | kT = 0.8 # temperature in keV
8 |
9 | waverange = [21,27]
10 |
11 | # find the lines in a certain wavelength range
12 | llist = sess.return_linelist(kT, waverange)
13 |
14 | # filter out to get only lines within 10% of the strongest
15 | llist = llist[ llist['Epsilon'] > max(llist['Epsilon'])*0.1]
16 |
17 | # print the results:
18 |
19 | # column names
20 | print(llist.dtype.names)
21 |
22 | # data
23 | print(llist)
24 |
25 |
26 | # now let's see how one of the lines varies as a function of temperature. Let's look
27 | # at the O VII resonance line (7 -> 1)
28 |
29 | # list of temperatures to look at
30 | kTlist = numpy.linspace(0.05,3.0,20)
31 |
32 | # get the emissivity as a function of temperature (returned in a dict)
33 | ldata = sess.return_line_emissivity(kTlist, 8, 7, 7, 1)
34 |
35 | # print out the data
36 | for i in range(len(kTlist)):
37 | print("%.3f keV %e ph cm^3 s^-1"%(ldata['Te'][i], ldata['epsilon'][i]))
38 |
--------------------------------------------------------------------------------
/pyatomdb/examples/wrapper_xspec_examples.py:
--------------------------------------------------------------------------------
1 | # temporarily add the wrappers folder to the path
2 | import sys
3 | sys.path.append('../wrappers')
4 |
5 |
6 | from apec_xspec import *
7 |
8 | # declare a new model
9 | # inital import creates pyapec, pyvapec, pyvvapec, analagous to apec, vapec, vvapec
10 |
11 | m1 = xspec.Model('pyapec')
12 |
13 | m1.show()
14 |
15 | m1.pyapec.kT=5.0
16 |
17 |
18 | # let's plot a spectrum
19 | xspec.Plot.device='/xs'
20 |
21 | xspec.Plot('model')
22 |
23 | # you can fiddle with some aspects of the model directly
24 | cie.set_eebrems(False) # turn off electron-electron bremsstrahlung
25 |
26 | xspec.Plot('model')
27 |
28 | # it is also possible to go in and change broadening, etc. The interface can be
29 | # adjust quite easily by looking at apec_xspec.py to add extra parameters
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/pyatomdb/linear_approx.c:
--------------------------------------------------------------------------------
1 | /* Original: stl2.f -- translated by f2c (version 19970219). */
2 | #include
3 | #include
4 | #include
5 |
6 | void linear_approx(double *x, double *y, double *e, int *m, double *u,
7 | double *v, double *w, int *k, int *ip) {
8 |
9 | /* System generated locals */
10 | int i__1;
11 | double r__1, r__2;
12 |
13 | /* Local variables */
14 | int indc, keep, itch, init;
15 | double smin;
16 | int ipiv;
17 | double smax, xeye, yeye, test, svmn=0, svmx=0, temp1, temp2;
18 | int i__, j, l, n, idiot;
19 | double epsln, slope=0, xinit, yinit;
20 | int kp=0;
21 | double dx;
22 | int it, igraze;
23 | double sgn, svx=0, svy=0;
24 |
25 | /* From D.G. Wilson, 1976, ACM Transactions on Mathematical Software,2,388 */
26 |
27 | /* Piecewise linear approximations of fewest line segments within
28 | given tolerances. x, y, e and m contain input data. u,v,k and
29 | possibly w contain output. ip is a parameter determining the
30 | operation of the program. x and y are input data arrays of m
31 | elements x(i),y(i) contains the ith data point. e may be a
32 | single tolerance or a table of tolerances depending on the value
33 | of ip. If e is an array, then e(i) is the tolerance associated
34 | with x(i),y(i) and e must contain m nonnegative elements. u and
35 | v are output arrays of k+1 elements. u is a partition of the
36 | interval (x(1),x(n)) with u(1)=x(1) and u(k+1)=x(n). v(i) is an
37 | ordinate to be associated with u(i) in the approximation. (If a
38 | continuous approximation is requested, then v(i) is 'the'
39 | ordinate to be associated with u(i).) If a continuous
40 | approximation is requested, then w is not used. In this case the
41 | ith approximating segment is the straight line from u(i),v(i) to
42 | u(i+1),v(i+1). If a continuous approximation is not requested,
43 | then w is a k-element output array. In this case the ith
44 | approximating segment is the straight line from u(i),w(i) to
45 | u(i+1),v(i+1), and v(1) is set equal to w(1). k is the number of
46 | segments in the piece- wise linear approximation generated. In
47 | case of an error return, k will be set to zero.
48 |
49 | The control parameter ip is the product of three indicators i1,i2
50 | and i3. i1 indicates whether or not e is an array of tolerances.
51 | i1 = -1 indicates e is an array i1 = +1 indicates e is a single
52 | number.
53 |
54 | i2 indicates whether or not the approximation is to be restricted to
55 | the 'tolerance band' about the data.
56 | i2 = 1 indicates no band restriction
57 | i2 = 2 indicates apply this restriction
58 | (the 'tolerance band' is a piecewise linear band centered at the
59 | data whose width is determined by the tolerances at the data
60 | points.)
61 |
62 | i3 indicates whether or not the approximation must be continuous.
63 | i3 = 1 indicates continuity not required
64 | i3 = 3 indicates continuity is required
65 |
66 | call stl2 (x,y,e,m,x,y,e,m,ip) will not cause problems provided
67 | that either a continuous approximation is equested, or e is a
68 | sufficiently large array.
69 |
70 | The program performs the following data checks. Are the x-values
71 | in increasing order? Are the tolerance(s) nonnegative? Is the
72 | number of data points greater than one? If any check fails, the
73 | program returns with k set equal to 0. In this case no further
74 | processing is attempted. */
75 |
76 | /* Parameter adjustments */
77 | --w;
78 | --v;
79 | --u;
80 | --e;
81 | --y;
82 | --x;
83 |
84 | /* Function Body */
85 | n = *m;
86 | itch = *ip;
87 | j = 1;
88 | /* ERROR CHECKS */
89 | if (n <= 1) {
90 | printf("linear_approx: n (%d) is <= 1\n",n);
91 | goto L400;
92 | }
93 | if (e[1] < (double)0.) {
94 | printf("linear_approx: tolerance[0] (%e) is < 0\n",e[1]);
95 | goto L400;
96 | }
97 | i__1 = n;
98 | for (l = 2; l <= i__1; ++l) {
99 | if (x[l - 1] >= x[l]) {
100 | printf("linear_approx: x[%d] (%e) > x[%d] (%e)\n",l-2,x[l-1],
101 | l-1,x[l]);
102 | goto L400;
103 | }
104 | if (itch >= 0) {
105 | goto L10;
106 | }
107 | if (e[l] < (double)0.) {
108 | printf("linear_approx: tolerance[%d] (%e) is < 0 for (%e)\n",
109 | l-1,e[l],y[l]);
110 | goto L400;
111 | }
112 | L10:
113 | ;
114 | }
115 | /* INITIALIZATION FOR ENTIRE PROGRAM */
116 | epsln = e[1];
117 | sgn = (double)1.;
118 | keep = 1;
119 | i__ = 1;
120 | u[1] = x[1];
121 | j = 2;
122 | init = 1;
123 | indc = 0;
124 | goto L30;
125 | /* INITIALIZATION FOR EACH SEGMENT */
126 | L20:
127 | ++j;
128 | init = i__;
129 | indc = 0;
130 | if (abs(itch) < 3) {
131 | keep = i__;
132 | }
133 | if ((i__1 = abs(itch) - 4, abs(i__1)) != 2) {
134 | goto L30;
135 | }
136 | /* RESTRICTED TO TOLERANCE BAND */
137 | xeye = u[j - 1];
138 | yeye = v[j - 1];
139 | temp1 = epsln;
140 | if (itch < 0) {
141 | temp1 += (sgn * e[i__ - 1] - epsln) * (x[i__] - u[j - 1]) / (x[i__] -
142 | x[i__ - 1]);
143 | }
144 | yinit = yeye - temp1 - temp1;
145 | goto L40;
146 | L30:
147 | /* NOT RESTRICTED TO TOLERANCE BAND */
148 | xeye = x[i__];
149 | yeye = y[i__] + epsln;
150 | yinit = y[i__] - epsln;
151 | if (abs(itch) == 1 || i__ == 1) {
152 | goto L40;
153 | }
154 | temp1 = epsln;
155 | if (itch < 0) {
156 | temp1 = sgn * e[i__ + 1];
157 | }
158 | smin = (y[i__ + 1] - yeye - temp1) / (x[i__ + 1] - xeye);
159 | if (itch < 0) {
160 | temp1 = sgn * e[i__ - 1];
161 | }
162 | smax = (yeye - y[i__ - 1] + temp1) / (xeye - x[i__ - 1]);
163 | if (keep == i__ - 1) {
164 | goto L50;
165 | }
166 | it = i__ - 2;
167 | xinit = xeye;
168 | ipiv = i__;
169 | igraze = i__;
170 | ++i__;
171 | goto L150;
172 | L40:
173 | if (xeye >= x[i__]) {
174 | ++i__;
175 | }
176 | if (itch < 0) {
177 | epsln = sgn * e[i__];
178 | }
179 | dx = x[i__] - xeye;
180 | smax = (y[i__] + epsln - yeye) / dx;
181 | smin = (y[i__] - epsln - yeye) / dx;
182 | L50:
183 | xinit = xeye;
184 | ipiv = i__;
185 | igraze = i__;
186 | /* DETERMINATION OF INDIVIDUAL SEGMENT */
187 | L60:
188 | if (i__ == n) {
189 | goto L260;
190 | }
191 | ++i__;
192 | L70:
193 | /* TEST FOR NEW *MAX* SLOPE */
194 | dx = x[i__] - xeye;
195 | if (itch < 0) {
196 | epsln = sgn * e[i__];
197 | }
198 | temp1 = (y[i__] + epsln - yeye) / dx;
199 | test = temp1 - smax;
200 | if (sgn <= (double)0.) {
201 | test = -test;
202 | }
203 | if (test < (double)0.) {
204 | goto L80;
205 | } else if (test == 0) {
206 | goto L90;
207 | } else {
208 | goto L100;
209 | }
210 | L80:
211 | /* TEST FOR END OF CANDIDATE SEGMENT */
212 | test = temp1 - smin;
213 | if (sgn <= (double)0.) {
214 | test = -test;
215 | }
216 | if (test < (double)0.) {
217 | goto L210;
218 | }
219 | smax = temp1;
220 | L90:
221 | /* TEST FOR NEW *MIN* SLOPE */
222 | ipiv = i__;
223 | L100:
224 | temp2 = (y[i__] - epsln - yeye) / dx;
225 | test = temp2 - smax;
226 | if (sgn <= (double)0.) {
227 | test = -test;
228 | }
229 | if (test < (double)0.) {
230 | goto L110;
231 | } else if (test == 0) {
232 | goto L120;
233 | } else {
234 | goto L140;
235 | }
236 | L110:
237 | test = smin - temp2;
238 | if (sgn <= (double)0.) {
239 | test = -test;
240 | }
241 | if (test < (double)0.) {
242 | goto L120;
243 | } else if (test == 0) {
244 | goto L130;
245 | } else {
246 | goto L60;
247 | }
248 | L120:
249 | smin = temp2;
250 | L130:
251 | igraze = i__;
252 | goto L60;
253 | /* CHECK FOR PIVOT AT NEW EYE POINT */
254 | L140:
255 | if (xeye == x[ipiv]) {
256 | goto L220;
257 | }
258 | if (itch < 0) {
259 | epsln = sgn * e[ipiv];
260 | }
261 | indc = 1;
262 | svx = xeye;
263 | svy = yeye;
264 | svmn = smin;
265 | svmx = smax;
266 | xeye = x[ipiv];
267 | yeye = y[ipiv] + epsln;
268 | smin = smax;
269 | smax = (yinit - yeye) / (xinit - xeye);
270 | if (keep >= ipiv) {
271 | goto L170;
272 | }
273 | it = ipiv - 1;
274 | L150:
275 | temp2 = yeye + epsln;
276 | i__1 = it;
277 | for (l = keep; l <= i__1; ++l) {
278 | if (itch < 0) {
279 | temp2 = yeye + sgn * e[l];
280 | }
281 | temp1 = (y[l] - temp2) / (x[l] - xeye);
282 | test = temp1 - smax;
283 | if (sgn <= (double)0.) {
284 | test = -test;
285 | }
286 | if (test < (double)0.) {
287 | smax = temp1;
288 | }
289 | /* L160: */
290 | }
291 | L170:
292 | if (ipiv >= i__ - 1) {
293 | goto L70;
294 | }
295 | it = i__ - 2;
296 | temp2 = yeye - epsln;
297 | idiot = ipiv;
298 | i__1 = it;
299 | for (l = idiot; l <= i__1; ++l) {
300 | dx = x[l + 1] - xeye;
301 | if (itch < 0) {
302 | temp2 = yeye - sgn * e[l + 1];
303 | }
304 | temp1 = (y[l + 1] - temp2) / dx;
305 | test = temp1 - smax;
306 | if (sgn <= (double)0.) {
307 | test = -test;
308 | }
309 | if (test < (double)0.) {
310 | goto L180;
311 | } else if (test == 0) {
312 | goto L190;
313 | } else {
314 | goto L200;
315 | }
316 | L180:
317 | smax = temp1;
318 | L190:
319 | ipiv = l + 1;
320 | L200:
321 | ;
322 | }
323 | goto L70;
324 | /* END OF CURRENT SEGMENT */
325 | L210:
326 | temp2 = smin;
327 | if (i__ == n) {
328 | goto L240;
329 | }
330 | keep = igraze;
331 | goto L250;
332 | L220:
333 | temp2 = smax;
334 | if (i__ == n) {
335 | goto L230;
336 | }
337 | sgn = -sgn;
338 | epsln = -epsln;
339 | keep = ipiv;
340 | goto L250;
341 | L230:
342 | if (indc == 0 || xeye != x[n - 1]) {
343 | goto L240;
344 | }
345 | xeye = svx;
346 | yeye = svy;
347 | smin = svmn;
348 | smax = svmx;
349 | L240:
350 | u[j] = x[n - 1];
351 | yinit = y[n - 1];
352 | goto L270;
353 | L250:
354 | if ((i__1 = abs(itch) - 4, abs(i__1)) != 2) {
355 | goto L300;
356 | }
357 | /* DETERMINE KNOT ON EDGE OF TOLERANCE BAND */
358 | temp1 = (double)0.;
359 | if (itch < 0) {
360 | temp1 = epsln - sgn * e[i__ - 1];
361 | }
362 | temp1 = (y[i__] - y[i__ - 1] + temp1) / (x[i__] - x[i__ - 1]);
363 | u[j] = (y[i__] + epsln - yeye - temp1 * x[i__] + temp2 * xeye) / (temp2 -
364 | temp1);
365 | goto L310;
366 | L260:
367 | u[j] = x[n];
368 | yinit = y[n];
369 | L270:
370 | /* CONTINUITY CHECK FOR LAST SEGMENT */
371 | if (abs(itch) >= 3 || init == 1) {
372 | goto L290;
373 | }
374 | it = init - 1;
375 | svmx = smax + sgn;
376 | temp2 = yeye + epsln;
377 | i__1 = it;
378 | for (l = kp; l <= i__1; ++l) {
379 | if (itch < 0) {
380 | temp2 = yeye + sgn * e[l];
381 | }
382 | temp1 = (y[l] - temp2) / (x[l] - xeye);
383 | test = temp1 - svmx;
384 | if (sgn <= (double)0.) {
385 | test = -test;
386 | }
387 | if (test < (double)0.) {
388 | svmx = temp1;
389 | }
390 | /* L280: */
391 | }
392 | if ((r__1 = svmx - smax + svmx - smin, fabs(r__1)) <= (r__2 = smax - smin,
393 | fabs(r__2))) {
394 | smax = svmx;
395 | }
396 | L290:
397 | /* NEARNESS CHECK FOR LAST SEGMENT */
398 | temp2 = smax;
399 | temp1 = yeye + smax * (u[j] - xeye);
400 | test = yinit - temp1;
401 | if (sgn < (double)0.) {
402 | test = -test;
403 | }
404 | if (test > (double)0.) {
405 | goto L310;
406 | }
407 | temp2 = smin;
408 | temp1 = yeye + smin * (u[j] - xeye);
409 | test = yinit - temp1;
410 | if (sgn < (double)0.) {
411 | test = -test;
412 | }
413 | if (test < (double)0.) {
414 | goto L310;
415 | }
416 | temp2 = (yinit - yeye) / (u[j] - xeye);
417 | v[j] = yinit;
418 | goto L320;
419 | L300:
420 | if (abs(itch) >= 3) {
421 | goto L330;
422 | }
423 | u[j] = (x[i__] + x[i__ - 1]) * (double).5;
424 | L310:
425 | v[j] = yeye + temp2 * (u[j] - xeye);
426 | L320:
427 | if (xeye != xinit) {
428 | goto L330;
429 | }
430 | if (abs(itch) == 2) {
431 | goto L360;
432 | }
433 | if (abs(itch) != 6) {
434 | goto L330;
435 | }
436 | if (j <= 2) {
437 | goto L380;
438 | }
439 | goto L390;
440 | L330:
441 | /* RECOMPUTATION OF KNOT FOR CONTINUITY */
442 | if (j <= 2) {
443 | goto L370;
444 | }
445 | if (slope == temp2) {
446 | goto L360;
447 | }
448 | yinit = v[j - 2];
449 | if (abs(itch) < 3) {
450 | yinit = w[j - 2];
451 | }
452 | temp1 = (xeye * temp2 - u[j - 2] * slope + yinit - yeye) / (temp2 - slope)
453 | ;
454 | if (abs(itch) >= 3) {
455 | goto L350;
456 | }
457 | if (temp1 > xinit) {
458 | goto L360;
459 | }
460 | test = fabs(epsln);
461 | idiot = init - kp;
462 | i__1 = idiot;
463 | for (l = 1; l <= i__1; ++l) {
464 | it = init - l;
465 | if (temp1 >= x[it]) {
466 | goto L350;
467 | }
468 | dx = y[it] - yeye - temp2 * (x[it] - xeye);
469 | if (itch < 0) {
470 | test = e[it];
471 | }
472 | if (fabs(dx) > test) {
473 | goto L360;
474 | }
475 | /* L340: */
476 | }
477 | L350:
478 | u[j - 1] = temp1;
479 | v[j - 1] = yeye + temp2 * (u[j - 1] - xeye);
480 | if (abs(itch) < 3) {
481 | w[j - 1] = v[j - 1];
482 | }
483 | goto L390;
484 | L360:
485 | w[j - 1] = yeye + temp2 * (u[j - 1] - xeye);
486 | goto L390;
487 | L370:
488 | if (abs(itch) < 3) {
489 | goto L360;
490 | }
491 | L380:
492 | v[1] = yeye + temp2 * (u[1] - xeye);
493 | L390:
494 | slope = temp2;
495 | kp = keep;
496 | if (i__ < n) {
497 | goto L20;
498 | }
499 | if (x[n] == u[j]) {
500 | goto L400;
501 | }
502 | if (abs(itch) < 3) {
503 | w[j] = v[j];
504 | }
505 | ++j;
506 | u[j] = x[n];
507 | v[j] = y[n];
508 | L400:
509 | if (j >= 2 && abs(itch) < 3) {
510 | v[1] = w[1];
511 | }
512 | *k = j - 1;
513 | }
514 |
515 |
--------------------------------------------------------------------------------
/pyatomdb/make_test_outputs.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 |
3 | pyatomdbversion=pyatomdb.__version__
4 |
5 | PYADBVERS = pyatomdbversion.replace('.','')
6 |
7 | ADBVERS = '309'
8 |
9 | s = pyatomdb.spectrum.CIESession()
10 |
11 | ebins=pyatomdb.numpy.linspace(0.1,10,1000)
12 | s.set_response(ebins*1.0, raw=True)
13 | y = s.return_spectrum(1.0)
14 |
15 | pyatomdb.numpy.save("tests/testdata/test_set_response_spec1_%s.npy"%(ADBVERS),y)
16 |
17 |
18 | s = pyatomdb.spectrum.CIESession()
19 | t = {}
20 | s.set_response('tests/testdata/aciss_heg1_cy19.grmf',\
21 | arf='tests/testdata/aciss_heg1_cy19.garf')
22 |
23 | t['spec'] = s.return_spectrum(1.0)
24 |
25 | s.set_broadening(True)
26 | t['tbroadspec'] = s.return_spectrum(1.0)
27 |
28 | s.set_response('tests/testdata/aciss_heg1_cy19.grmf',arf=False)
29 | t['tbroadspec_noarf'] = s.return_spectrum(1.0)
30 |
31 | pyatomdb.numpy.savez("tests/testdata/test_set_response_spec2_%s.npz"%(ADBVERS),\
32 | spec=t['spec'],\
33 | tbroadspec=t['tbroadspec'],\
34 | tbroadspec_noarf=t['tbroadspec_noarf'])
35 |
36 |
--------------------------------------------------------------------------------
/pyatomdb/pyatomdb/__init__.py:
--------------------------------------------------------------------------------
1 | __all__=["atomdb","util","atomic","spectrum","const","apec"]
2 |
3 | #from .atomdb import *
4 | import os
5 | from . import spectrum
6 | from . import atomic
7 | import ctypes
8 | from . import apec
9 | from . import util
10 | import sys, glob
11 |
12 | __version__="1.0.5"
13 |
14 | try:
15 | PATH = os.path.dirname(__file__)
16 | g = glob.glob("%s/../linear_approx*.dylib"%(PATH))
17 | if len(g) ==1:
18 | liblinapprox_file = os.path.join(PATH,g[0])
19 | else:
20 | g = glob.glob("%s/../linear_approx*.so"%(PATH))
21 | liblinapprox_file = os.path.join(PATH,g[0])
22 |
23 | liblinapprox = ctypes.CDLL( liblinapprox_file, ctypes.RTLD_GLOBAL)
24 | except (OSError, IndexError):
25 | on_rtd=os.environ.get('READTHEDOCS')=='True'
26 | if on_rtd:
27 | pass
28 | else:
29 | raise
30 |
31 | # check initialization
32 | on_rtd=os.environ.get('READTHEDOCS')=='True'
33 | if on_rtd:
34 | pass
35 | else:
36 | if os.environ.get('ATOMDB')==None:
37 | # issues here
38 | install = ''
39 | while not install in ['yes','no']:
40 | install = util.question("ATOMDB environment variable not set. Set up AtomDB files now?", "yes",multichoice=["yes","no","info"])
41 | if install=='info':
42 | print("If yes, this will run the pyatomdb.util.initialize() script, which installs the necessary data files to run pyatomdb")
43 | if install=='yes':
44 | util.initialize()
45 |
46 | elif not os.path.exists(os.path.expandvars("$ATOMDB/userdata")):
47 | install = ''
48 | while not install in ['yes','no']:
49 | install = util.question("ATOMDB Environment Variable Not Set. Set up AtomDB files now?", "yes",multichoice=["yes","no","info"])
50 | if install=='info':
51 | print("If yes, this will run the pyatomdb.util.initialize() script, which installs the necessary data files to run pyatomdb")
52 |
53 | if install=='yes':
54 | util.initialize()
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/pyatomdb/pyatomdb/const.py:
--------------------------------------------------------------------------------
1 | """
2 | This contains a list of constants, both physical and apec code related.
3 |
4 | Version 0.1 - initial release
5 | Adam Foster July 17th 2015
6 | """
7 |
8 | #PHYSICAL CONSTANTS
9 | KBOLTZ = 8.617385e-8# /*!< in units of keV/K *== 1/(11604.5*1000)/
10 | M_E = 2.7182818284590452354 # /*!< Euler e */
11 | UPSILON_COLL_COEFF = 8.629e-6 # /*!< sqrt{2 pi / kB} hbar^2/m_e^{1.5} */
12 | ERG_KEV = 1.60219e-9
13 | ME_KEV = 510.99895
14 | RYDBERG = 0.013605693122 # in keV, updated to NIST value 6/11/2024. Previously 0.013605804
15 | BREMS_COEFF = 1.6542996e-20
16 | PLANCK_CONSTANT = 6.626176e-27 # erg-seconds
17 | CLASSICAL_ELECTRON_RADIUS = 2.8179403262e-13 # m
18 | PROTON_MASS = 1.67262192e-24 # gm
19 | ELECTRON_MASS =9.1e-28 #gm
20 | BOLTZMAN_CONSTANT = 1.380649e-16 #cgs
21 |
22 | HC_IN_KEV_A = 12.398425 # hc for converting keV to Ang
23 |
24 | HC_IN_ERG_A = 1.9862e-8 # /* = hc (erg A) = 12398.425 * 1.602e-12 */
25 | SAF_COEFF = 3.30e-24
26 |
27 | LIGHTSPEED = 299792458. # m/s
28 |
29 | AMUKG = 1.66054E-27
30 |
31 |
32 | # APEC SPECIFIC CONSTANTS
33 | MAX_UPS = 20
34 | MAX_CHI = 200.0
35 | MAX_IONREC = 20
36 |
37 | E_UPSILON=1 # /*!< Electron upsilon values (unitless) */
38 | E_RATE_COEFF=2 #/*!< Electron rate coefficient (cm^3/s) */
39 | P_UPSILON=3 #/*!< Proton upsilon values (unitless) */
40 | P_RATE_COEFF=4 #/*!< Proton rate coefficient (cm^3/s) */
41 | EI_UPSILON=5 # /*!< Electron-impact ionization upsilon values (unitless) */
42 |
43 | BURGESSTULLY=1 #/*!< Burgess-Tully-type data*/
44 | CHIANTI_1=11 #/*!< CHIANTI pre-4.0 type 1 data (5 pt spline) */
45 | CHIANTI_2=12 #/*!< CHIANTI pre-4.0 type 2 data (5 pt spline) */
46 | CHIANTI_3=13 #/*!< CHIANTI pre-4.0 type 3 data (5 pt spline) */
47 | CHIANTI_4=14 #/*!< CHIANTI pre-4.0 type 4 data (5 pt spline) */
48 | CHIANTI_5=15 #/*!< CHIANTI pre-4.0 type 5 data (5 pt spline) */
49 | CHIANTI_6=16 #/*!< CHIANTI pre-4.0 type 6 data (5 pt spline) */
50 |
51 | CHIANTI4_1=21 #/*!< CHIANTI 4.0 type 1 data (9 pt spline) */
52 | CHIANTI4_2=22 #/*!< CHIANTI 4.0 type 2 data (9 pt spline) */
53 | CHIANTI4_3=23 #/*!< CHIANTI 4.0 type 3 data (9 pt spline) */
54 | CHIANTI4_4=24 #/*!< CHIANTI 4.0 type 4 data (9 pt spline) */
55 | CHIANTI4_5=25 #/*!< CHIANTI 4.0 type 5 data (9 pt spline) */
56 | CHIANTI4_6=26 #/*!< CHIANTI 4.0 type 6 data (9 pt spline) */
57 |
58 | SGC_1=31 #/*!< Sampson, Goett and Clark (1983) S-type He-like data */
59 | SGC_2=32 #/*!< Sampson, Goett and Clark (1983) P-type He-like data */
60 | SGC_3=33 #/*!< Sampson, Goett and Clark (1983) S-type H-like data */
61 | KATO_NAKAZAKI_1=41 #/*!< Kato and Nakazaki (1989), ADNDT 42, 313 */
62 | KATO_NAKAZAKI_2=42 #/*!< Kato and Nakazaki (1989), ADNDT 42, 313 */
63 |
64 | #/* These must be spaced by at least MAX_UPS */
65 |
66 | INTERP_E_UPSILON=100 #/*!< Include both left & right boundaries */
67 | INTERP_P_UPSILON=200 #/*!< Include both left & right boundaries */
68 | INTERP_E_RATE_COEFF=300 #/*!< Include both left & right boundaries */
69 | INTERP_P_RATE_COEFF=400 #/*!< Include both left & right boundaries */
70 |
71 | INTERP_E_UPS_OPEN=150 #/*!< Include neither boundary */
72 | INTERP_P_UPS_OPEN=250 #/*!< Include neither boundary */
73 | INTERP_E_RATE_OPEN=350 #/*!< Include neither boundary */
74 | INTERP_P_RATE_OPEN=450 #/*!< Include neither boundary */
75 |
76 | INTERP_E_UPS_INC_MIN=500 #/*!< Include only minimum; max is out */
77 | INTERP_P_UPS_INC_MIN=600 #/*!< Include only minimum; max is out */
78 | INTERP_E_RATE_INC_MIN=700 #/*!< Include only minimum; max is out */
79 | INTERP_P_RATE_INC_MIN=800 #/*!< Include only minimum; max is out */
80 |
81 | INTERP_E_UPS_INC_MAX=550 #/*!< Include only maximum; min is out */
82 | INTERP_P_UPS_INC_MAX=650 #/*!< Include only maximum; min is out */
83 | INTERP_E_RATE_INC_MAX=750 #/*!< Include only maximum; min is out */
84 | INTERP_P_RATE_INC_MAX=850 #/*!< Include only maximum; min is out */
85 |
86 | INTERP_I_UPSILON=900 #/*!< Include both left & right boundaries */
87 |
88 | PROTON_BT=1001 #/*!< For Burgess-Tully Proton excitation rates */
89 |
90 |
91 | CI_YOUNGER = 51
92 | CI_URDAMPILLETA = 52
93 | CI_HAHNMULLERSAVIN = 53 # Double ionization rate coeffts
94 | EA_ARNROTH_LITHIUM = 61
95 | EA_ARNROTH = 62
96 | EA_MAZZOTTA_IRON = 63
97 | EA_URDAMPILLETA = 64
98 | RR_SHULL = 71
99 | RR_VERNER = 72
100 | RR_ARNRAY = 73
101 | RR_BADNELL = 74
102 | DR_MAZZOTTA = 81
103 | DR_BADNELL = 82
104 | CI_DERE = 100
105 |
106 | INTERP_IONREC_RATE_COEFF = 300
107 | INTERP_IONREC_RATE_OPEN = 350
108 | INTERP_IONREC_RATE_INC_MIN = 700
109 | INTERP_IONREC_RATE_INC_MAX = 750
110 |
111 |
112 | NO_PHOT= -1
113 | HYDROGENIC= 0
114 | CLARK= 1
115 | VERNER= 2
116 | XSTAR= 3
117 | XSTAR_49_MIN =10000
118 | XSTAR_49_MAX =19999
119 | XSTAR_53_MIN =20000
120 | XSTAR_53_MAX =29999
121 |
122 |
123 | #Bremsstrahlung types:
124 | HUMMER = 1
125 | KELLOGG = 2
126 | RELATIVISTIC = 3
127 | BREMS_NONE = 4
128 |
129 | #MISCfile types in FILEMAP files
130 | ABUNDANCE = 10
131 | HUMMER_TYPE = 11
132 | GAUNT_FF_TYPE = 13
133 |
134 |
135 | RRC_COEFF = 1.31e8
136 | TOT_ABSACC = 1.e-21
137 | TOT_RELACC = 0.0001
138 | BIN_ABSACC = 1.e-21
139 | BIN_RELACC = 0.01
140 |
141 | TOLERANCE = 0.01
142 |
143 | MIN_RRC_EXPONENT=-150.
144 | MAX_RRC_EXPONENT=150.
145 |
146 |
147 | ROMANIK = 1
148 | SAFRANOVA = 2
149 |
150 | # ATOMDB ONLINE CONSTANTS
151 | FILEDOWNLOAD = 1
152 |
153 | # APEC SIZE LIMITS
154 | NLEV_NOSPARSE = 60000
155 | MIN_IONPOP = 1e-10
156 | MIN_LEVPOP = 1e-40
157 |
158 | # MISC
159 | MAXZ_CIE = 30
160 | MAXZ_NEI = 30
161 |
162 | MINEPSOFFSET=1e-40
163 |
164 |
165 | FTPPATH = 'https://hea-www.cfa.harvard.edu/AtomDB'
166 |
--------------------------------------------------------------------------------
/pyatomdb/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools >= 64"]
3 | build-backend = "setuptools.build_meta"
4 |
5 | [project]
6 | dynamic = ["version"]
7 | name = 'pyatomdb'
8 | dependencies = ["numpydoc", "requests", "wget", "numpy>=1.9.0", "scipy>=1.9.0", "joblib", "mock", "astropy"]
9 | authors = [
10 | {name = "Adam Foster", email = "afoster@cfa.harvard.edu"}
11 | ]
12 | maintainers = [
13 | {name = "Adam Foster", email = "afoster@cfa.harvard.edu"}
14 | ]
15 | description="AtomDB python library."
16 | #url=['http://www.atomdb.org']
17 | #packages=['pyatomdb','tests']
18 |
19 | classifiers=["Development Status :: 4 - Beta",
20 | # "Environment :: Console",
21 | "Intended Audience :: Developers",
22 | "Intended Audience :: Education",
23 | "Intended Audience :: End Users/Desktop",
24 | "Intended Audience :: Science/Research",
25 | "Topic :: Scientific/Engineering :: Astronomy",
26 | "Topic :: Scientific/Engineering :: Physics",
27 | "Programming Language :: Python :: 3",
28 | "Operating System :: POSIX"]
29 |
30 | readme = "README.rst"
31 | license = {file = "COPYING.txt"}
32 | [project.urls]
33 | Homepage = "http://www.atomdb.org"
34 | Documentation = "https://atomdb.readthedocs.io/en/master/"
35 | Repository = "https://github.com/AtomDB/pyatomdb.git"
36 | Issues = "https://github.com/AtomDB/pyatomdb/issues"
37 | #Changelog = "https://github.com/me/spam/blob/master/CHANGELOG.md"
38 |
39 | [tool.setuptools.dynamic]
40 | version = {attr = "pyatomdb.__version__"}
41 |
--------------------------------------------------------------------------------
/pyatomdb/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, Extension
2 | import os
3 |
4 | import sys
5 |
6 |
7 | on_rtd = os.environ.get('READTHEDOCS')=='True'
8 |
9 |
10 | def get_version(relpath):
11 | """read version info from file without importing it"""
12 | from os.path import dirname, join
13 | for line in open(join(dirname(__file__), relpath)):
14 | if '__version__' in line:
15 | if '"' in line:
16 | # __version__ = "0.10"
17 | return line.split('"')[1]
18 | elif "'" in line:
19 | return line.split("'")[1]
20 |
21 |
22 | readme = open('README.rst', 'r')
23 | README_TEXT = readme.read()
24 | readme.close()
25 |
26 | linapprox = Extension("linear_approx",['linear_approx.c'],\
27 | define_macros = [('MAJOR_VERSION', '1'),\
28 | ('MINOR_VERSION','0')])
29 |
30 |
31 |
32 |
33 | if on_rtd:
34 | try:
35 | from unittest.mock import MagicMock
36 | except ImportError:
37 | from mock import Mock as MagicMock
38 |
39 |
40 | extmos= []
41 |
42 | # class Mock(MagicMock):
43 | # @classmethod
44 | # def __getattr__(cls, name):
45 | # return Mock()
46 |
47 | MOCK_MODULES = ['liblinapprox']
48 | sys.modules.update((mod_name, MagicMock()) for mod_name in MOCK_MODULES)
49 |
50 | else:
51 | extmos= [linapprox]
52 | #setup()
53 | setup(name='pyatomdb',
54 | # version=get_version('pyatomdb/__init__.py'),
55 | # description='AtomDB python library.',
56 | # url='http://www.atomdb.org',
57 | # author='Adam Foster',
58 | # author_email='afoster@cfa.harvard.edu',
59 | # license='Smithsonian',
60 | packages=['pyatomdb','tests'],
61 | # classifiers=['Development Status :: 4 - Beta',\
62 | # 'Environment :: Console',\
63 | # 'Intended Audience :: Developers',\
64 | # 'Intended Audience :: Education',\
65 | # 'Intended Audience :: End Users/Desktop',\
66 | # 'Intended Audience :: Science/Research',\
67 | # 'Topic :: Scientific/Engineering :: Astronomy',\
68 | # 'Topic :: Scientific/Engineering :: Physics',\
69 | # 'Programming Language :: Python :: 3',\
70 | # 'Operating System :: POSIX'],
71 | # zip_safe=False,
72 | # long_description = README_TEXT,\
73 | # install_requires=[
74 | # "numpydoc",\
75 | # "requests",\
76 | # "wget",\
77 | # "numpy>=1.9.0",\
78 | # "scipy>=1.9.0",\
79 | # "joblib",\
80 | # "mock",\
81 | # "astropy",\
82 | # "pycurl"],
83 | ext_modules = extmos)
84 | #
85 | #
86 |
--------------------------------------------------------------------------------
/pyatomdb/tests/__init__.py:
--------------------------------------------------------------------------------
1 | import pyatomdb
2 |
--------------------------------------------------------------------------------
/pyatomdb/tests/test1.py:
--------------------------------------------------------------------------------
1 | import unittest, warnings
2 | import pyatomdb
3 |
4 | ATOMDBVERSION='309'
5 |
6 |
7 |
8 | class TestSpectrum(unittest.TestCase):
9 |
10 |
11 | def test_convert_temp(self):
12 | """ Test temperature conversion in test_convert_temp"""
13 | T={}
14 | T['keV'] = 2.0
15 |
16 | Unitsin=['K','keV','eV']
17 | Unitsout=['K','keV','eV']
18 | T['K'] = T['keV']/pyatomdb.const.KBOLTZ
19 | T['eV'] = T['keV']*1000
20 | for Uin in Unitsin:
21 | for Uout in Unitsout:
22 | c = T[Uout]
23 | i = T[Uin]
24 | pyatomdb.numpy.testing.assert_allclose(c, pyatomdb.spectrum.convert_temp(i,Uin,Uout))
25 |
26 |
27 | self.assertRaises(pyatomdb.util.UnitsError, pyatomdb.spectrum.convert_temp, 1.0,'krf','kev')
28 |
29 | self.assertRaises(pyatomdb.util.UnitsError, pyatomdb.spectrum.convert_temp, 1.0,'kev','krh')
30 |
31 |
32 |
33 | class TestSpectrumCIESession(unittest.TestCase):
34 |
35 | def setUp(self):
36 | warnings.simplefilter("ignore", ResourceWarning)
37 |
38 | self.s = pyatomdb.spectrum.CIESession()
39 |
40 | def test_init(self):
41 | """ Testing initialization of the CIESession"""
42 | self.assertEqual(self.s.broaden_limit, 1e-18)
43 |
44 |
45 | def test_set_raw_response(self):
46 | """ Testing dummy (raw) responses"""
47 |
48 | self.assertRaises(pyatomdb.util.ReadyError, self.s.return_spectrum,1.0)
49 |
50 | ebins=pyatomdb.numpy.linspace(0.1,10,1000)
51 | self.s.set_response(ebins*1.0, raw=True)
52 | pyatomdb.numpy.testing.assert_allclose(self.s.specbins, ebins)
53 |
54 | # now test spectrum calculation
55 |
56 | # load the correct result
57 | testdat = pyatomdb.numpy.load("tests/testdata/test_set_response_spec1_%s.npy"%(ATOMDBVERSION))
58 |
59 | t = self.s.return_spectrum(1.0)
60 | pyatomdb.numpy.testing.assert_allclose(t, testdat)
61 |
62 |
63 | def test_set_response(self):
64 | """ Testing real responses and spectral broadening"""
65 | # test with real response
66 | self.s.set_response('tests/testdata/aciss_heg1_cy19.grmf',\
67 | arf='tests/testdata/aciss_heg1_cy19.garf')
68 |
69 | # load the correct result
70 | testdat = pyatomdb.numpy.load("tests/testdata/test_set_response_spec2_%s.npz"%(ATOMDBVERSION))
71 |
72 | # calc spectrum
73 | t = self.s.return_spectrum(1.0)
74 | pyatomdb.numpy.testing.assert_allclose(t, testdat['spec'])
75 |
76 |
77 | # turn on thermal broadening
78 | self.s.set_broadening(True)
79 | t = self.s.return_spectrum(1.0)
80 | pyatomdb.numpy.testing.assert_allclose(t, testdat['tbroadspec'])
81 |
82 | def test_nearest_spectrum(self):
83 | """ Testing real responses with the nearest spectrum"""
84 | # test with real response
85 | self.s.set_response('tests/testdata/aciss_heg1_cy19.grmf',\
86 | arf='tests/testdata/aciss_heg1_cy19.garf')
87 |
88 | # load the correct result
89 | testdat = pyatomdb.numpy.load("tests/testdata/test_set_response_spec2_%s.npz"%(ATOMDBVERSION))
90 |
91 | # calc spectrum
92 | t = self.s.return_spectrum(1.0)
93 | pyatomdb.numpy.testing.assert_allclose(t, testdat['spec'])
94 |
95 |
96 | # turn on thermal broadening
97 | self.s.set_broadening(True)
98 | t = self.s.return_spectrum(1.0)
99 | pyatomdb.numpy.testing.assert_allclose(t, testdat['tbroadspec'])
100 |
101 |
102 | if __name__ == '__main__':
103 | print("WHEE")
104 | unittest.main()
105 | print("WHOO")
106 |
--------------------------------------------------------------------------------
/pyatomdb/tests/testdata/aciss_heg1_cy19.garf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/tests/testdata/aciss_heg1_cy19.garf
--------------------------------------------------------------------------------
/pyatomdb/tests/testdata/aciss_heg1_cy19.grmf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/tests/testdata/aciss_heg1_cy19.grmf
--------------------------------------------------------------------------------
/pyatomdb/tests/testdata/test_set_response_spec1.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/tests/testdata/test_set_response_spec1.npy
--------------------------------------------------------------------------------
/pyatomdb/tests/testdata/test_set_response_spec1_309.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/tests/testdata/test_set_response_spec1_309.npy
--------------------------------------------------------------------------------
/pyatomdb/tests/testdata/test_set_response_spec2_309.npz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AtomDB/pyatomdb/314f3cbd809a7a1fd99cd0cb814f6f04db6990f5/pyatomdb/tests/testdata/test_set_response_spec2_309.npz
--------------------------------------------------------------------------------
/pyatomdb/wrappers/IonE_apec_xspec.py:
--------------------------------------------------------------------------------
1 | import numpy, xspec
2 | import pyatomdb
3 |
4 | # This wrapper is for using a separate temperature for defining line broadening
5 | # in the spectrum, instead of just Te. kTlwidth is the temperature used for this
6 | # There are many things out there called ion temperature. Strictly, this
7 | # would be the correct use of that term. However I am loathe to use it because
8 | # it is misused so ofter elsewhere. Instead the parameter is named kTlwidth.
9 |
10 | # To use this, import this file within the python session you have XSPEC running
11 | # in. e.g.
12 |
13 | #
14 | # python
15 | # python> import xspec
16 | # python> import IonE_apec_xspec
17 | # python> m1 = xspec.Model('pyibapec')
18 |
19 | #initialize CX object
20 | cie = pyatomdb.spectrum.CIESession()
21 | cie.set_broadening(True)
22 | # These are the definitions XSPEC uses for the inputs
23 |
24 | pyibapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
25 | "Abundanc \"\" 1.0 0.01 0.2 100. 1000. 0.01",
26 | "kTlwidth \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",\
27 | "Velocity \"km/s\" 0.0 -10.0 0. 0. 1e6 1e6",
28 | "*Redshift \"\" 0.0")
29 |
30 | pyibvapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
31 | "H \"\" 1.0 0.01 0.2 100. 1000. 0.01",
32 | "He \"\" 1.0 0.01 0.2 100. 1000. 0.01",
33 | "C \"\" 1.0 0.01 0.2 100. 1000. 0.01",
34 | "N \"\" 1.0 0.01 0.2 100. 1000. 0.01",
35 | "O \"\" 1.0 0.01 0.2 100. 1000. 0.01",
36 | "Ne \"\" 1.0 0.01 0.2 100. 1000. 0.01",
37 | "Mg \"\" 1.0 0.01 0.2 100. 1000. 0.01",
38 | "Al \"\" 1.0 0.01 0.2 100. 1000. 0.01",
39 | "Si \"\" 1.0 0.01 0.2 100. 1000. 0.01",
40 | "S \"\" 1.0 0.01 0.2 100. 1000. 0.01",
41 | "Ar \"\" 1.0 0.01 0.2 100. 1000. 0.01",
42 | "Ca \"\" 1.0 0.01 0.2 100. 1000. 0.01",
43 | "Fe \"\" 1.0 0.01 0.2 100. 1000. 0.01",
44 | "Ni \"\" 1.0 0.01 0.2 100. 1000. 0.01",
45 | "kTlwidth \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",\
46 | "Velocity \"km/s\" 0.0 -10.0 0. 0. 1e6 1e6",
47 | "*Redshift \"\" 0.0")
48 |
49 |
50 | pyibvvapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
51 | "H \"\" 1.0 0.01 0.2 100. 1000. 0.01",
52 | "He \"\" 1.0 0.01 0.2 100. 1000. 0.01",
53 | "Li \"\" 1.0 0.01 0.2 100. 1000. 0.01",
54 | "Be \"\" 1.0 0.01 0.2 100. 1000. 0.01",
55 | "B \"\" 1.0 0.01 0.2 100. 1000. 0.01",
56 | "C \"\" 1.0 0.01 0.2 100. 1000. 0.01",
57 | "N \"\" 1.0 0.01 0.2 100. 1000. 0.01",
58 | "O \"\" 1.0 0.01 0.2 100. 1000. 0.01",
59 | "F \"\" 1.0 0.01 0.2 100. 1000. 0.01",
60 | "Ne \"\" 1.0 0.01 0.2 100. 1000. 0.01",
61 | "Na \"\" 1.0 0.01 0.2 100. 1000. 0.01",
62 | "Mg \"\" 1.0 0.01 0.2 100. 1000. 0.01",
63 | "Al \"\" 1.0 0.01 0.2 100. 1000. 0.01",
64 | "Si \"\" 1.0 0.01 0.2 100. 1000. 0.01",
65 | "P \"\" 1.0 0.01 0.2 100. 1000. 0.01",
66 | "S \"\" 1.0 0.01 0.2 100. 1000. 0.01",
67 | "Cl \"\" 1.0 0.01 0.2 100. 1000. 0.01",
68 | "Ar \"\" 1.0 0.01 0.2 100. 1000. 0.01",
69 | "K \"\" 1.0 0.01 0.2 100. 1000. 0.01",
70 | "Ca \"\" 1.0 0.01 0.2 100. 1000. 0.01",
71 | "Sc \"\" 1.0 0.01 0.2 100. 1000. 0.01",
72 | "Ti \"\" 1.0 0.01 0.2 100. 1000. 0.01",
73 | "V \"\" 1.0 0.01 0.2 100. 1000. 0.01",
74 | "Cr \"\" 1.0 0.01 0.2 100. 1000. 0.01",
75 | "Mn \"\" 1.0 0.01 0.2 100. 1000. 0.01",
76 | "Fe \"\" 1.0 0.01 0.2 100. 1000. 0.01",
77 | "Co \"\" 1.0 0.01 0.2 100. 1000. 0.01",
78 | "Ni \"\" 1.0 0.01 0.2 100. 1000. 0.01",
79 | "Cu \"\" 1.0 0.01 0.2 100. 1000. 0.01",
80 | "Zn \"\" 1.0 0.01 0.2 100. 1000. 0.01",
81 | "kTlwidth \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",\
82 | "Velocity \"km/s\" 0.0 -10.0 0. 0. 1e6 1e6",
83 | "*Redshift \"\" 0.0")
84 |
85 |
86 |
87 | def pyibapec(engs, params, flux):
88 |
89 | """
90 | CIE model for data
91 |
92 | PARAMETERS
93 | ----------
94 | engs : list[float]
95 | The energy bin edges (from xspec)
96 | params : list[float]
97 | The parameter list. See acx2Info for definition
98 | flux : list[float]
99 | The array to fill with return values
100 |
101 | RETURNS
102 | -------
103 | None
104 | Fills out the flux array with photon cm3 s-1 bin-1, x10^14
105 |
106 | USAGE
107 | -----
108 | # load the model into XSPEC
109 | xspec.AllModels.addPyMod(pyapec, pyapecInfo, 'add')
110 | # make a model
111 | m = xspec.Model('pyapec')
112 | """
113 |
114 | # This is the call that will return everything. So set everything!
115 | ebins = numpy.array(engs)
116 |
117 | elements = []
118 | for i in range(1,31): elements.append(i)
119 |
120 | if len(params)==6:
121 | # apec model
122 | abund=numpy.array(params[1])
123 | elements=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,\
124 | 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
125 | eloffset = 2
126 | elif len(params)==19:
127 | # apec model
128 | elements=[1,2,6,7,8,10,12,13,14,16,18,20,26,28]
129 | abund=params[1:15]
130 | eloffset = 15
131 | elif len(params)==35:
132 | # apec model
133 | elements=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\
134 | 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
135 | abund=params[1:31]
136 | eloffset = 31
137 |
138 | thermal_broaden_temperature=float(params[eloffset])
139 |
140 | vel_broadening = float(params[eloffset+1])
141 | # get redshift
142 | redshift = float(params[eloffset+2])
143 |
144 | # set energy bins, accounting for redshift
145 | cie.set_response(ebins*(1.0+redshift), raw=True)
146 |
147 |
148 | # set abundance vector
149 | # abund = numpy.array(params[1])
150 | cie.set_abund(elements, abund)
151 | cie.set_eebrems(False)
152 | cie.set_broadening(True, velocity_broadening=vel_broadening,\
153 | thermal_broaden_temperature=thermal_broaden_temperature)
154 | # get the spectrum
155 | spec = cie.return_spectrum(params[0], log_interp=False)
156 |
157 | # return the flux.
158 | flux[:] = spec*1e14
159 |
160 | def pyibvapec(engs, params, flux):
161 | pyibapec(engs, params, flux)
162 |
163 | def pyibvvapec(engs, params, flux):
164 | pyibapec(engs, params, flux)
165 |
166 |
167 |
168 | # this is how to import the models into pyxspec.
169 | xspec.AllModels.addPyMod(pyibapec, pyibapecInfo, 'add')
170 | xspec.AllModels.addPyMod(pyibvapec, pyibvapecInfo, 'add')
171 | xspec.AllModels.addPyMod(pyibvvapec, pyibvvapecInfo, 'add')
172 |
173 |
--------------------------------------------------------------------------------
/pyatomdb/wrappers/apec_xspec.py:
--------------------------------------------------------------------------------
1 | import numpy, xspec
2 | import pyatomdb
3 |
4 | #initialize CX object
5 | cie = pyatomdb.spectrum.CIESession()
6 |
7 | # These are the definitions XSPEC uses for the inputs
8 |
9 | pyapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
10 | "Abundanc \"\" 1.0 0.01 0.2 100. 1000. 0.01",
11 | "*Redshift \"\" 0.0")
12 |
13 | pyvapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
14 | "H \"\" 1.0 0.01 0.2 100. 1000. 0.01",
15 | "He \"\" 1.0 0.01 0.2 100. 1000. 0.01",
16 | "C \"\" 1.0 0.01 0.2 100. 1000. 0.01",
17 | "N \"\" 1.0 0.01 0.2 100. 1000. 0.01",
18 | "O \"\" 1.0 0.01 0.2 100. 1000. 0.01",
19 | "Ne \"\" 1.0 0.01 0.2 100. 1000. 0.01",
20 | "Mg \"\" 1.0 0.01 0.2 100. 1000. 0.01",
21 | "Al \"\" 1.0 0.01 0.2 100. 1000. 0.01",
22 | "Si \"\" 1.0 0.01 0.2 100. 1000. 0.01",
23 | "S \"\" 1.0 0.01 0.2 100. 1000. 0.01",
24 | "Ar \"\" 1.0 0.01 0.2 100. 1000. 0.01",
25 | "Ca \"\" 1.0 0.01 0.2 100. 1000. 0.01",
26 | "Fe \"\" 1.0 0.01 0.2 100. 1000. 0.01",
27 | "Ni \"\" 1.0 0.01 0.2 100. 1000. 0.01",
28 | "*Redshift \"\" 0.0")
29 |
30 |
31 | pyvvapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
32 | "H \"\" 1.0 0.01 0.2 100. 1000. 0.01",
33 | "He \"\" 1.0 0.01 0.2 100. 1000. 0.01",
34 | "Li \"\" 1.0 0.01 0.2 100. 1000. 0.01",
35 | "Be \"\" 1.0 0.01 0.2 100. 1000. 0.01",
36 | "B \"\" 1.0 0.01 0.2 100. 1000. 0.01",
37 | "C \"\" 1.0 0.01 0.2 100. 1000. 0.01",
38 | "N \"\" 1.0 0.01 0.2 100. 1000. 0.01",
39 | "O \"\" 1.0 0.01 0.2 100. 1000. 0.01",
40 | "F \"\" 1.0 0.01 0.2 100. 1000. 0.01",
41 | "Ne \"\" 1.0 0.01 0.2 100. 1000. 0.01",
42 | "Na \"\" 1.0 0.01 0.2 100. 1000. 0.01",
43 | "Mg \"\" 1.0 0.01 0.2 100. 1000. 0.01",
44 | "Al \"\" 1.0 0.01 0.2 100. 1000. 0.01",
45 | "Si \"\" 1.0 0.01 0.2 100. 1000. 0.01",
46 | "P \"\" 1.0 0.01 0.2 100. 1000. 0.01",
47 | "S \"\" 1.0 0.01 0.2 100. 1000. 0.01",
48 | "Cl \"\" 1.0 0.01 0.2 100. 1000. 0.01",
49 | "Ar \"\" 1.0 0.01 0.2 100. 1000. 0.01",
50 | "K \"\" 1.0 0.01 0.2 100. 1000. 0.01",
51 | "Ca \"\" 1.0 0.01 0.2 100. 1000. 0.01",
52 | "Sc \"\" 1.0 0.01 0.2 100. 1000. 0.01",
53 | "Ti \"\" 1.0 0.01 0.2 100. 1000. 0.01",
54 | "V \"\" 1.0 0.01 0.2 100. 1000. 0.01",
55 | "Cr \"\" 1.0 0.01 0.2 100. 1000. 0.01",
56 | "Mn \"\" 1.0 0.01 0.2 100. 1000. 0.01",
57 | "Fe \"\" 1.0 0.01 0.2 100. 1000. 0.01",
58 | "Co \"\" 1.0 0.01 0.2 100. 1000. 0.01",
59 | "Ni \"\" 1.0 0.01 0.2 100. 1000. 0.01",
60 | "Cu \"\" 1.0 0.01 0.2 100. 1000. 0.01",
61 | "Zn \"\" 1.0 0.01 0.2 100. 1000. 0.01",
62 | "*Redshift \"\" 0.0")
63 |
64 |
65 |
66 | def pyapec(engs, params, flux):
67 |
68 | """
69 | ACX2 model for data
70 |
71 | PARAMETERS
72 | ----------
73 | engs : list[float]
74 | The energy bin edges (from xspec)
75 | params : list[float]
76 | The parameter list. See acx2Info for definition
77 | flux : list[float]
78 | The array to fill with return values
79 |
80 | RETURNS
81 | -------
82 | None
83 | Fills out the flux array with photon cm3 s-1 bin-1, x1e10
84 |
85 | USAGE
86 | -----
87 | # load the model into XSPEC
88 | xspec.AllModels.addPyMod(pyapec, pyapecInfo, 'add')
89 | # make a model
90 | m = xspec.Model('pyapec')
91 | """
92 |
93 | # This is the call that will return everything. So set everything!
94 | ebins = numpy.array(engs)
95 |
96 | elements = []
97 | for i in range(1,31): elements.append(i)
98 |
99 | if len(params)==4:
100 | # apec model
101 | abund=numpy.array(params[1])
102 | elements=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,\
103 | 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
104 | eloffset = 2
105 | elif len(params)==17:
106 | # apec model
107 | elements=[1,2,6,7,8,10,12,13,14,16,18,20,26,28]
108 | abund=params[1:15]
109 | eloffset = 15
110 | elif len(params)==33:
111 | # apec model
112 | elements=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\
113 | 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
114 | abund=params[1:31]
115 | eloffset = 31
116 |
117 | # get redshift
118 | redshift = float(params[eloffset+0])
119 |
120 | # set energy bins, accounting for redshift
121 | cie.set_response(ebins*(1.0+redshift), raw=True)
122 |
123 |
124 | # set abundance vector
125 | # abund = numpy.array(params[1])
126 | cie.set_abund(elements, abund)
127 | cie.set_eebrems(False)
128 | # get the spectrum
129 | spec = cie.return_spectrum(params[0], log_interp=False)
130 |
131 | # return the flux.
132 | flux[:] = spec*1e14
133 |
134 | def pyvapec(engs, params, flux):
135 | pyapec(engs, params, flux)
136 |
137 | def pyvvapec(engs, params, flux):
138 | pyapec(engs, params, flux)
139 |
140 |
141 |
142 | # this is how to import the models into pyxspec.
143 | xspec.AllModels.addPyMod(pyapec, pyapecInfo, 'add')
144 | xspec.AllModels.addPyMod(pyvapec, pyvapecInfo, 'add')
145 | xspec.AllModels.addPyMod(pyvvapec, pyvvapecInfo, 'add')
146 |
147 |
--------------------------------------------------------------------------------
/pyatomdb/wrappers/bapec_xspec.py:
--------------------------------------------------------------------------------
1 | import numpy, xspec
2 | import pyatomdb
3 |
4 | #initialize CX object
5 | cie = pyatomdb.spectrum.CIESession()
6 | cie.set_broadening(True)
7 |
8 | # These are the definitions XSPEC uses for the inputs
9 |
10 | pybapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
11 | "Abundanc \"\" 1.0 0.01 0.2 100. 1000. 0.01",
12 | "*Redshift \"\" 0.0",\
13 | "Velocity \"km/s\" 0.0 -10.0 0. 0. 1e6 1e6")
14 |
15 | pybvapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
16 | "H \"\" 1.0 0.01 0.2 100. 1000. 0.01",
17 | "He \"\" 1.0 0.01 0.2 100. 1000. 0.01",
18 | "C \"\" 1.0 0.01 0.2 100. 1000. 0.01",
19 | "N \"\" 1.0 0.01 0.2 100. 1000. 0.01",
20 | "O \"\" 1.0 0.01 0.2 100. 1000. 0.01",
21 | "Ne \"\" 1.0 0.01 0.2 100. 1000. 0.01",
22 | "Mg \"\" 1.0 0.01 0.2 100. 1000. 0.01",
23 | "Al \"\" 1.0 0.01 0.2 100. 1000. 0.01",
24 | "Si \"\" 1.0 0.01 0.2 100. 1000. 0.01",
25 | "S \"\" 1.0 0.01 0.2 100. 1000. 0.01",
26 | "Ar \"\" 1.0 0.01 0.2 100. 1000. 0.01",
27 | "Ca \"\" 1.0 0.01 0.2 100. 1000. 0.01",
28 | "Fe \"\" 1.0 0.01 0.2 100. 1000. 0.01",
29 | "Ni \"\" 1.0 0.01 0.2 100. 1000. 0.01",
30 | "*Redshift \"\" 0.0",\
31 | "Velocity \"km/s\" 0.0 -10.0 0. 0. 1e6 1e6")
32 |
33 |
34 | pybvvapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
35 | "H \"\" 1.0 0.01 0.2 100. 1000. 0.01",
36 | "He \"\" 1.0 0.01 0.2 100. 1000. 0.01",
37 | "Li \"\" 1.0 0.01 0.2 100. 1000. 0.01",
38 | "Be \"\" 1.0 0.01 0.2 100. 1000. 0.01",
39 | "B \"\" 1.0 0.01 0.2 100. 1000. 0.01",
40 | "C \"\" 1.0 0.01 0.2 100. 1000. 0.01",
41 | "N \"\" 1.0 0.01 0.2 100. 1000. 0.01",
42 | "O \"\" 1.0 0.01 0.2 100. 1000. 0.01",
43 | "F \"\" 1.0 0.01 0.2 100. 1000. 0.01",
44 | "Ne \"\" 1.0 0.01 0.2 100. 1000. 0.01",
45 | "Na \"\" 1.0 0.01 0.2 100. 1000. 0.01",
46 | "Mg \"\" 1.0 0.01 0.2 100. 1000. 0.01",
47 | "Al \"\" 1.0 0.01 0.2 100. 1000. 0.01",
48 | "Si \"\" 1.0 0.01 0.2 100. 1000. 0.01",
49 | "P \"\" 1.0 0.01 0.2 100. 1000. 0.01",
50 | "S \"\" 1.0 0.01 0.2 100. 1000. 0.01",
51 | "Cl \"\" 1.0 0.01 0.2 100. 1000. 0.01",
52 | "Ar \"\" 1.0 0.01 0.2 100. 1000. 0.01",
53 | "K \"\" 1.0 0.01 0.2 100. 1000. 0.01",
54 | "Ca \"\" 1.0 0.01 0.2 100. 1000. 0.01",
55 | "Sc \"\" 1.0 0.01 0.2 100. 1000. 0.01",
56 | "Ti \"\" 1.0 0.01 0.2 100. 1000. 0.01",
57 | "V \"\" 1.0 0.01 0.2 100. 1000. 0.01",
58 | "Cr \"\" 1.0 0.01 0.2 100. 1000. 0.01",
59 | "Mn \"\" 1.0 0.01 0.2 100. 1000. 0.01",
60 | "Fe \"\" 1.0 0.01 0.2 100. 1000. 0.01",
61 | "Co \"\" 1.0 0.01 0.2 100. 1000. 0.01",
62 | "Ni \"\" 1.0 0.01 0.2 100. 1000. 0.01",
63 | "Cu \"\" 1.0 0.01 0.2 100. 1000. 0.01",
64 | "Zn \"\" 1.0 0.01 0.2 100. 1000. 0.01",\
65 | "Velocity \"km/s\" 0.0 -10.0 0. 0. 1e6 1e6",
66 | "*Redshift \"\" 0.0")
67 |
68 |
69 |
70 | def pybapec(engs, params, flux):
71 |
72 | """
73 | ACX2 model for data
74 |
75 | PARAMETERS
76 | ----------
77 | engs : list[float]
78 | The energy bin edges (from xspec)
79 | params : list[float]
80 | The parameter list. See acx2Info for definition
81 | flux : list[float]
82 | The array to fill with return values
83 |
84 | RETURNS
85 | -------
86 | None
87 | Fills out the flux array with photon cm3 s-1 bin-1, x1e10
88 |
89 | USAGE
90 | -----
91 | # load the model into XSPEC
92 | xspec.AllModels.addPyMod(pyapec, pyapecInfo, 'add')
93 | # make a model
94 | m = xspec.Model('pyapec')
95 | """
96 |
97 | # This is the call that will return everything. So set everything!
98 | ebins = numpy.array(engs)
99 |
100 | elements = []
101 | for i in range(1,31): elements.append(i)
102 |
103 | if len(params)==5:
104 | # apec model
105 | abund=numpy.array(params[1])
106 | elements=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,\
107 | 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
108 | eloffset = 2
109 | elif len(params)==18:
110 | # apec model
111 | elements=[1,2,6,7,8,10,12,13,14,16,18,20,26,28]
112 | abund=params[1:15]
113 | eloffset = 15
114 | elif len(params)==34:
115 | # apec model
116 | elements=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\
117 | 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
118 | abund=params[1:31]
119 | eloffset = 31
120 |
121 | # get redshift
122 | redshift = float(params[eloffset+0])
123 |
124 | broadening = float(params[eloffset+1])
125 |
126 | # set energy bins, accounting for redshift
127 | cie.set_response(ebins*(1.0+redshift), raw=True)
128 |
129 |
130 | # set abundance vector
131 | # abund = numpy.array(params[1])
132 | cie.set_abund(elements, abund)
133 | cie.set_eebrems(False)
134 |
135 | # set the response
136 | cie.set_broadening(True, velocity_broadening=broadening)
137 |
138 | # get the spectrum
139 | spec = cie.return_spectrum(params[0], log_interp=False)
140 |
141 | # return the flux.
142 | flux[:] = spec*1e14
143 |
144 | def pybvapec(engs, params, flux):
145 | pybapec(engs, params, flux)
146 |
147 | def pybvvapec(engs, params, flux):
148 | pybapec(engs, params, flux)
149 |
150 |
151 |
152 | # this is how to import the models into pyxspec.
153 | xspec.AllModels.addPyMod(pybapec, pybapecInfo, 'add')
154 | xspec.AllModels.addPyMod(pybvapec, pybvapecInfo, 'add')
155 | xspec.AllModels.addPyMod(pybvvapec, pybvvapecInfo, 'add')
156 |
157 |
--------------------------------------------------------------------------------
/pyatomdb/wrappers/rsapec_xspec.py:
--------------------------------------------------------------------------------
1 | import numpy, xspec
2 | import pyatomdb
3 |
4 |
5 | #initialize CX object
6 | cie_rs = pyatomdb.spectrum.CIESession_RS()
7 | cie_rs.set_broadening(True)
8 |
9 | # These are the definitions XSPEC uses for the inputs
10 |
11 |
12 |
13 | pyrsapecInfo = ("kT \"keV\" 4.0 0.00862 0.00862 86. 86. 0.01",
14 | "Abundanc \"\" 0.6 0.01 0.2 100. 1000. 0.01",
15 | "*Redshift \"\" 0.0",\
16 | "Velocity \"km/s\" 150.0 -10.0 0. 0. 1e6 1e6",
17 | "nL \"cm^-2\" 1e21 1e20 1e20 1e23 1e23 1e18")
18 |
19 |
20 |
21 | pyrsvapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
22 | "H \"\" 1.0 0.01 0.2 100. 1000. 0.01",
23 | "He \"\" 1.0 0.01 0.2 100. 1000. 0.01",
24 | "C \"\" 1.0 0.01 0.2 100. 1000. 0.01",
25 | "N \"\" 1.0 0.01 0.2 100. 1000. 0.01",
26 | "O \"\" 1.0 0.01 0.2 100. 1000. 0.01",
27 | "Ne \"\" 1.0 0.01 0.2 100. 1000. 0.01",
28 | "Mg \"\" 1.0 0.01 0.2 100. 1000. 0.01",
29 | "Al \"\" 1.0 0.01 0.2 100. 1000. 0.01",
30 | "Si \"\" 1.0 0.01 0.2 100. 1000. 0.01",
31 | "S \"\" 1.0 0.01 0.2 100. 1000. 0.01",
32 | "Ar \"\" 1.0 0.01 0.2 100. 1000. 0.01",
33 | "Ca \"\" 1.0 0.01 0.2 100. 1000. 0.01",
34 | "Fe \"\" 1.0 0.01 0.2 100. 1000. 0.01",
35 | "Ni \"\" 1.0 0.01 0.2 100. 1000. 0.01",
36 | "*Redshift \"\" 0.0",\
37 | "Velocity \"km/s\" 0.0 -10.0 0. 0. 1e6 1e6",
38 | "nL \"cm^-2\" 1e21 1e20 1e20 1e23 1e23 1e18")
39 |
40 |
41 | pyrsvvapecInfo = ("kT \"keV\" 1.0 0.00862 0.00862 86. 86. 0.01",
42 | "H \"\" 1.0 0.01 0.2 100. 1000. 0.01",
43 | "He \"\" 1.0 0.01 0.2 100. 1000. 0.01",
44 | "Li \"\" 1.0 0.01 0.2 100. 1000. 0.01",
45 | "Be \"\" 1.0 0.01 0.2 100. 1000. 0.01",
46 | "B \"\" 1.0 0.01 0.2 100. 1000. 0.01",
47 | "C \"\" 1.0 0.01 0.2 100. 1000. 0.01",
48 | "N \"\" 1.0 0.01 0.2 100. 1000. 0.01",
49 | "O \"\" 1.0 0.01 0.2 100. 1000. 0.01",
50 | "F \"\" 1.0 0.01 0.2 100. 1000. 0.01",
51 | "Ne \"\" 1.0 0.01 0.2 100. 1000. 0.01",
52 | "Na \"\" 1.0 0.01 0.2 100. 1000. 0.01",
53 | "Mg \"\" 1.0 0.01 0.2 100. 1000. 0.01",
54 | "Al \"\" 1.0 0.01 0.2 100. 1000. 0.01",
55 | "Si \"\" 1.0 0.01 0.2 100. 1000. 0.01",
56 | "P \"\" 1.0 0.01 0.2 100. 1000. 0.01",
57 | "S \"\" 1.0 0.01 0.2 100. 1000. 0.01",
58 | "Cl \"\" 1.0 0.01 0.2 100. 1000. 0.01",
59 | "Ar \"\" 1.0 0.01 0.2 100. 1000. 0.01",
60 | "K \"\" 1.0 0.01 0.2 100. 1000. 0.01",
61 | "Ca \"\" 1.0 0.01 0.2 100. 1000. 0.01",
62 | "Sc \"\" 1.0 0.01 0.2 100. 1000. 0.01",
63 | "Ti \"\" 1.0 0.01 0.2 100. 1000. 0.01",
64 | "V \"\" 1.0 0.01 0.2 100. 1000. 0.01",
65 | "Cr \"\" 1.0 0.01 0.2 100. 1000. 0.01",
66 | "Mn \"\" 1.0 0.01 0.2 100. 1000. 0.01",
67 | "Fe \"\" 1.0 0.01 0.2 100. 1000. 0.01",
68 | "Co \"\" 1.0 0.01 0.2 100. 1000. 0.01",
69 | "Ni \"\" 1.0 0.01 0.2 100. 1000. 0.01",
70 | "Cu \"\" 1.0 0.01 0.2 100. 1000. 0.01",
71 | "Zn \"\" 1.0 0.01 0.2 100. 1000. 0.01",
72 | "*Redshift \"\" 0.0",\
73 | "Velocity \"km/s\" 0.0 -10.0 0. 0. 1e6 1e6",\
74 | "nL \"cm^-2\" 1e21 1e20 1e20 1e23 1e23 1e18")
75 |
76 |
77 | #"Density \"cm^-3\" 0.03 1e-3 1e-3 0.05 0.05 1e-3")
78 |
79 | def pyapecrs(engs, params, flux):
80 |
81 | """
82 | ACX2 model for data
83 |
84 | PARAMETERS
85 | ----------
86 | engs : list[float]
87 | The energy bin edges (from xspec)
88 | params : list[float]
89 | The parameter list. See acx2Info for definition
90 | flux : list[float]
91 | The array to fill with return values
92 |
93 | RETURNS
94 | -------
95 | None
96 | Fills out the flux array with photon cm3 s-1 bin-1, x1e10
97 |
98 | USAGE
99 | -----
100 | # load the model into XSPEC
101 | xspec.AllModels.addPyMod(pyapec, pyapecInfo, 'add')
102 | # make a model
103 | m = xspec.Model('pyapec')
104 | """
105 |
106 | # This is the call that will return everything. So set everything!
107 | ebins = numpy.array(engs)
108 | #print(ebins)
109 | #ebins = numpy.linspace(6.0,7.0,10000)
110 |
111 | elements = []
112 | for i in range(1,31): elements.append(i)
113 |
114 | if len(params)==6:
115 | # apec model
116 | abund=numpy.array(params[1])
117 | elements=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,\
118 | 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
119 | eloffset = 2
120 |
121 | elif len(params)==19:
122 | # apec model
123 | elements=[1,2,6,7,8,10,12,13,14,16,18,20,26,28]
124 | abund=params[1:15]
125 | eloffset = 15
126 |
127 | elif len(params)==35:
128 | # apec model
129 | elements=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\
130 | 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
131 | abund=params[1:31]
132 | eloffset = 31
133 |
134 |
135 | redshift = float(params[eloffset+0])
136 |
137 | broadening = float(params[eloffset+1])
138 |
139 | nL_integral = float(params[eloffset+2])
140 |
141 |
142 | # set energy bins, accounting for redshift
143 | cie_rs.set_response(ebins*(1.0+redshift), raw=True)
144 |
145 |
146 | # set abundance vector
147 | # abund = numpy.array(params[1])
148 | cie_rs.set_abund(elements, abund)
149 | cie_rs.set_eebrems(False)
150 |
151 | # set the response
152 | cie_rs.set_broadening(True, velocity_broadening=broadening)
153 |
154 |
155 |
156 | # get the spectrum
157 | spec = cie_rs.return_spectrum(params[0], N_e= nL_integral, Ab=abund, log_interp=False)
158 |
159 | # return the flux.
160 | flux[:] = spec*1e14
161 |
162 |
163 | def pyvapecrs(engs, params, flux):
164 | pyapecrs(engs, params, flux)
165 |
166 |
167 | def pyvvapecrs(engs, params, flux):
168 | pyapecrs(engs, params, flux)
169 |
170 |
171 |
172 |
173 | # this is how to import the models into pyxspec.
174 | xspec.AllModels.addPyMod(pyapecrs, pyrsapecInfo, 'add')
175 | xspec.AllModels.addPyMod(pyvapecrs, pyrsvapecInfo, 'add')
176 | xspec.AllModels.addPyMod(pyvvapecrs, pyrsvvapecInfo, 'add')
--------------------------------------------------------------------------------