diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index ad9a89721..873c9d0ba 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,18 +1,18 @@ -name: 'Close stale issues and PR' +name: Close stale issues and PR on: schedule: - - cron: '30 1 * * *' + - cron: 30 1 * * * jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-pr-message: 'This pull request will be closed in 14 days due to six months of inactivity unless the stale label or comment is removed.' - close-pr-message: 'This pull request was closed because it has had no activity for the past six months.' - days-before-pr-stale: 180 - days-before-pr-close: 15 + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-pr-message: This pull request will be closed in 14 days due to six months of inactivity unless the stale label or comment is removed. + close-pr-message: This pull request was closed because it has had no activity for the past six months. + days-before-pr-stale: 180 + days-before-pr-close: 15 # never close issues - days-before-close: -1 + days-before-close: -1 diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index a56ba59be..9fc2d1653 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -117,7 +117,7 @@ jobs: - name: Install language-pack-fr and tzdata run: sudo apt-get install graphviz pandoc - name: Build documentation - run: tox -e build_docs_nitpicky -- -q + run: tox -e build_docs -- -q codespell: name: codespell runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 44c5cf62c..dd222538c 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ instance/ # Sphinx documentation docs/_build/ +docs/api # PyBuilder target/ diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..d8c9bc431 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,13 @@ +version: 2 + +formats: +- htmlzip + +python: + version: '3.8' + install: + - requirements: requirements/install.txt + - requirements: requirements/docs.txt + - method: setuptools + path: . + system_packages: true diff --git a/.readthedocs.yml b/.readthedocs.yml deleted file mode 100644 index 215f29974..000000000 --- a/.readthedocs.yml +++ /dev/null @@ -1,11 +0,0 @@ -version: 2 - -formats: all - -python: - version: 3.8 - install: - - requirements: docs/requirements.txt - - method: setuptools - path: . - system_packages: true diff --git a/docs/_links.rst b/docs/_links.rst new file mode 100644 index 000000000..24aaf042d --- /dev/null +++ b/docs/_links.rst @@ -0,0 +1,25 @@ +.. _Astropy: https://www.astropy.org +.. _BibTeX format: https://www.bibtex.com/g/bibtex-format +.. _BibTeX: http://www.bibtex.org +.. _conda: https://docs.conda.io +.. _git: https://git-scm.com +.. _Hinode: https://www.nasa.gov/mission_pages/hinode/index.html +.. _Jupyter: https://jupyter.org +.. _matplotlib: https://matplotlib.org +.. _NumPy: https://numpy.org +.. _pip: https://pip.pypa.io +.. _pre-commit: https://pre-commit.com +.. _PyPI: https://pypi.org +.. _pytest: https://docs.pytest.org +.. _Python: https://www.python.org +.. _Read the Docs: https://readthedocs.org +.. _SciPy: https://scipy.org +.. _SolarSoft IDL: https://www.lmsal.com/solarsoft +.. _Sphinx: https://www.sphinx-doc.org +.. _SunPy: https://docs.sunpy.org/en/stable +.. _tox: https://tox.wiki/en/latest +.. _X-Ray Telescope: https://xrt.cfa.harvard.edu +.. _XRT: https://xrt.cfa.harvard.edu/ +.. _XRTpy's documentation: https://xrtpy.readthedocs.io/en/latest +.. _XRTpy's GitHub repository: https://github.com/HinodeXRT/xrtpy +.. _Zenodo: https://zenodo.org diff --git a/docs/_static/css/admonition_color_contrast.css b/docs/_static/css/admonition_color_contrast.css new file mode 100644 index 000000000..f91be52be --- /dev/null +++ b/docs/_static/css/admonition_color_contrast.css @@ -0,0 +1,144 @@ +/* + The following sections were adapted from the file + sphinx_rtd_theme_ext_color_contrast/_static/sphinx_rtd_theme_ext_color_contrast.css + in the following repository: + https://github.com/AaltoSciComp/sphinx_rtd_theme_ext_color_contrast + The license is in our licenses directory. + + These customizations will be able to be removed if sphinx_rtd_theme + defaults end up getting changed to meet accessibility guidelines. +*/ + + +/* warning */ +.wy-alert.wy-alert-warning .wy-alert-title, +.rst-content .wy-alert-warning.note .wy-alert-title, +.rst-content .attention .wy-alert-title, +.rst-content .caution .wy-alert-title, +.rst-content .wy-alert-warning.danger .wy-alert-title, +.rst-content .wy-alert-warning.error .wy-alert-title, +.rst-content .wy-alert-warning.hint .wy-alert-title, +.rst-content .wy-alert-warning.important .wy-alert-title, +.rst-content .wy-alert-warning.tip .wy-alert-title, +.rst-content .warning .wy-alert-title, +.rst-content .wy-alert-warning.seealso .wy-alert-title, +.rst-content .admonition-todo .wy-alert-title, +.rst-content .wy-alert-warning.admonition .wy-alert-title, +.wy-alert.wy-alert-warning .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-warning .admonition-title, +.rst-content .wy-alert-warning.note .admonition-title, +.rst-content .attention .admonition-title, +.rst-content .caution .admonition-title, +.rst-content .wy-alert-warning.danger .admonition-title, +.rst-content .wy-alert-warning.error .admonition-title, +.rst-content .wy-alert-warning.hint .admonition-title, +.rst-content .wy-alert-warning.important .admonition-title, +.rst-content .wy-alert-warning.tip .admonition-title, +.rst-content .warning .admonition-title, .rst-content +.wy-alert-warning.seealso .admonition-title, +.rst-content .admonition-todo .admonition-title, +.rst-content .wy-alert-warning.admonition .admonition-title { + background: #B15E16; +} + +/* important */ + +.wy-alert.wy-alert-success .wy-alert-title, +.rst-content .wy-alert-success.note .wy-alert-title, +.rst-content .wy-alert-success.attention .wy-alert-title, +.rst-content .wy-alert-success.caution .wy-alert-title, +.rst-content .wy-alert-success.danger .wy-alert-title, +.rst-content .wy-alert-success.error .wy-alert-title, +.rst-content .hint .wy-alert-title, +.rst-content .important .wy-alert-title, +.rst-content .tip .wy-alert-title, +.rst-content .wy-alert-success.warning .wy-alert-title, +.rst-content .wy-alert-success.seealso .wy-alert-title, +.rst-content .wy-alert-success.admonition-todo .wy-alert-title, +.rst-content .wy-alert-success.admonition .wy-alert-title, +.wy-alert.wy-alert-success .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-success .admonition-title, +.rst-content .wy-alert-success.note .admonition-title, +.rst-content .wy-alert-success.attention .admonition-title, +.rst-content .wy-alert-success.caution .admonition-title, +.rst-content .wy-alert-success.danger .admonition-title, +.rst-content .wy-alert-success.error .admonition-title, +.rst-content .hint .admonition-title, +.rst-content .important .admonition-title, +.rst-content .tip .admonition-title, +.rst-content .wy-alert-success.warning .admonition-title, +.rst-content .wy-alert-success.seealso .admonition-title, +.rst-content .wy-alert-success.admonition-todo .admonition-title, +.rst-content .wy-alert-success.admonition .admonition-title { + background: #12826C; +} + +/* seealso, note, etc */ + +.wy-alert.wy-alert-info .wy-alert-title, +.rst-content .note .wy-alert-title, +.rst-content .wy-alert-info.attention .wy-alert-title, +.rst-content .wy-alert-info.caution .wy-alert-title, +.rst-content .wy-alert-info.danger .wy-alert-title, +.rst-content .wy-alert-info.error .wy-alert-title, +.rst-content .wy-alert-info.hint .wy-alert-title, +.rst-content .wy-alert-info.important .wy-alert-title, +.rst-content .wy-alert-info.tip .wy-alert-title, +.rst-content .wy-alert-info.warning .wy-alert-title, +.rst-content .seealso .wy-alert-title, +.rst-content .wy-alert-info.admonition-todo .wy-alert-title, +.rst-content .wy-alert-info.admonition .wy-alert-title, +.wy-alert.wy-alert-info .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-info .admonition-title, +.rst-content .note .admonition-title, +.rst-content .wy-alert-info.attention .admonition-title, +.rst-content .wy-alert-info.caution .admonition-title, +.rst-content .wy-alert-info.danger .admonition-title, +.rst-content .wy-alert-info.error .admonition-title, +.rst-content .wy-alert-info.hint .admonition-title, +.rst-content .wy-alert-info.important .admonition-title, +.rst-content .wy-alert-info.tip .admonition-title, +.rst-content .wy-alert-info.warning .admonition-title, +.rst-content .seealso .admonition-title, +.rst-content .wy-alert-info.admonition-todo .admonition-title, +.rst-content .wy-alert-info.admonition .admonition-title { + background: #277CB4; +} + +/* error, danger */ + +.rst-content .danger .admonition-title, +.rst-content .danger .wy-alert-title, +.rst-content .error .admonition-title, +.rst-content .error .wy-alert-title, +.rst-content .wy-alert-danger.admonition-todo .admonition-title, +.rst-content .wy-alert-danger.admonition-todo .wy-alert-title, +.rst-content .wy-alert-danger.admonition .admonition-title, +.rst-content .wy-alert-danger.admonition .wy-alert-title, +.rst-content .wy-alert-danger.attention .admonition-title, +.rst-content .wy-alert-danger.attention .wy-alert-title, +.rst-content .wy-alert-danger.caution .admonition-title, +.rst-content .wy-alert-danger.caution .wy-alert-title, +.rst-content .wy-alert-danger.hint .admonition-title, +.rst-content .wy-alert-danger.hint .wy-alert-title, +.rst-content .wy-alert-danger.important .admonition-title, +.rst-content .wy-alert-danger.important .wy-alert-title, +.rst-content .wy-alert-danger.note .admonition-title, +.rst-content .wy-alert-danger.note .wy-alert-title, +.rst-content .wy-alert-danger.seealso .admonition-title, +.rst-content .wy-alert-danger.seealso .wy-alert-title, +.rst-content .wy-alert-danger.tip .admonition-title, +.rst-content .wy-alert-danger.tip .wy-alert-title, +.rst-content .wy-alert-danger.warning .admonition-title, +.rst-content .wy-alert-danger.warning .wy-alert-title, +.rst-content .wy-alert.wy-alert-danger .admonition-title, +.wy-alert.wy-alert-danger .rst-content .admonition-title, +.wy-alert.wy-alert-danger .wy-alert-title { + background: #e31704; +} + +/* Generic admonition titles */ + +.wy-alert-title, .rst-content .admonition-title { + background: #277CB4; +} diff --git a/docs/_static/css/plasmapy.css b/docs/_static/css/plasmapy.css new file mode 100644 index 000000000..b59e85f70 --- /dev/null +++ b/docs/_static/css/plasmapy.css @@ -0,0 +1,186 @@ +/* + This file contains styles rules for PlasmaPy's documentation, which + includes new rules as well as rules that override styles from the + Sphinx Read the Docs theme (sphinx_rtd_theme). + + The CSS style rule syntax is: + + selectors-list { + properties-list + } + + The code in selectors-list selects the patterns for the elements to be + styled. The code in properties-list sets the style of these elements. + The CSS rule to be applied is generally the one that has the most + specific selectors. + + For more information on CSS, go to: https://www.w3schools.com/css + + Most web browsers have inspection tools that help with adding new CSS + rules. Right-click or ctrl-click on an element of a website, and + choose "inspect" to see the HTML code along with CSS selectors and + properties. + + When creating a new rule, use increased specificity instead of + !important when possible. Using !important can make debugging more + difficult. Use relative units like rem (root font size) to help with + accessibility and scaling. Please add descriptive comments for new + rules that are understandable to someone who is unfamiliar with CSS. + + CSS files can be validated at: https://jigsaw.w3.org/css-validator +*/ + +/* ----------------------------------------------------------------------------- + * RTD Overrides + */ + +/* Style for toctree in a table */ +td .toctree-wrapper ul { + font-size: 16px; + line-height: 18px !important; + list-style: none !important; + margin-bottom: 0 !important; +} + +td .toctree-wrapper ul li { + list-style: none !important; + margin-left: 0 !important; +} + +/* Unordered list nested in ordered list */ +.section li ul { + margin-bottom: 12px !important; +} + +/* Add margin-bottom to inheritance diagrams */ +div.graphviz { + margin-bottom: 24px !important; +} + +/* + * Remove bottom margin for the autosummary table in a directive:option:: + * section + */ +.rst-content dl.rst table p, +.rst-content dl.std table p, +.rst-content dl.py table p { + margin-bottom: 0 !important; +} + +/* Remove excess bottom margin for table headings */ +.rst-content table.docutils thead p { + margin-bottom: 0; +} + +/* Remove excess bottom margin for for multiline table entries when using line-block */ +.rst-content table.docutils div.line-block { + margin-bottom: 0; +} + +/* Allow text wrapping for last column of a table. */ +.rst-content table.docutils td:last-child p { + white-space: normal; + line-height: 140%; +} + +/* Reduce top/bottom margin for equations in tables */ +table div.MathJax_Display { + margin: 0.5em 0; +} + +/* + * Adjustments to the Glossary styling + */ +dl.glossary dd ul { + margin-bottom: 12px !important; +} +dl.glossary dd { + margin-top: 4px; + margin-bottom: 18px; +} +dl.glossary dt { + margin-bottom: 2px; +} + +/* Styles for text in the footer chosen to improve contrast. */ + +footer p { + color: #141414; +} + +/* + Styles for hyperlinks. The colors must meet the WCAG AA standard + for contrast. Link colors can be tested for accessibility at: + https://webaim.org/resources/linkcontrastchecker +*/ + +div.wy-nav-content a:link { + color: #0069d6; +} +div.wy-nav-content a:visited { + color: #9151b6; +} +div.wy-nav-content a:hover { + text-decoration:underline; +} + +/* + The style for generic code literals, in particular text that is + enclosed in double back ticks in reST (e.g., ``make -j 32``). +*/ + +div.wy-nav-content .rst-content code.literal { + background-color: #f6f6f6; + color: #db2424; +} + +/* + The style for links to Python objects, in particular text enclosed in + single back ticks in reST (e.g., `~plasmapy.particles`). +*/ + +div.wy-nav-content .rst-content code.literal.xref { + color: #0069d6; + font-weight: bold; +} + +/* + The style for literal text that shows the location of a file, in + particular when used by the reST role :file: (e.g., + :file:`docs/_static/css/plasmapy.css`). +*/ +div.wy-nav-content .rst-content code.literal.file { + color: #b84d00; + background-color: #F9F1F0; +} + +/* ----------------------------------------------------------------------------- + * RTD layout styling additions + */ + +/* Style for module/index links in sidebar below the search field. */ +div.pkgnav { + color: white; + font-size: 1em; + margin-top: 12px; + text-align: center; +} + +div.pkgnav ul { + list-style: none; +} + +div.pkgnav ul li { + display: inline; +} + +div.pkgnav ul li a { + color: #f9f9f0; + margin: 0; + text-shadow: 0 0 1px rgba(0, 0, 0, 0.5); +} + +div.pkgnav ul li a:hover { + color: #f50404; + text-shadow: 0 0 1px rgba(255, 255, 255, 0.5); +} diff --git a/docs/_substitutions.rst b/docs/_substitutions.rst new file mode 100644 index 000000000..1e570ffe0 --- /dev/null +++ b/docs/_substitutions.rst @@ -0,0 +1,40 @@ +.. |bibliography| replace:: :ref:`bibliography`\ +.. |glossary| replace:: :ref:`glossary`\ +.. |inf| replace:: `~numpy.inf` +.. |minpython| replace:: 3.8 +.. |nan| replace:: `~numpy.nan` +.. |ndarray| replace:: :class:`~numpy.ndarray` +.. |Quantity| replace:: :class:`~astropy.units.Quantity` +.. |TimeDelta| replace:: :class:`~astropy.time.TimeDelta` +.. |Time| replace:: :class:`~astropy.time.Time` + +.. A workaround for nested inline literals so that the filename will get + formatted like a file but will be a link. In the text, these get used + with the syntax for a substitution followed by an underscore to + indicate that it's for a link: |docs/_static|_ + +.. For these workarounds, if the replacement is something in single back + ticks (e.g., `xarray`), then it should also be added to + nitpick_ignore_regex in docs/conf.py so that it doesn't get counted + as an error in a nitpicky doc build (e.g., tox -e doc_build_nitpicky). + +.. _`docs/_static`: https://github.com/PlasmaPy/PlasmaPy/tree/main/docs/_static +.. |docs/_static| replace:: :file:`docs/_static` + +.. _`docs/_static/css`: https://github.com/PlasmaPy/PlasmaPy/tree/main/docs/_static/css +.. |docs/_static/css| replace:: :file:`docs/_static/css` + +.. _`docs/api_static`: https://github.com/PlasmaPy/PlasmaPy/tree/main/docs/api_static +.. |docs/api_static| replace:: :file:`docs/api_static` + +.. _`docs/conf.py`: https://github.com/PlasmaPy/PlasmaPy/blob/main/docs/conf.py +.. |docs/conf.py| replace:: :file:`docs/conf.py` + +.. _`docs/glossary.rst`: https://github.com/PlasmaPy/PlasmaPy/blob/main/docs/glossary.rst +.. |docs/glossary.rst| replace:: :file:`docs/glossary.rst` + +.. _`docs/bibliography.bib`: https://github.com/PlasmaPy/PlasmaPy/blob/main/docs/bibliography.bib +.. |docs/bibliography.bib| replace:: :file:`docs/bibliography.bib` + +.. _`setup.cfg`: https://github.com/PlasmaPy/PlasmaPy/blob/main/setup.cfg +.. |setup.cfg| replace:: :file:`setup.cfg` diff --git a/docs/api_static/xrtpy.response.channel.rst b/docs/api_static/xrtpy.response.channel.rst new file mode 100644 index 000000000..be53692bd --- /dev/null +++ b/docs/api_static/xrtpy.response.channel.rst @@ -0,0 +1,8 @@ +:orphan: + +`xrtpy.response.channel` +======================== + +.. currentmodule:: xrtpy.response.channel + +.. automodapi:: xrtpy.response.channel diff --git a/docs/api_static/xrtpy.response.rst b/docs/api_static/xrtpy.response.rst new file mode 100644 index 000000000..80adc6faa --- /dev/null +++ b/docs/api_static/xrtpy.response.rst @@ -0,0 +1,8 @@ +:orphan: + +`xrtpy.response` +================ + +.. currentmodule:: xrtpy.response + +.. automodapi:: xrtpy.response diff --git a/docs/api_static/xrtpy.rst b/docs/api_static/xrtpy.rst new file mode 100644 index 000000000..91fb98a50 --- /dev/null +++ b/docs/api_static/xrtpy.rst @@ -0,0 +1,8 @@ +:orphan: + +`xrtpy` +======= + +.. currentmodule:: xrtpy + +.. automodapi:: xrtpy diff --git a/docs/bibliography.bib b/docs/bibliography.bib new file mode 100644 index 000000000..14a6ba443 --- /dev/null +++ b/docs/bibliography.bib @@ -0,0 +1,40 @@ +@ARTICLE{culhane:2007, + author = {{Culhane}, J.~L. and {Harra}, L.~K. and {James}, A.~M. and {Al-Janabi}, K. and {Bradley}, L.~J. and {Chaudry}, R.~A. and {Rees}, K. and {Tandy}, J.~A. and {Thomas}, P. and {Whillock}, M.~C.~R. and {Winter}, B. and {Doschek}, G.~A. and {Korendyke}, C.~M. and {Brown}, C.~M. and {Myers}, S. and {Mariska}, J. and {Seely}, J. and {Lang}, J. and {Kent}, B.~J. and {Shaughnessy}, B.~M. and {Young}, P.~R. and {Simnett}, G.~M. and {Castelli}, C.~M. and {Mahmoud}, S. and {Mapson-Menard}, H. and {Probyn}, B.~J. and {Thomas}, R.~J. and {Davila}, J. and {Dere}, K. and {Windt}, D. and {Shea}, J. and {Hagood}, R. and {Moye}, R. and {Hara}, H. and {Watanabe}, T. and {Matsuzaki}, K. and {Kosugi}, T. and {Hansteen}, V. and {Wikstol}, {\O}.}, + title = "{The EUV Imaging Spectrometer for Hinode}", + journal = "{Solar Physics}", + year = 2007, + volume = {243}, + number = {1}, + pages = {19-61}, + doi = {10.1007/s01007-007-0293-1} +} +@ARTICLE{golub:2007, + author = {{Golub}, L. and {Deluca}, E. and {Austin}, G. and {Bookbinder}, J. and {Caldwell}, D. and {Cheimets}, P. and {Cirtain}, J. and {Cosmo}, M. and {Reid}, P. and {Sette}, A. and {Weber}, M. and {Sakao}, T. and {Kano}, R. and {Shibasaki}, K. and {Hara}, H. and {Tsuneta}, S. and {Kumagai}, K. and {Tamura}, T. and {Shimojo}, M. and {McCracken}, J. and {Carpenter}, J. and {Haight}, H. and {Siler}, R. and {Wright}, E. and {Tucker}, J. and {Rutledge}, H. and {Barbera}, M. and {Peres}, G. and {Varisco}, S.}, + title = "{The X-Ray Telescope (XRT) for the Hinode Mission}", + journal = "{Solar Physics}", + year = 2007, + volume = {243}, + number = {1}, + pages = {63-86}, + doi = {10.1007/s11207-007-0182-1} +} +@ARTICLE{kosugi:2007, + author = {{Kosugi}, T. and {Matsuzaki}, K. and {Sakao}, T. and {Shimizu}, T. and {Sone}, Y. and {Tachikawa}, S. and {Hashimoto}, T. and {Minesugi}, K. and {Ohnishi}, A. and {Yamada}, T. and {Tsuneta}, S. and {Hara}, H. and {Ichimoto}, K. and {Suematsu}, Y. and {Shimojo}, M. and {Watanabe}, T. and {Shimada}, S. and {Davis}, J.~M. and {Hill}, L.~D. and {Owens}, J.~K. and {Title}, A.~M. and {Culhane}, J.~L. and {Harra}, L.~K. and {Doschek}, G.~A. and {Golub}, L.}, + title = "{The Hinode (Solar-B) Mission: An Overview}", + journal = "{Solar Physics}", + year = 2007, + volume = {243}, + number = {1}, + pages = {3-17}, + doi = {10.1007/s11207-007-9014-6} +} +@ARTICLE{tsuneta:2008, + author = {{Tsuneta}, S. and {Ichimoto}, K. and {Katsukawa}, Y. and {Nagata}, S. and {Otsubo}, M. and {Shimizu}, T. and {Suematsu}, Y. and {Nakagiri}, M. and {Noguchi}, M. and {Tarbell}, T. and {Title}, A. and {Shine}, R. and {Rosenberg}, W. and {Hoffmann}, C. and {Jurcevich}, B. and {Kushner}, G. and {Levay}, M. and {Lites}, B. and {Elmore}, D. and {Matsushita}, T. and {Kawaguchi}, N. and {Saito}, H. and {Mikami}, I. and {Hill}, L.~D. and {Owens}, J.~K.}, + title = "{The Solar Optical Telescope for the Hinode Mission: An Overview}", + journal = "{Solar Physics}", + year = 2008, + volume = {249}, + number = {2}, + pages = {167-196}, + doi = {10.1007/s11207-008-9174-z} +} diff --git a/docs/bibliography.rst b/docs/bibliography.rst new file mode 100644 index 000000000..54b204ac0 --- /dev/null +++ b/docs/bibliography.rst @@ -0,0 +1,10 @@ +.. _bibliography: + +############ +Bibliography +############ + +.. The bibliography is built from references contained within + bibliography.bib. Add new references to bibliography.bib. + +.. bibliography:: diff --git a/docs/conf.py b/docs/conf.py index 28894cc18..2bed0eabf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,18 +4,16 @@ # full list see the documentation: # http://www.sphinx-doc.org/en/master/config +import os + from datetime import datetime +from sphinx.application import Sphinx # -- Project information ----------------------------------------------------- project = "xrtpy" author = "Joy Velasquez and Nick Murphy" - -# TODO: Simplify the copyright year commands in 2022 -current_year = datetime.utcnow().year -copyright_years = str(current_year) if current_year == 2021 else f"2021–{current_year}" - -copyright = f"{copyright_years}, {author}" +copyright = f"2015–{datetime.utcnow().year}, {author}" # The full version, including alpha/beta/rc tags # from xrtpy import __version__ @@ -29,53 +27,178 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ + "sphinx_automodapi.automodapi", "sphinx.ext.autodoc", "sphinx.ext.intersphinx", - "sphinx.ext.todo", - "sphinx.ext.coverage", - "sphinx.ext.inheritance_diagram", - "sphinx.ext.viewcode", - "sphinx.ext.napoleon", - "sphinx.ext.doctest", + "sphinx.ext.graphviz", "sphinx.ext.mathjax", - "sphinx_automodapi.automodapi", - "sphinx_automodapi.smart_resolver", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "nbsphinx", + "sphinx_copybutton", + "sphinx_gallery.load_style", + "IPython.sphinxext.ipython_console_highlighting", + "sphinx_changelog", + "sphinxcontrib.bibtex", + "hoverxref.extension", ] +bibtex_bibfiles = ["bibliography.bib"] +bibtex_default_style = "plain" +bibtex_reference_style = "author_year" +bibtex_cite_id = "{key}" + # Add any paths that contain templates here, relative to this directory. # templates_path = ['_templates'] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +exclude_patterns = [ + ".DS_Store", + "_build", + "_links.rst", + "_substitutions.rst", + "Thumbs.db", +] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: source_suffix = ".rst" -# The master toctree document. -master_doc = "index" +# The root toctree document. +root_doc = "index" # -- Options for intersphinx extension --------------------------------------- intersphinx_mapping = { - "python": ("https://docs.python.org/3", None), + "astropy": ("https://docs.astropy.org/en/stable/", None), + "ndcube": ("https://docs.sunpy.org/projects/ndcube/en/stable/", None), "numpy": ("https://numpy.org/doc/stable/", None), + "python": ("https://docs.python.org/3", None), "scipy": ("https://docs.scipy.org/doc/scipy/reference/", None), - "pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None), - "astropy": ("https://docs.astropy.org/en/stable/", None), "sunpy": ("https://docs.sunpy.org/en/stable/", None), - "ndcube": ("https://docs.sunpy.org/projects/ndcube/en/stable/", None), } +hoverxref_intersphinx = [ + "astropy", + "ndcube", + "numpy", + "python", + "scipy", + "sunpy", +] + +autoclass_content = "both" +autodoc_typehints_format = "short" + # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = "bizstyle" +html_theme = "sphinx_rtd_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ['_static'] +html_static_path = ["_static"] + +linkcheck_allowed_redirects = { + r"https://doi\.org/.+": r"https://.+", # DOI links are more persistent + r"https://docs.+\.org": r"https://docs.+\.org/en/.+", + r"https://docs.+\.io": r"https://docs.+\.io/en/.+", + r"https://docs.+\.com": r"https://docs.+\.com/en/.+", + r"https://docs.+\.dev": r"https://docs.+\.dev/en/.+", + r"https://.+\.readthedocs\.io": r"https://.+\.readthedocs\.io/en/.+", + r"https://.+/github\.io": r"https://.+/github\.io/en/.+", + r"https://pip\.pypa\.io": r"https://pip\.pypa\.io/en/.+", + r"https://www.python.org/dev/peps/pep.+": "https://peps.python.org/pep.+", +} + +linkcheck_anchors = True +linkcheck_anchors_ignore = [ + "/room", + r".+openastronomy.+", + "L[0-9].+", + "!forum/plasmapy", +] + +# Use a code highlighting style that meets the WCAG AA contrast standard +pygments_style = "default" + +# adapted from sphinx-hoverxref conf.py +if os.environ.get("READTHEDOCS"): + # Building on Read the Docs + hoverxref_api_host = "https://readthedocs.org" + + if os.environ.get("PROXIED_API_ENDPOINT"): + # Use the proxied API endpoint + # - A RTD thing to avoid a CSRF block when docs are using a + # custom domain + hoverxref_api_host = "/_" + +hoverxref_tooltip_maxwidth = 600 # RTD main window is 696px +hoverxref_auto_ref = True +hoverxref_mathjax = True +hoverxref_sphinxtabs = True + +# hoverxref has to be applied to these +hoverxref_domains = ["py", "cite"] +hoverxref_roles = ["confval", "term"] + +hoverxref_role_types = { + # roles with cite domain + "p": "tooltip", + "t": "tooltip", + # + # roles with py domain + "attr": "tooltip", + "class": "tooltip", + "const": "tooltip", + "data": "tooltip", + "exc": "tooltip", + "func": "tooltip", + "meth": "tooltip", + "mod": "tooltip", + "obj": "tooltip", + # + # roles with std domain + "confval": "tooltip", + "hoverxref": "tooltip", + "ref": "tooltip", + "term": "tooltip", +} + +# Specify patterns to ignore when doing a nitpicky documentation build. + +python_role = "py:.*" + +nitpick_ignore_regex = [ + (python_role, "and"), + (python_role, "array .*"), + (python_role, "array_like"), + (python_role, "callable"), + (python_role, "function"), + (python_role, ".*integer.*"), + (python_role, "iterable"), + (python_role, "key"), + (python_role, "keyword-only"), + (python_role, ".* object"), + (python_role, "optional"), + (python_role, "or"), + (python_role, ".*real number.*"), + (python_role, ".*Unit.*"), +] + +# This is added to the end of RST files — a good place to put substitutions to +# be used globally. +rst_epilog = "" +for epilog_file in ["_links.rst", "_substitutions.rst"]: + with open(epilog_file) as file: + rst_epilog += file.read() + + +def setup(app: Sphinx) -> None: + app.add_config_value("revision", "", True) + app.add_css_file("css/admonition_color_contrast.css") + app.add_css_file("css/plasmapy.css", priority=600) diff --git a/docs/contributing/data_from_idl.rst b/docs/contributing/data_from_idl.rst new file mode 100644 index 000000000..64d44d510 --- /dev/null +++ b/docs/contributing/data_from_idl.rst @@ -0,0 +1,7 @@ +.. _release guide: + +******************************** +Updating Data from SolarSoft IDL +******************************** + +This page has not yet been written. diff --git a/docs/contributing/index.rst b/docs/contributing/index.rst new file mode 100644 index 000000000..fe4cb6592 --- /dev/null +++ b/docs/contributing/index.rst @@ -0,0 +1,13 @@ +.. _contributor guide: + +***************** +Contributor Guide +***************** + +.. toctree:: + :maxdepth: 3 + + install_dev + workflow + data_from_idl + release_guide diff --git a/docs/contributing/install_dev.rst b/docs/contributing/install_dev.rst new file mode 100644 index 000000000..c20a0b1f5 --- /dev/null +++ b/docs/contributing/install_dev.rst @@ -0,0 +1,7 @@ +.. _installation for development: + +**************************** +Installation for Development +**************************** + +This page has not yet been written. diff --git a/docs/contributing/release_guide.rst b/docs/contributing/release_guide.rst new file mode 100644 index 000000000..2f51004ae --- /dev/null +++ b/docs/contributing/release_guide.rst @@ -0,0 +1,7 @@ +.. _release guide: + +************* +Release Guide +************* + +This page has not yet been written. diff --git a/docs/contributing/workflow.rst b/docs/contributing/workflow.rst new file mode 100644 index 000000000..14562f10e --- /dev/null +++ b/docs/contributing/workflow.rst @@ -0,0 +1,7 @@ +.. _contribution workflow: + +********************* +Contribution Workflow +********************* + +This page has not yet been written. diff --git a/docs/examples.rst b/docs/examples.rst new file mode 100644 index 000000000..ef1e018d6 --- /dev/null +++ b/docs/examples.rst @@ -0,0 +1,16 @@ +Examples +======== + +Here we catalog all the example Jupyter notebooks that have been created for +the various functionality contained in `xrtpy`. + +.. contents:: + :local: + +Getting started +--------------- + +.. nbgallery:: + :glob: + + notebooks/getting_started/* diff --git a/docs/getting_started.rst b/docs/getting_started.rst new file mode 100644 index 000000000..67fecf76d --- /dev/null +++ b/docs/getting_started.rst @@ -0,0 +1,8 @@ +Getting Started +=============== + +This page includes example notebooks intended for new users of `xrtpy`. + +.. nbgallery:: + + notebooks/getting_started/units diff --git a/docs/glossary.rst b/docs/glossary.rst new file mode 100644 index 000000000..69d81ce1b --- /dev/null +++ b/docs/glossary.rst @@ -0,0 +1,10 @@ +.. currentmodule:: xrtpy + +.. _glossary: + +******** +Glossary +******** + +.. glossary:: + :sorted: diff --git a/docs/index.rst b/docs/index.rst index 35fdfa0fe..9d6798984 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,14 +1,26 @@ -xrtpy Documentation -------------------- +:tocdepth: 2 -This is the documentation for xrtpy: a Python package being developed -for the analysis of observations made by the X-Ray Telescope (XRT) on -the *Hinode* spacecraft. +.. _xrtpy-documentation: + +################### +XRTpy Documentation +################### + +This is the documentation for `xrtpy`: a Python_ package being developed +for the analysis of observations made by the `X-Ray Telescope`_ (XRT) +:cite:p:`golub:2007` on the Hinode_ spacecraft :cite:p:`kosugi:2007`. .. toctree:: :maxdepth: 2 :caption: Contents: + install + getting_started + examples + bibliography + glossary + contributing/index + Indices and tables ================== diff --git a/docs/install.rst b/docs/install.rst new file mode 100644 index 000000000..5d23de905 --- /dev/null +++ b/docs/install.rst @@ -0,0 +1,233 @@ +.. _xrtpy-install: + +**************** +Installing XRTpy +**************** + +.. important:: + + These instructions were written in preparation for the initial + release of `xrtpy` which has not yet happened. At present, `xrtpy` is + not able to be installed via ``pip`` from PyPI_, ``conda``, or + Anaconda Navigator. No official releases are available on Zenodo or + GitHub. + +.. .. note:: + If you would like to contribute to XRTpy, please refer to the + instructions on :ref:`installing XRTpy for development + `. + +.. contents:: Contents + :local: + +Installing Python +================= + +XRTpy requires Python_ |minpython| or newer. If you do not have Python_ +installed already, here are the instructions to `download Python`_ and +install it. + +.. tip:: + + New versions of Python_ are released annually in October, and it can + take a few months for the scientific Python ecosystem to catch up. If + you have trouble installing `xrtpy` on the most recent Python_ + version between October and ∼December, then try installing it on the + second most recent version. + +.. _install-pip: + +Installing XRTpy with pip +============================ + +To install the most recent release of `xrtpy` on PyPI_ with pip_ into +an existing Python_ |minpython|\ + environment on macOS or Linux, open a +terminal and run: + +.. code-block:: bash + + python -m pip install xrtpy + +On some systems, it might be necessary to specify the Python_ version +number by using ``python3``, ``python3.8``, ``python3.9``, or +``python3.10`` instead of ``python``. + +To install XRTpy on Windows, run: + +.. code-block:: bash + + py -3.10 -m pip install xrtpy + +The version of Python_ may be changed from ``3.10`` to another supported +Python |minpython|\ + release that has been installed on your computer. + +For more detailed information, please refer to this tutorial on +`installing packages`_. + +.. _install-conda: + +Installing Xrtpy with Conda +============================== + +Conda_ is a package management system and environment manager that is +commonly used in the scientific Python_ ecosystem. Conda_ lets us create +and switch between Python_ environments that are isolated from each +other and the system installation. Conda_ can also be used for packages +written in languages other than Python_. + +After `installing Conda`_ or miniconda_, `xrtpy` can be installed +into an activated Conda_ environment by opening a terminal and running: + +.. code-block:: bash + + conda install -c conda-forge xrtpy + +Here ``-c conda-forge`` indicates that `xrtpy` should be installed +from the conda-forge_ channel. + +To install `xrtpy` into another existing Conda_ environment, append +:samp:`-n {env_name}` to the previous command, where :samp:`{env_name}` +is replaced with the name of the environment. + +To create a new environment with `xrtpy` installed in it, run: + +.. code-block:: bash + + conda create -n env_name -c conda-forge xrtpy + +where :samp:`{env_name}` is replaced by the name of the environment. To +activate this environment, run: + +.. code-block:: bash + + conda activate env_name + +To update `xrtpy` to the most recent version within a currently +activated Conda_ environment, run: + +.. code-block:: bash + + conda update xrtpy + +.. tip:: + + Creating a Conda_ environment can sometimes take a few minutes. If it + takes longer than that, try updating to the newest version of Conda_ + with ``conda update conda`` or checking out these tips for + `improving Conda performance`_. + +Installing XRTpy with Anaconda Navigator +=========================================== + +.. note:: + + This section contains instructions on how to install XRTpy with + `Anaconda Navigator`_ at the time of writing. For the most up-to-date + information, please go to the official documentation on `installing + Anaconda Navigator`_ and `managing packages`_. + +`Anaconda Navigator`_ is a graphical user interface (GUI) for Conda_ +that can be used to install Python packages. It is installed +automatically with newer versions of Conda_. If you are using Miniconda_ +or a different Conda_ environment, you can install it with +``conda install anaconda-navigator``. After that it can be opened by +entering ``anaconda-navigator`` in the terminal. + +First, go to the :guilabel:`Environments` tab and select +:guilabel:`Channels`. If ``conda-forge`` is not listed, then go to +:guilabel:`Add`, enter ``https://conda.anaconda.org/conda-forge``, and +click on :guilabel:`Update channels` and then :guilabel:`Update index`. + +.. Is conda-forge now being added by default? +.. Is clicking on `Update index` actually necessary? + +Next, while on the :guilabel:`Environments` tab, select the environment +that you would like to install `xrtpy` in. The default is generally +``base (root)``. Optionally, you may select :guilabel:`Create` to start +a new environment. In the search bar, enter ``xrtpy``. Click on the +checkbox next to ``xrtpy``, and select :guilabel:`Apply` to begin the +installation process. + +To test the installation, click on the :guilabel:`▶` icon that should be +present next to the activated environment, and select +:guilabel:`Open terminal`. Enter ``python`` in the terminal, and then +``import xrtpy`` to make sure it works. + +Installing XRTpy from source code +==================================== + +Obtaining official releases +--------------------------- + +A ZIP_ file containing the source code for official releases of +`xrtpy` can be obtained `from PyPI`_ or `from Zenodo`_. + +Alternatively, official releases can be downloaded from the +releases_ page on `XRTpy's GitHub repository`_. + +Obtaining source code from GitHub +--------------------------------- + +If you have git_ installed on your computer, you may clone `XRTpy's +GitHub repository`_ and access the source code from the most recent +development version by running: + +.. code:: bash + + git clone https://github.com/xrtpy/xrtpy.git + +The repository will be cloned inside a new subdirectory called +:file:`xrtpy`. + +If you do not have git_ installed on your computer, then you may download +the most recent source code from `XRTpy's GitHub repository`_ by +going to :guilabel:`Code` and selecting :guilabel:`Download ZIP`. +`Unzipping `__ the file will +create a subdirectory called :file:`XRTpy` that contains the source +code. + +Building and installing +----------------------- + +To install the downloaded version of `xrtpy`, enter the :file:`xrtpy` +directory and run: + +.. code:: bash + + pip install . + +If you expect to occasionally edit the source code, instead run: + +.. code:: bash + + pip install -e .[developer] + +The ``-e`` flag makes the installation editable and ``[developer]`` +indicates that all of the dependencies needed for developing XRTpy +will be installed. + +.. note:: + + If you noticed any places where the installation instructions could + be improved or have become out of date, please create an issue on + `XRTpy's GitHub repository`_. It would really help! + +.. .. tip:: + The :ref:`contributing-to-xrtpy` guide has instructions on how to + fork a repository and create branches so that you may make + contributions via pull requests. + +.. _Anaconda Navigator: https://www.anaconda.com/products/individual +.. _clone a repository using SSH: https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-ssh-urls +.. _conda-forge: https://conda-forge.org +.. _download Python: https://www.python.org/downloads/ +.. _from PyPI: https://pypi.org/project/xrtpy +.. _from Zenodo: https://doi.org/10.5281/zenodo.1436011 +.. _improving Conda performance: https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/conda-performance.html#improving-conda-performance +.. _installing Anaconda Navigator: https://docs.anaconda.com/anaconda/navigator/install/ +.. _installing Conda: https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html +.. _installing packages: https://packaging.python.org/en/latest/tutorials/installing-packages/#installing-from-vcs +.. _managing packages: https://docs.anaconda.com/anaconda/navigator/tutorials/manage-packages/#installing-a-package +.. _miniconda: https://docs.conda.io/en/latest/miniconda.html +.. _releases: https://github.com/xrtpy/xrtpy/releases +.. _ZIP: https://en.wikipedia.org/wiki/ZIP_(file_format) diff --git a/docs/notebooks/getting_started/units.ipynb b/docs/notebooks/getting_started/units.ipynb new file mode 100644 index 000000000..0c43836cf --- /dev/null +++ b/docs/notebooks/getting_started/units.ipynb @@ -0,0 +1,724 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6e8f0d92", + "metadata": {}, + "source": [ + "# Using Astropy Units" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2751e56", + "metadata": { + "nbsphinx": "hidden" + }, + "outputs": [], + "source": [ + "%xmode minimal" + ] + }, + { + "cell_type": "markdown", + "id": "c566fe1c", + "metadata": {}, + "source": [ + "In scientific computing, we often represent physical quantities as numbers." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ee456b33", + "metadata": {}, + "outputs": [], + "source": [ + "distance_in_miles = 50\n", + "time_in_hours = 2\n", + "velocity_in_mph = distance_in_miles / time_in_hours\n", + "print(velocity_in_mph)" + ] + }, + { + "cell_type": "markdown", + "id": "93658d4f", + "metadata": {}, + "source": [ + "[astropy.units]: https://docs.astropy.org/en/stable/units/index.html\n", + "[xrtpy]: https://xrtpy.readthedocs.io/en/latest\n", + "\n", + "Representing a physical quantity as a number has risks. We might unknowingly perform operations with different units, like `time_in_seconds + time_in_hours`. We might even accidentally perform operations with physically incompatible units, like `length + time`, without catching our mistake. We can avoid these problems by using a units package.\n", + "\n", + "This notebook introduces [astropy.units] with an emphasis on the functionality needed to work with [xrtpy]. We typically import this subpackage as `u`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8c20320a", + "metadata": {}, + "outputs": [], + "source": [ + "import astropy.units as u" + ] + }, + { + "cell_type": "markdown", + "id": "ad28288e", + "metadata": {}, + "source": [ + "## Contents\n", + "\n", + "1. [Unit basics](#Unit-basics)\n", + "2. [Unit operations](#Unit-operations) \n", + "3. [Unit conversations](#Unit-conversions)\n", + "4. [Detaching units and values](#Detaching-units-and-values)\n", + "5. [Equivalencies](#Equivalencies)\n", + "6. [Physical constants](#Physical-constants)\n", + "7. [Optimizing unit operations](#Optimizing-unit-operations)\n", + "8. [Physical Types](#Physical-types)" + ] + }, + { + "cell_type": "markdown", + "id": "a9fad673", + "metadata": {}, + "source": [ + "## Unit basics\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "e9ccbb06", + "metadata": {}, + "source": [ + "We can create a physical quantity by multiplying or dividing a number or array with a unit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8437650a", + "metadata": {}, + "outputs": [], + "source": [ + "distance = 60 * u.km\n", + "print(distance)" + ] + }, + { + "cell_type": "markdown", + "id": "ccc6659f", + "metadata": {}, + "source": [ + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "This operation creates a [Quantity]: a number, sequence, or array that has been assigned a physical unit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a6354b93", + "metadata": {}, + "outputs": [], + "source": [ + "type(distance)" + ] + }, + { + "cell_type": "markdown", + "id": "744a9b01", + "metadata": {}, + "source": [ + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "We can also create an object by using the [Quantity] class itself." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d2bb681", + "metadata": {}, + "outputs": [], + "source": [ + "time = u.Quantity(120, u.min)" + ] + }, + { + "cell_type": "markdown", + "id": "1bb28951", + "metadata": {}, + "source": [ + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "We can create [Quantity] objects with compound units." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4932159b", + "metadata": {}, + "outputs": [], + "source": [ + "88 * u.imperial.mile / u.hour" + ] + }, + { + "cell_type": "markdown", + "id": "9cc9adba", + "metadata": {}, + "source": [ + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "We can even create [Quantity] objects that are explicitly dimensionless." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09e9752c", + "metadata": {}, + "outputs": [], + "source": [ + "3 * u.dimensionless_unscaled" + ] + }, + { + "cell_type": "markdown", + "id": "4cffc8a0", + "metadata": {}, + "source": [ + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "We can also create a [Quantity] based off of a NumPy array or a list." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3235d80", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "np.array([2.5, 3.2, 1.1]) * u.kg" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a686fd93", + "metadata": {}, + "outputs": [], + "source": [ + "[2, 3, 4] * u.m / u.s" + ] + }, + { + "cell_type": "markdown", + "id": "a60e9ea9", + "metadata": {}, + "source": [ + "## Unit operations\n", + "\n", + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "Operations between [Quantity] objects handle unit conversions automatically. We can add [Quantity] objects together as long as their units have the same physical type." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65e08284", + "metadata": {}, + "outputs": [], + "source": [ + "1 * u.m + 25 * u.cm" + ] + }, + { + "cell_type": "markdown", + "id": "edb43067", + "metadata": {}, + "source": [ + "Units get handled automatically during operations like multiplication, division, and exponentiation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c36788db", + "metadata": {}, + "outputs": [], + "source": [ + "velocity = distance / time\n", + "print(velocity)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "04b48a57", + "metadata": {}, + "outputs": [], + "source": [ + "area = distance**2\n", + "print(area)" + ] + }, + { + "cell_type": "markdown", + "id": "98331629", + "metadata": {}, + "source": [ + "Attempting an operation between physically incompatible units gives us an error, which we can use to find bugs in our code." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0877feb6", + "metadata": { + "tags": [ + "raises-exception" + ] + }, + "outputs": [], + "source": [ + "3 * u.m + 3 * u.s" + ] + }, + { + "cell_type": "markdown", + "id": "4f0c461e", + "metadata": {}, + "source": [ + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "[numpy.ndarray]: https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html\n", + "\n", + "[Quantity] objects behave very similarly to NumPy arrays because [Quantity] is a subclass of [numpy.ndarray]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59389429", + "metadata": {}, + "outputs": [], + "source": [ + "balmer_series = [656.279, 486.135, 434.0472, 410.1734] * u.nm\n", + "Hα = balmer_series[0]\n", + "print(Hα)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a6545132", + "metadata": {}, + "outputs": [], + "source": [ + "np.max(balmer_series)" + ] + }, + { + "cell_type": "markdown", + "id": "e1bb9434", + "metadata": {}, + "source": [ + "[NumPy]: https://numpy.org/\n", + "[SciPy]: https://scipy.org/\n", + "\n", + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "[Quantity objects lose their units with some operations]: https://docs.astropy.org/en/stable/known_issues.html#quantities-lose-their-units-with-some-operations\n", + "\n", + "Most frequently encountered [NumPy] and [SciPy] functions can be used with [Quantity] objects. However, [Quantity objects lose their units with some operations]. " + ] + }, + { + "cell_type": "markdown", + "id": "b910a84b", + "metadata": {}, + "source": [ + "## Unit conversions\n", + "\n", + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "[to]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity.to\n", + "\n", + "The [to] method allows us to convert a [Quantity] to different units of the same physical type. This method accepts strings that represent a unit (including compound units) or a unit object." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "80f4f133", + "metadata": {}, + "outputs": [], + "source": [ + "velocity.to(\"m/s\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21c46ef1", + "metadata": {}, + "outputs": [], + "source": [ + "velocity.to(u.m / u.s)" + ] + }, + { + "cell_type": "markdown", + "id": "c1e742ca", + "metadata": {}, + "source": [ + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "[si]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity.si\n", + "[cgs]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity.cgs\n", + "\n", + "The [si] and [cgs] attributes convert the [Quantity] to SI or CGS units, respectively. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "02bda4d2", + "metadata": {}, + "outputs": [], + "source": [ + "velocity.si" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "560a0cfe", + "metadata": {}, + "outputs": [], + "source": [ + "velocity.cgs" + ] + }, + { + "cell_type": "markdown", + "id": "1429d5a2", + "metadata": {}, + "source": [ + "## Detaching units and values\n", + "\n", + "[value]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity.value \n", + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "The [value] attribute of a [Quantity] provides the number (as a NumPy scalar) or NumPy array without the unit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24e8403c", + "metadata": {}, + "outputs": [], + "source": [ + "time.value" + ] + }, + { + "cell_type": "markdown", + "id": "4c6c027b", + "metadata": {}, + "source": [ + "[unit]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity.unit\n", + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "The [unit] attribute of a [Quantity] provides the unit without the value." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c41a2fa", + "metadata": {}, + "outputs": [], + "source": [ + "time.unit" + ] + }, + { + "cell_type": "markdown", + "id": "be0c5349", + "metadata": {}, + "source": [ + "## Equivalencies" + ] + }, + { + "cell_type": "markdown", + "id": "07c3b9c1", + "metadata": {}, + "source": [ + "[electron-volt]: https://en.wikipedia.org/wiki/Electronvolt\n", + "[Boltzmann constant]: https://en.wikipedia.org/wiki/Boltzmann_constant\n", + "\n", + "Occasionally the [electron-volt] (eV) as a unit of temperature. This is a shortcut for describing the thermal energy per particle, or more accurately the temperature multiplied by the [Boltzmann constant], $k_B$. Because an electron-volt is a unit of energy rather than temperature, we cannot directly convert electron-volts to kelvin." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b6fafd6", + "metadata": { + "tags": [ + "raises-exception" + ] + }, + "outputs": [], + "source": [ + "u.eV.to(\"K\")" + ] + }, + { + "cell_type": "markdown", + "id": "9299c8a1", + "metadata": {}, + "source": [ + "[astropy.units]: https://docs.astropy.org/en/stable/units/index.html\n", + "[equivalencies]: https://docs.astropy.org/en/stable/units/equivalencies.html\n", + "[temperature_energy()]: https://docs.astropy.org/en/stable/units/equivalencies.html#temperature-energy-equivalency\n", + "\n", + "To handle non-standard unit conversions, [astropy.units] allows the use of [equivalencies]. The conversion from eV to K can be done by using the [temperature_energy()] equivalency." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "afac5b4a", + "metadata": {}, + "outputs": [], + "source": [ + "(1 * u.eV).to(\"K\", equivalencies=u.temperature_energy())" + ] + }, + { + "cell_type": "markdown", + "id": "b4c492cc", + "metadata": {}, + "source": [ + "[dimensionless_angles()]: https://docs.astropy.org/en/stable/api/astropy.units.equivalencies.dimensionless_angles.html#dimensionless-angles\n", + "\n", + "[frequency]: https://en.wikipedia.org/wiki/Frequency\n", + "[angular frequency]: https://en.wikipedia.org/wiki/Angular_frequency\n", + "\n", + "Radians are treated dimensionlessly when the [dimensionless_angles()] equivalency is in effect. Note that this equivalency does not account for the multiplicative factor of $2π$ that is used when converting between [frequency] and [angular frequency]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9735710b", + "metadata": {}, + "outputs": [], + "source": [ + "(3.2 * u.rad / u.s).to(\"1 / s\", equivalencies=u.dimensionless_angles())" + ] + }, + { + "cell_type": "markdown", + "id": "7ec6d857", + "metadata": {}, + "source": [ + "## Physical constants" + ] + }, + { + "cell_type": "markdown", + "id": "b714de6a", + "metadata": {}, + "source": [ + "[astropy.constants]: https://docs.astropy.org/en/stable/constants/index.html\n", + "\n", + "We can use [astropy.constants] to access the most commonly needed physical constants." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "746a79a7", + "metadata": {}, + "outputs": [], + "source": [ + "from astropy.constants import c, e, eps0, hbar, k_B, mu0\n", + "\n", + "print(c)" + ] + }, + { + "cell_type": "markdown", + "id": "c3ee9feb", + "metadata": {}, + "source": [ + "[Constant]: https://docs.astropy.org/en/stable/api/astropy.constants.Constant.html#astropy.constants.Constant\n", + "[Quantity]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "[u.temperature_energy()]: https://docs.astropy.org/en/stable/units/equivalencies.html#temperature-energy-equivalency\n", + "\n", + "A [Constant] behaves very similarly to a [Quantity]. For example, we can use the Boltzmann constant to mimic the behavior of [u.temperature_energy()]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2d59d08", + "metadata": {}, + "outputs": [], + "source": [ + "thermal_energy_per_particle = 0.6 * u.keV\n", + "temperature = thermal_energy_per_particle / k_B\n", + "print(temperature.to(\"MK\"))" + ] + }, + { + "cell_type": "markdown", + "id": "7c145497", + "metadata": {}, + "source": [ + "Electromagnetic constants often need the unit system to be specified. Code within PlasmaPy uses SI units." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "015de7fc", + "metadata": { + "tags": [ + "raises-exception" + ] + }, + "outputs": [], + "source": [ + "2 * e" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a90c979", + "metadata": {}, + "outputs": [], + "source": [ + "2 * e.si" + ] + }, + { + "cell_type": "markdown", + "id": "f4da2ab0", + "metadata": {}, + "source": [ + "## Optimizing unit operations\n", + "\n", + "[performance tips]: https://docs.astropy.org/en/stable/units/index.html#performance-tips\n", + "[astropy.units]: https://docs.astropy.org/en/stable/units/index.html\n", + "\n", + "Astropy's documentation includes [performance tips] for using [astropy.units] in computationally intensive situations. For example, putting compound units in parentheses reduces the need to make multiple copies of the data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3bc2348", + "metadata": {}, + "outputs": [], + "source": [ + "volume = 0.62 * (u.barn * u.Mpc)" + ] + }, + { + "cell_type": "markdown", + "id": "55b8dcd1", + "metadata": {}, + "source": [ + "## Physical types" + ] + }, + { + "cell_type": "markdown", + "id": "0421ee56", + "metadata": {}, + "source": [ + "[physical type]: https://docs.astropy.org/en/stable/units/physical_types.html\n", + "[physical_type]: https://docs.astropy.org/en/stable/api/astropy.units.UnitBase.html#astropy.units.UnitBase.physical_type\n", + "[get_physical_type()]: https://docs.astropy.org/en/stable/api/astropy.units.get_physical_type.html#astropy.units.get_physical_type\n", + "\n", + "A [physical type] corresponds to physical quantities with dimensionally compatible units. Astropy has functionality that represents different physical types. These physical type objects can be accessed using either the [physical_type] attribute of a unit or [get_physical_type()]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "da6c9c7d", + "metadata": {}, + "outputs": [], + "source": [ + "(u.m**2 / u.s).physical_type" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f0d49b03", + "metadata": {}, + "outputs": [], + "source": [ + "u.get_physical_type(\"number density\")" + ] + }, + { + "cell_type": "markdown", + "id": "8cd7e09a", + "metadata": {}, + "source": [ + "These physical type objects can be used for dimensional analysis." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d03b8eb0", + "metadata": {}, + "outputs": [], + "source": [ + "energy_density = (u.J * u.m**-3).physical_type\n", + "velocity = u.get_physical_type(\"velocity\")\n", + "print(energy_density * velocity)" + ] + } + ], + "metadata": { + "celltoolbar": "Tags", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 562e92fca..000000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,11 +0,0 @@ --r ../requirements.txt - -jinja2 < 3.1 -numpydoc -pillow -sphinx == 2.4.4 -sphinx-automodapi -sphinx-gallery -sphinx_rtd_theme -pytest -setuptools-scm diff --git a/docs/response/index.html b/docs/response/index.html new file mode 100644 index 000000000..3cbb92aa0 --- /dev/null +++ b/docs/response/index.html @@ -0,0 +1,30 @@ +.. _xrtpy-response: + +*************************** +Response (`xrtpy.response`) +*************************** + +.. py:module:: xrtpy.response +.. currentmodule:: xrtpy.response + +Introduction +============ + +The `xrtpy.response` subpackage includes functionality for describing +XRT_ channels & filters, finding the effective area, and calculating the +temperature response function. + +Submodules +========== + +.. toctree:: + :maxdepth: 2 + + channel + +API +=== + +.. automodapi:: xrtpy.response + :noindex: + :no-main-docstring: diff --git a/pyproject.toml b/pyproject.toml index ba3843144..1009d034f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,6 +4,10 @@ requires = ["setuptools >= 50.0", "wheel >= 0.34.0"] # ought to mirror 'requirements/build.txt' build-backend = "setuptools.build_meta" +[tool.gilesbot] + +[tool.gilesbot.pull_requests] +enabled = true [tool.isort] line_length = 88 @@ -16,7 +20,3 @@ use_parentheses = true include_trailing_comma = true force_alphabetical_sort_within_sections = true lines_between_types = 1 - -[ tool.gilesbot ] - [ tool.gilesbot.pull_requests ] - enabled = true diff --git a/requirements/docs.txt b/requirements/docs.txt index 38315f499..3a4d8f6ec 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -5,17 +5,19 @@ -r extras.txt -r install.txt docutils < 0.18 +ipykernel +ipython jinja2 < 3.1 nbsphinx >= 0.8 numpydoc >= 1.2 pillow pygments >= 2.11.0 -sphinx <= 2.4.4 -sphinx_automodapi +sphinx >= 4.5.0 sphinx-changelog sphinx-copybutton sphinx-gallery sphinx-hoverxref +sphinx_automodapi sphinx_rtd_theme >= 1.0.0 sphinxcontrib-bibtex towncrier >= 20.0 diff --git a/setup.cfg b/setup.cfg index 96e80655d..04d75f42e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -58,12 +58,14 @@ docs = # ought to mirror requirements/docs.txt %(extras)s docutils < 0.18 + ipykernel + ipython jinja2 < 3.1 nbsphinx >= 0.8 numpydoc >= 1.2 pillow pygments >= 2.11.0 - sphinx <= 2.4.4 + sphinx >= 4.5.0 sphinx_automodapi sphinx-changelog sphinx-copybutton diff --git a/setup.py b/setup.py index f5a87d166..461b7b0ac 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,6 @@ from setuptools import setup - VERSION_TEMPLATE = """ # Note that we need to fall back to the hard-coded version if either # setuptools_scm can't be imported or setuptools_scm can't determine the diff --git a/tox.ini b/tox.ini index 50791feac..397e5cf32 100644 --- a/tox.ini +++ b/tox.ini @@ -40,14 +40,11 @@ skip_install = true commands = coverage erase [testenv:build_docs] -deps = - jinja2 < 3.1 - docutils < 0.18 changedir = {toxinidir} extras = docs setenv = HOME = {envtmpdir} -commands = sphinx-build docs docs{/}_build{/}html -W --keep-going -b html {posargs} +commands = sphinx-build docs docs{/}_build{/}html -W -n --keep-going -b html {posargs} [testenv:build_docs_no_examples] deps = @@ -57,17 +54,7 @@ changedir = {toxinidir} extras = docs setenv = HOME = {envtmpdir} -commands = sphinx-build -D nbsphinx_execute='never' docs docs{/}_build{/}html -b html {posargs} - -[testenv:build_docs_nitpicky] -deps = - jinja2 < 3.1 - docutils < 0.18 -changedir = {toxinidir} -extras = docs -setenv = - HOME = {envtmpdir} -commands = sphinx-build docs docs{/}_build{/}html -W -n --keep-going -b html {posargs} +commands = sphinx-build -D nbsphinx_execute='never' docs docs{/}_build{/}html -W -n --keep-going -b html {posargs} # This env tests minimal versions of each dependency. [testenv:py38-all-minimal] diff --git a/xrtpy/__init__.py b/xrtpy/__init__.py index 3d3caac2c..51bb2b4ad 100644 --- a/xrtpy/__init__.py +++ b/xrtpy/__init__.py @@ -1,4 +1,7 @@ -# Licensed under a 3-clause BSD style license - see LICENSE.rst +""" +A Python data analysis package for the `X-Ray Telescope`_ (XRT) on +Hinode_. +""" import warnings diff --git a/xrtpy/response/__init__.py b/xrtpy/response/__init__.py index 46245627e..ebea88c8d 100644 --- a/xrtpy/response/__init__.py +++ b/xrtpy/response/__init__.py @@ -1,5 +1,7 @@ +"""Response analysis for Hinode/XRT""" + from . import channel -from .channel import Geometry, EntranceFilter, Mirror, Filter, CCD, Channel +from .channel import Geometry, EntranceFilter, Mirror, Filter, CCD, Channel, resolve_filter_name __all__ = [ "channel", diff --git a/xrtpy/response/channel.py b/xrtpy/response/channel.py index 55c7e39f6..d2e2e4031 100644 --- a/xrtpy/response/channel.py +++ b/xrtpy/response/channel.py @@ -1,5 +1,6 @@ +"""Classes for describing channels on Hinode/XRT.""" + __all__ = [ - "channel", "Geometry", "EntranceFilter", "Mirror", @@ -40,6 +41,7 @@ def resolve_filter_name(name): + """Resolve the filter name.""" name = name.replace("_", "-") parts: list = name.split("/") new_parts: list = [part.capitalize() for part in name.split("/")]