diff --git a/docs/CODE_OF_CONDUCT.rst b/docs/CODE_OF_CONDUCT.rst index 49621ee5..b271d8bc 100644 --- a/docs/CODE_OF_CONDUCT.rst +++ b/docs/CODE_OF_CONDUCT.rst @@ -1,50 +1,51 @@ -.. currentmodule:: xrtpy - .. _CODE_OF_CONDUCT: -******************* +*************** Code of Conduct -******************* +*************** -XRTpy follows the Contributor Covenant Code of Conduct, which is a widely adopted standard for fostering an inclusive -and respectful community. Below are the key principles and standards that all contributors and community members are -expected to adhere to. +XRTpy follows the Contributor Covenant Code of Conduct, which is a widely adopted standard for fostering an inclusive and respectful community. +Below are the key principles and standards that all contributors and community members are expected to adhere to. Our Pledge ========== -We, as contributors and maintainers of XRTpy, pledge to make participation in our project and community a harassment-free -experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of -experience, education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and -orientation. + +We, as contributors and maintainers of XRTpy, pledge to make participation in our project and community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and orientation. Respectful Communication -========================= -We expect all participants to communicate respectfully and constructively. This includes being polite, considerate, and welcoming, -while avoiding any form of harassment, discrimination, or offensive behavior. +======================== + +We expect all participants to communicate respectfully and constructively. +This includes being polite, considerate, and welcoming, while avoiding any form of harassment, discrimination, or offensive behavior. Diversity and Inclusion -========================= -XRTpy values diversity and is dedicated to creating an inclusive environment. We welcome contributions from people of all backgrounds, -regardless of gender, disability, ethnicity, religion, nationality, sexual orientation, or any other characteristic. +======================= + +XRTpy values diversity and is dedicated to creating an inclusive environment. +We welcome contributions from people of all backgrounds, regardless of gender, disability, ethnicity, religion, nationality, sexual orientation, or any other characteristic. Constructive Criticism -========================= -Feedback is essential for the growth and improvement of XRTpy. We encourage everyone to provide and receive feedback in a constructive manner. +====================== + +Feedback is essential for the growth and improvement of XRTpy. +We encourage everyone to provide and receive feedback in a constructive manner. Criticism should focus on improving the project and fostering learning, with an emphasis on what is best for the overall community. Conflict Resolution and Enforcement -===================================== -Conflicts may arise in any collaborative environment. Participants should engage respectfully and with an open mind. -If unresolved, project maintainers will mediate to ensure a fair resolution. Violations of this Code of Conduct will result -in appropriate consequences, including warnings, temporary bans, or permanent removal. Community leaders are responsible for -enforcing these rules and taking corrective action as needed. +=================================== + +Conflicts may arise in any collaborative environment. +Participants should engage respectfully and with an open mind. +If unresolved, project maintainers will mediate to ensure a fair resolution. +Violations of this Code of Conduct will result in appropriate consequences, including warnings, temporary bans, or permanent removal. +Community leaders are responsible for enforcing these rules and taking corrective action as needed. **Enforcement and Reporting** -- Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at xrtpy@cfa.harvard.edu. All complaints will be reviewed and investigated promptly and fairly. +- Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at ``xrtpy@cfa.harvard.edu``. + All complaints will be reviewed and investigated promptly and fairly. - Community leaders are obligated to respect the privacy and security of the reporter of any incident. - This Code of Conduct is adapted from the `Contributor Covenant`_, version 2.1. .. _Contributor Covenant : https://www.contributor-covenant.org/version/2/1/code_of_conduct.html diff --git a/docs/_static/css/admonition_color_contrast.css b/docs/_static/css/admonition_color_contrast.css deleted file mode 100644 index f91be52b..00000000 --- a/docs/_static/css/admonition_color_contrast.css +++ /dev/null @@ -1,144 +0,0 @@ -/* - 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 deleted file mode 100644 index b59e85f7..00000000 --- a/docs/_static/css/plasmapy.css +++ /dev/null @@ -1,186 +0,0 @@ -/* - 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/images/XRT_composite_image_full_disk_14February2015.png b/docs/_static/images/XRT_composite_image_full_disk_14February2015.png similarity index 100% rename from docs/images/XRT_composite_image_full_disk_14February2015.png rename to docs/_static/images/XRT_composite_image_full_disk_14February2015.png diff --git a/docs/images/XRT_filter_wheels_Sun_View_Diagram.png b/docs/_static/images/XRT_filter_wheels_Sun_View_Diagram.png similarity index 100% rename from docs/images/XRT_filter_wheels_Sun_View_Diagram.png rename to docs/_static/images/XRT_filter_wheels_Sun_View_Diagram.png diff --git a/docs/images/XRTpy_logo.png b/docs/_static/images/XRTpy_logo.png similarity index 100% rename from docs/images/XRTpy_logo.png rename to docs/_static/images/XRTpy_logo.png diff --git a/docs/_static/notebook_images/hinode_satellite.png b/docs/_static/images/hinode_satellite.png similarity index 100% rename from docs/_static/notebook_images/hinode_satellite.png rename to docs/_static/images/hinode_satellite.png diff --git a/docs/_static/notebook_images/astropy_logo_notext.png b/docs/_static/notebook_images/astropy_logo_notext.png deleted file mode 100644 index bcff0ed6..00000000 Binary files a/docs/_static/notebook_images/astropy_logo_notext.png and /dev/null differ diff --git a/docs/_substitutions.rst b/docs/_substitutions.rst index bd3f806b..c866378c 100644 --- a/docs/_substitutions.rst +++ b/docs/_substitutions.rst @@ -1,4 +1,4 @@ -.. |bibliography| replace:: :ref:`bibliography`\ +.. |bibliography| replace:: :ref:`xrtpy-bibliography`\ .. |Channel| replace:: :class:`~xrtpy.response.channel.Channel` .. |EffectiveAreaFundamental| replace:: :class:`~xrtpy.response.effective_area.EffectiveAreaFundamental` .. |glossary| replace:: :ref:`glossary`\ diff --git a/docs/about_xrt.rst b/docs/about_xrt.rst index d6cbee4c..1bf07567 100644 --- a/docs/about_xrt.rst +++ b/docs/about_xrt.rst @@ -1,57 +1,55 @@ -.. _about-xrt: - -.. image:: images/hinode_satellite.png - :alt: Hinode Satellite - :align: right - :scale: 64% - +.. _xrtpy-about-xrt: ******************************* About the X-Ray Telescope (XRT) ******************************* -.. contents:: Contents - :local: - Hinode ====== -Hinode is a joint mission involving the space agencies of Japan, the United States, Europe, and the United Kingdom. It is depicted in the *illustration shown above*. + +.. image:: _static/images/hinode_satellite.png + :alt: Hinode Satellite + :align: center + +Hinode is a joint mission involving the space agencies of Japan, the United States, Europe, and the United Kingdom. +It is depicted in the *illustration shown above*. The spacecraft is equipped with three instruments: the Solar Optical Telescope (SOT), the Extreme Ultraviolet Imaging Spectrometer (EIS), and the X-Ray Telescope (XRT). -These instruments are designed to provide multi-wavelength data from the photosphere to the upper corona. The solar spacecraft spacecraft was launched at 6:36 a.m on -September 23, 2006 (Japan Standard Time) and placed into a polar, sun-synchronous orbit, enabling continuous observations of the Sun. For further information, visit `NASA's Hinode space mission to the Sun`_. +These instruments are designed to provide multi-wavelength data from the photosphere to the upper corona. +The solar spacecraft spacecraft was launched at 6:36 a.m on September 23, 2006 (Japan Standard Time) and placed into a polar, sun-synchronous orbit, enabling continuous observations of the Sun. +For further information, visit `NASA's Hinode space mission to the Sun`_. The X-Ray Telescope -==================== -The X-Ray Telescope (XRT), depicted as a long linear black tube on the Hinode spacecraft (illustration at the top of the page), is a crucial instrument for observing the solar corona's most intense regions, with temperatures ranging from 1,000,000 to 10,000,000 Kelvin. -The image below is a synoptic composite from February 14, 2015, created using the Al-Mesh/Be-Thin/Al-Med filters. -This method combines images taken with different filters, each set to a distinct color in the RGB color model to highlight various thermal conditions within the corona. -For a comprehensive overview of XRT's mission and capabilities, please visit the official xrt-cfa-harvard_ website. +=================== -.. image:: images/XRT_composite_image_full_disk_14February2015.png +.. image:: _static/images/XRT_composite_image_full_disk_14February2015.png :alt: XRT Composite Image :align: center - :scale: 40% + :scale: 50% + +The X-Ray Telescope (XRT), depicted as a long linear black tube on the Hinode spacecraft is a crucial instrument for observing the solar corona's most intense regions, with temperatures ranging from 1,000,000 to 10,000,000 Kelvin. +The image below is a synoptic composite from February 14, 2015, created using the Al-Mesh/Be-Thin/Al-Med filters. +This method combines images taken with different filters, each set to a distinct color in the RGB color model to highlight various thermal conditions within the corona. +For a comprehensive overview of XRT's mission and capabilities, please visit the official xrt-cfa-harvard_ website. + +.. tip:: + + Visit the `XRT Picture of the Week`_ and the `Hinode-XRT YouTube`_ page for captivating visual content showcasing the XRT's solar observations. SolarSoft XRT Analysis Guide ============================ + The `SolarSoft XRT Analysis Guide`_ is a comprehensive resource for analysis of XRT data. -It includes both an Instrument Guide and an overview of the X-Ray telescope's hardware components. -The XRT software was originally created in Interactive Data Language (IDL). -IDL is a software programming language used to analyze and create meaningful information from numerical data. +It includes both an instrument guide and an overview of the x-ray telescope's hardware components. +The XRT software was originally created in the Interactive Data Language (IDL). .. note:: + Please note that the `SolarSoft XRT Analysis Guide`_ does not serve as a guide for using XRTpy. It focuses solely on the analysis of XRT data using the IDL software. -.. tip:: - Visit the `XRT Picture of the Week`_ and the `Hinode-XRT YouTube`_ page for captivating visual content showcasing the XRT's solar observations. - -.. _NASA's Hinode space mission to the Sun: https://www.nasa.gov/mission_pages/hinode/mission.html +.. _Hinode-XRT YouTube: https://www.youtube.com/user/xrtpow .. _Interactive Data Language: https://www.l3harrisgeospatial.com/Software-Technology/IDL - +.. _NASA's Hinode space mission to the Sun: https://www.nasa.gov/mission_pages/hinode/mission.html .. _SolarSoft XRT Analysis Guide: https://xrt.cfa.harvard.edu/resources/documents/XAG/XAG.pdf -.. _xrt-cfa-harvard: https://xrt.cfa.harvard.edu/index.php -.. _Artist's concept of the Hinode: https://www.nasa.gov/mission_pages/sunearth/missions/mission-hinode.html - -.. _Hinode-XRT YouTube: https://www.youtube.com/user/xrtpow .. _XRT Picture of the Week: https://xrt.cfa.harvard.edu/xpow +.. _xrt-cfa-harvard: https://xrt.cfa.harvard.edu/index.php diff --git a/docs/contributing/acknowledging_xrtpy.rst b/docs/acknowledging_xrtpy.rst similarity index 67% rename from docs/contributing/acknowledging_xrtpy.rst rename to docs/acknowledging_xrtpy.rst index 3b371b07..cc1fdd2e 100644 --- a/docs/contributing/acknowledging_xrtpy.rst +++ b/docs/acknowledging_xrtpy.rst @@ -1,30 +1,33 @@ -.. _citation_guide: +.. _xrtpy-citation: -=============================================== +********************************************** Citing XRTpy in Publications and Presentations -=============================================== +********************************************** - -If XRTpy has been useful in your research, we encourage you to consider including a citation or acknowledgment in your work. Below are suggested formats to credit XRTpy in your scientific papers, posters, or presentations. While this is not required, it is greatly appreciated. - -Suggested Citations -=================== +If XRTpy has been useful in your research, we encourage you to consider including a citation or acknowledgment in your work. +Below are suggested formats to credit XRTpy in your scientific papers, posters, or presentations. +While this is not required, it is greatly appreciated. For a scientific paper ----------------------- +====================== + You may use the following format to cite XRTpy in your publications: +.. code-block:: text + "We acknowledge the use of XRTpy (v0.4.1) for Hinode X-Ray Telescope data analysis, available at https://xrtpy.readthedocs.io/ (Velasquez et al. 2024, JOSS, DOI: 10.21105/joss.06396)." For a poster or presentation ----------------------------- +============================ + If you are presenting work that involves XRTpy in a poster or presentation, you may use the following acknowledgment: +.. code-block:: text + "This work made use of XRTpy (v0.4.1), a Python package for solar Hinode X-Ray Telescope data analysis, available at https://xrtpy.readthedocs.io/ (Velasquez et al. 2024, JOSS, DOI: 10.21105/joss.06396)." References ========== -Velasquez, J., Murphy, N., Reeves, K. K., Slavin, J., Weber, M., & Barnes, W. (2024). XRTpy: A Hinode-X-Ray Telescope Python Package. The Journal of Open Source Software, 9(100), 6396. https://doi.org/10.21105/joss.06396 -.. _joss_citation: https://doi.org/10.21105/joss.06396 +Velasquez, J., Murphy, N., Reeves, K. K., Slavin, J., Weber, M., & Barnes, W. (2024). XRTpy: A Hinode-X-Ray Telescope Python Package. The Journal of Open Source Software, 9(100), 6396. https://doi.org/10.21105/joss.06396 diff --git a/docs/api_static/xrtpy.image_correction.deconvolve.rst b/docs/api_static/xrtpy.image_correction.deconvolve.rst deleted file mode 100644 index 5f874e05..00000000 --- a/docs/api_static/xrtpy.image_correction.deconvolve.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -`xrtpy.image_correction.deconvolve` -=================================== - -.. currentmodule:: xrtpy.image_correction.deconvolve - -.. automodapi:: xrtpy.image_correction.deconvolve diff --git a/docs/api_static/xrtpy.image_correction.rst b/docs/api_static/xrtpy.image_correction.rst deleted file mode 100644 index 3b136aff..00000000 --- a/docs/api_static/xrtpy.image_correction.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -`xrtpy.image_correction` -======================== - -.. currentmodule:: xrtpy.image_correction - -.. automodapi:: xrtpy.image_correction diff --git a/docs/api_static/xrtpy.response.channel.rst b/docs/api_static/xrtpy.response.channel.rst deleted file mode 100644 index be53692b..00000000 --- a/docs/api_static/xrtpy.response.channel.rst +++ /dev/null @@ -1,8 +0,0 @@ -: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 deleted file mode 100644 index 80adc6fa..00000000 --- a/docs/api_static/xrtpy.response.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -`xrtpy.response` -================ - -.. currentmodule:: xrtpy.response - -.. automodapi:: xrtpy.response diff --git a/docs/api_static/xrtpy.response.temperature_from_filter_ratio.rst b/docs/api_static/xrtpy.response.temperature_from_filter_ratio.rst deleted file mode 100644 index a4bf0d0b..00000000 --- a/docs/api_static/xrtpy.response.temperature_from_filter_ratio.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -`xrtpy.response.temperature_from_filter_ratio` -============================================== - -.. currentmodule:: xrtpy.response.temperature_from_filter_ratio - -.. automodapi:: xrtpy.response.temperature_from_filter_ratio diff --git a/docs/api_static/xrtpy.response.temperature_response.rst b/docs/api_static/xrtpy.response.temperature_response.rst deleted file mode 100644 index 4da3ad44..00000000 --- a/docs/api_static/xrtpy.response.temperature_response.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -`xrtpy.response.temperature_response` -===================================== - -.. currentmodule:: xrtpy.response.temperature_response - -.. automodapi:: xrtpy.response.temperature_response diff --git a/docs/api_static/xrtpy.rst b/docs/api_static/xrtpy.rst deleted file mode 100644 index 91fb98a5..00000000 --- a/docs/api_static/xrtpy.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -`xrtpy` -======= - -.. currentmodule:: xrtpy - -.. automodapi:: xrtpy diff --git a/docs/api_static/xrtpy.util.make_exposure_map.rst b/docs/api_static/xrtpy.util.make_exposure_map.rst deleted file mode 100644 index 804ac0d2..00000000 --- a/docs/api_static/xrtpy.util.make_exposure_map.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -`xrtpy.util.make_exposure_map` -============================== - -.. currentmodule:: xrtpy.util.make_exposure_map - -.. automodapi:: xrtpy.util.make_exposure_map diff --git a/docs/api_static/xrtpy.util.rst b/docs/api_static/xrtpy.util.rst deleted file mode 100644 index 9ad5963e..00000000 --- a/docs/api_static/xrtpy.util.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -`xrtpy.util` -============ - -.. currentmodule:: xrtpy.util - -.. automodapi:: xrtpy.util diff --git a/docs/api_static/xrtpy.util.time.rst b/docs/api_static/xrtpy.util.time.rst deleted file mode 100644 index 31fa124b..00000000 --- a/docs/api_static/xrtpy.util.time.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -`xrtpy.util.time` -================= - -.. currentmodule:: xrtpy.util.time - -.. automodapi:: xrtpy.util.time diff --git a/docs/bibliography.rst b/docs/bibliography.rst index 54b204ac..f4200833 100644 --- a/docs/bibliography.rst +++ b/docs/bibliography.rst @@ -1,10 +1,10 @@ -.. _bibliography: +.. _xrtpy-bibliography: ############ Bibliography ############ -.. The bibliography is built from references contained within - bibliography.bib. Add new references to bibliography.bib. +.. 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 a436e659..31e500a1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,175 +1,206 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file does only contain a selection of the most common options. For a -# full list see the documentation: -# http://www.sphinx-doc.org/en/master/config +""" +Configuration file for the Sphinx documentation builder. +""" +# -- stdlib imports ------------------------------------------------------------ import os -from datetime import datetime - -from sphinx.application import Sphinx - -# -- Project information ----------------------------------------------------- - +import warnings +from datetime import UTC, datetime +from pathlib import Path + +from packaging.version import Version + +# -- Read the Docs Specific Configuration -------------------------------------- +# This needs to be done before xrtpy is imported +on_rtd = os.environ.get("READTHEDOCS", None) == "True" +if on_rtd: + os.environ["SUNPY_CONFIGDIR"] = "/home/docs/" + os.environ["HOME"] = "/home/docs/" + os.environ["LANG"] = "C" + os.environ["LC_ALL"] = "C" + os.environ["PARFIVE_HIDE_PROGRESS"] = "True" + +# -- Imports ------------------------------------------------------------------- +from astropy.utils.exceptions import AstropyDeprecationWarning # NOQA: E402 +from matplotlib import MatplotlibDeprecationWarning # NOQA: E402 +from sunpy.util.exceptions import ( # NOQA: E402 + SunpyDeprecationWarning, + SunpyPendingDeprecationWarning, +) + +# -- Project information ------------------------------------------------------- project = "xrtpy" author = "Joy Velasquez, Nick Murphy, and Jonathan Slavin" -copyright = f"2021–{datetime.utcnow().year}, {author}" +copyright = f"2021-{datetime.now(tz=UTC).year}, {author}" # The full version, including alpha/beta/rc tags -# from xrtpy import __version__ -# release = __version__ +from xrtpy import __version__ # NOQA: E402 -release = "0.4.0" +release = __version__ +version = Version(__version__) +is_release = not (version.is_prerelease or version.is_devrelease) # -- General configuration --------------------------------------------------- +# We want to make sure all the following warnings fail the build +warnings.filterwarnings("error", category=SunpyDeprecationWarning) +warnings.filterwarnings("error", category=SunpyPendingDeprecationWarning) +warnings.filterwarnings("error", category=MatplotlibDeprecationWarning) +warnings.filterwarnings("error", category=AstropyDeprecationWarning) + +# For the linkcheck +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 = [] + +# sphinxext-opengraph +ogp_image = "https://raw.githubusercontent.com/HinodeXRT/xrtpy/main/docs/_static/images/XRTpy_logo.png" +ogp_use_first_image = True +ogp_description_length = 160 +ogp_custom_meta_tags = [ + '', +] + +# Suppress warnings about overriding directives as we overload some of the +# doctest extensions. +suppress_warnings = [ + "app.add_directive", +] + # Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# extensions coming with Sphinx (named "sphinx.ext.*") or your custom # ones. extensions = [ + "matplotlib.sphinxext.plot_directive", "sphinx_automodapi.automodapi", + "sphinx_automodapi.smart_resolver", + "sphinx_gallery.gen_gallery", "sphinx.ext.autodoc", + "sphinx.ext.coverage", + "sphinx.ext.doctest", + "sphinx.ext.inheritance_diagram", "sphinx.ext.intersphinx", - "sphinx.ext.graphviz", "sphinx.ext.mathjax", "sphinx.ext.napoleon", "sphinx.ext.todo", - "nbsphinx", - "sphinx_changelog", + "sphinx.ext.viewcode", + "sphinxext.opengraph", + "sphinx_design", "sphinx_copybutton", - "sphinx_gallery.load_style", - "IPython.sphinxext.ipython_console_highlighting", - "sphinx_changelog", - "sphinx_issues", - "sphinxcontrib.bibtex", "hoverxref.extension", - "sphinx_copybutton", - "sphinx_codeautolink", - "sphinx.ext.viewcode", ] -bibtex_bibfiles = ["bibliography.bib"] -bibtex_default_style = "plain" -bibtex_reference_style = "author_year" -bibtex_cite_id = "{key}" +# Set automodapi to generate files inside the generated directory +automodapi_toctreedirnm = "generated/api" # Add any paths that contain templates here, relative to this directory. -# templates_path = ['_templates'] +# 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 = [ - ".DS_Store", - "_build", - "_links.rst", - "_substitutions.rst", - "Thumbs.db", -] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = ['robots.txt'] + +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: source_suffix = ".rst" -# The root toctree document. -root_doc = "index" - -# -- nbsphinx configuration -------------------------------------------------- - -nbsphinx_allow_errors = True # Allow errors in Jupyter notebooks - -# -- Options for intersphinx extension --------------------------------------- - -intersphinx_mapping = { - "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), - "sunpy": ("https://docs.sunpy.org/en/stable/", None), -} +# The master toctree document. +master_doc = "index" -hoverxref_intersphinx = [ - "astropy", - "ndcube", - "numpy", - "python", - "scipy", - "sunpy", -] +# The reST default role (used for this markup: `text`) to use for all +# documents. Set to the "smart" one. +default_role = "obj" -autoclass_content = "both" -autodoc_typehints_format = "short" +# Disable having a separate return type row +napoleon_use_rtype = False -# -- Options for HTML output ------------------------------------------------- +# Disable google style docstrings +napoleon_google_docstring = False -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = "sphinx_rtd_theme" +# Disable the use of param, which prevents a distinct "Other Parameters" section +napoleon_use_param = False -# 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"] +# Enable nitpicky mode, which forces links to be non-broken +nitpicky = True +# This is not used. See docs/nitpick-exceptions file for the actual listing. +nitpick_ignore = [] +with Path("nitpick-exceptions").open() as f: + for line in f: + if line.strip() == "" or line.startswith("#"): + continue + dtype, target = line.split(None, 1) + target = target.strip() + nitpick_ignore.append((dtype, target)) -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.+", -} +bibtex_bibfiles = ["bibliography.bib"] +bibtex_default_style = "plain" +bibtex_reference_style = "author_year" +bibtex_cite_id = "{key}" -linkcheck_anchors = True -linkcheck_anchors_ignore = [ - "/room", - r".+openastronomy.+", - "L[0-9].+", - "!forum/plasmapy", -] +# 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 Path(epilog_file).open() as file: + rst_epilog += file.read() -# Use a code highlighting style that meets the WCAG AA contrast standard -pygments_style = "default" +# -- Options for intersphinx extension --------------------------------------- -nbsphinx_thumbnails = { - "notebooks/getting_started/units": ( - "_static/notebook_images/astropy_logo_notext.png" - ), # CC BY-SA - "notebooks/getting_started/A_Practical_Guide_to_Data_Extraction_and_Visualization": ( - "_static/notebook_images/hinode_satellite.png" +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ( + "https://docs.python.org/3/", + (None, "http://www.astropy.org/astropy-data/intersphinx/python3.inv"), + ), + "numpy": ( + "https://numpy.org/doc/stable/", + (None, "http://www.astropy.org/astropy-data/intersphinx/numpy.inv"), ), + "scipy": ( + "https://docs.scipy.org/doc/scipy/reference/", + (None, "http://www.astropy.org/astropy-data/intersphinx/scipy.inv"), + ), + "astropy": ("https://docs.astropy.org/en/stable/", None), + "matplotlib": ("https://matplotlib.org/stable", None), + "ndcube": ("https://docs.sunpy.org/projects/ndcube/en/stable/", None), } -# adapted from sphinx-hoverxref conf.py +# -- Options for hoverxref ----------------------------------------------------- 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 + # 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_mathjax = True +hoverxref_modal_hover_delay = 500 +hoverxref_tooltip_maxwidth = 600 # RTD main window is 696px +hoverxref_intersphinx = list(intersphinx_mapping.keys()) hoverxref_role_types = { - # roles with cite domain + # Roles with cite domain "p": "tooltip", "t": "tooltip", - # - # roles with py domain + # Roles within the py domain "attr": "tooltip", "class": "tooltip", "const": "tooltip", @@ -179,50 +210,55 @@ "meth": "tooltip", "mod": "tooltip", "obj": "tooltip", - # - # roles with std domain + # Roles within the std domain "confval": "tooltip", "hoverxref": "tooltip", - "ref": "tooltip", + "ref": "tooltip", # Would be used by hoverxref_auto_ref if we set it to True "term": "tooltip", } -# Configure sphinx-issues - -issues_github_path = "HinodeXRT/xrtpy" - -# 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: # noqa: PTH123 - rst_epilog += file.read() +# -- 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 = "pydata_sphinx_theme" -# Add the nbsphinx_allow_errors option -nbsphinx_allow_errors = True +# 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"] + +# Render inheritance diagrams in SVG +graphviz_output_format = "svg" + +graphviz_dot_args = [ + "-Nfontsize=10", + "-Nfontname=Helvetica Neue, Helvetica, Arial, sans-serif", + "-Efontsize=10", + "-Efontname=Helvetica Neue, Helvetica, Arial, sans-serif", + "-Gfontsize=10", + "-Gfontname=Helvetica Neue, Helvetica, Arial, sans-serif", +] + +# -- Sphinx Gallery ------------------------------------------------------------ + +sphinx_gallery_conf = { + "backreferences_dir": Path("generated") / "modules", + "filename_pattern": "^((?!skip_).)*$", + "examples_dirs": Path("..") / "examples", + "within_subsection_order": "ExampleTitleSortKey", + "gallery_dirs": Path("generated") / "gallery", + "matplotlib_animations": True, + "default_thumb_file": "https://raw.githubusercontent.com/HinodeXRT/xrtpy/main/docs/_static/images/XRTpy_logo.png", + "abort_on_example_error": False, + "plot_gallery": "True", + "remove_config_comments": True, + "doc_module": ("xrtpy"), + "only_warn_on_example_error": True, +} +# -- Options for sphinx-copybutton --------------------------------------------- -def setup(app: Sphinx) -> None: - app.add_config_value("revision", "", True) # noqa: FBT003 - app.add_css_file("css/admonition_color_contrast.css") - app.add_css_file("css/plasmapy.css", priority=600) +# Python Repl + continuation, Bash, ipython and qtconsole + continuation, jupyter-console + continuation +copybutton_prompt_text = r">>> |\.\.\. |\$ |In \[\d*\]: | {2,5}\.\.\.: | {5,8}: " +copybutton_prompt_is_regexp = True diff --git a/docs/contributing/index.rst b/docs/contributing/index.rst index f7530cd2..29d228dc 100644 --- a/docs/contributing/index.rst +++ b/docs/contributing/index.rst @@ -1,4 +1,4 @@ -.. _contributor guide: +.. _xrtpy_contributing: ***************** Contributor Guide @@ -10,4 +10,3 @@ Contributor Guide contributing installation_for_development release_guide - acknowledging_xrtpy diff --git a/docs/examples.rst b/docs/examples.rst index 64499aa5..95495371 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -1,10 +1,11 @@ +.. _xrtpy-examples: + Examples ======== -In this section, we provide a catalog of example Jupyter notebooks that -demonstrate the various functionalities offered by `XRTpy`. These notebooks -serve as practical guides for utilizing the features and capabilities of XRTpy -in different scenarios. By exploring these examples, users can gain a better -understanding of how to effectively use XRTpy for their analysis tasks. + +In this section, we provide a catalog of example Jupyter notebooks that demonstrate the various functionalities offered by XRTpy. +These notebooks serve as practical guides for utilizing the features and capabilities of XRTpy in different scenarios. +By exploring these examples, users can gain a better understanding of how to effectively use XRTpy for their analysis tasks. .. contents:: :local: @@ -13,17 +14,17 @@ Getting started --------------- .. nbgallery:: - :glob: + :glob: - notebooks/getting_started/* + notebooks/getting_started/* Computing response functions ---------------------------- .. nbgallery:: - :glob: + :glob: - notebooks/computing_functions/* + notebooks/computing_functions/* Data analysis ------------- diff --git a/docs/feedback_communication.rst b/docs/feedback_communication.rst index 514be42c..8ed18b8f 100644 --- a/docs/feedback_communication.rst +++ b/docs/feedback_communication.rst @@ -1,28 +1,29 @@ -.. currentmodule:: xrtpy +.. _xrytpy-feedback-communication: -.. _feedback_communication: +************************ +Communicating with XRTpy +************************ -******************** -Communication Routes -******************** - -XRTpy has several methods of contact to get direct intel of XRTpy's current -works, reporting bugs, giving feedback, and asking questions. Please direct any comments, questions, or suggestions to `xrtpy@cfa.harvard.edu`_. +XRTpy has several methods that one can use to get contact with XRTpy developers, giving feedback or giving feedback. Feedback ======== -We appreciate any feedback describing your experience using XRTpy. We welcome other methods and ideas towards the development of XRTpy. You may contact us via `email`_ or through `GitHub Hinode XRT`_. -Bug Encounters -============== -In the event that you come across a direct XRTpy error, flaw, or unexpected operation, please report it to us directly via `email`_ or by creating a `GitHub-issue`_. +We appreciate any feedback describing your experience using XRTpy. +We welcome other methods and ideas towards the development of XRTpy. +You may contact us via `GitHub Hinode XRT`_ or `email`_. + +Bugs +==== + +If you encounter a XRTpy error, flaw, or unexpected operation, please report it to us by creating a `GitHub-issue`_ or by sending an `email`_. Contributing ============ -We welcome contributions from the community! For detailed guidelines on how to contribute, please see our `Contributing Guide` page section `Contributing to XRTpy` . +We welcome contributions from the community! +For detailed guidelines on how to contribute, please see :ref:`xrtpy_contributing`. -.. _xrtpy@cfa.harvard.edu: xrtpy@cfa.harvard.edu .. _email: xrtpy@cfa.harvard.edu -.. _GitHub-issue: https://github.com/HinodeXRT/xrtpy/issues .. _GitHub Hinode XRT : https://github.com/HinodeXRT/xrtpy +.. _GitHub-issue: https://github.com/HinodeXRT/xrtpy/issues diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 999d6ed5..eae46733 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -1,86 +1,93 @@ +.. _xrtpy-getting-started: + =============== Getting Started =============== -XRTpy is a Python package being developed for the analysis of observations made by the X-Ray Telescope (XRT) -on the board Hinode spacecraft. This page is intended for new users of `xrtpy`. For more background information about XRT please refer to the `SolarSoft XRT Analysis Guide`_. +XRTpy is a Python package being developed for the analysis of observations made by the X-Ray Telescope (XRT) on the board Hinode spacecraft. +This page is intended for new users of `xrtpy`. For more background information about XRT please refer to the `SolarSoft XRT Analysis Guide`_. +XRTpy Objects +************* -XRTpy Objects: -************** -XRTpy currently offers *Channel*, *Effective Area*, and *Temperature Response* classes. We have also introduced new functionality, including -the ablility to derive temperatures and emission measures for a pair of images, sharpen images using the point spread function, and -a function to correct synoptic images for the light leak (visible stray light) that XRT has developed. +XRTpy currently offers *Channel*, *Effective Area*, and *Temperature Response* classes. +There is the ability to to derive temperatures and emission measures for a pair of images, sharpen images using a Point Spread Function (PSF) deconvolution, and to correct synoptic images for the light leak (visible stray light) that XRT has developed. Visit our Example page for detail notebook example guides on how to use the XRTpy classes and functions. - Channel ------- -|Channel| is an instrument configuration class that contains the properties of particular XRT filters. It provides a detailed information on the filter channel, including the Charge-Coupled Device (CCD), Entrance Filter, Focus-Filter(s), Geometry, and Mirror(s). +|Channel| is an instrument configuration class that contains the properties of particular XRT filters. +It provides a detailed information on the filter channel, including the Charge-Coupled Device (CCD), Entrance Filter, Focus-Filter(s), Geometry, and Mirror(s). Effective Area -------------- + XRTpy calculates the effective areas for a set of XRT filter channels paired with thicknesses of the CCD contamination layer. For more information about the instrumental spectral responses, refer to the `SolarSoft XRT Analysis Guide`_. - Temperature Response -------------------- -XRTpy calculates the temperature response for each XRT filter channel, assuming a spectral emission model, refer to :cite:t:`narukage:2011` and :cite:t:`narukage:2014`. -The XRT default emission model is `CHIANTI`_ atomic database version 10.0 with coronal abundances :cite:t:`feldman:1992`. This structure contains data and information about a plasma emission model, as a function of wavelength and temperature. +XRTpy calculates the temperature response for each XRT filter channel, assuming a spectral emission model, refer to :cite:t:`narukage:2011` and :cite:t:`narukage:2014`. +The XRT default emission model is `CHIANTI`_ atomic database version 10.0 with coronal abundances :cite:t:`feldman:1992`. +This structure contains data and information about a plasma emission model, as a function of wavelength and temperature. Deriving Temperature and Emission Measure for a Pair of Images -------------------------------------------------------------- -XRTpy provides a routine, *temperature_from_filter_ratio*, that employs the objects listed above to derive the temperature and emission -measure in for a given pair of images using the filter ratio method. This uses the same methods as in the SolarSoft IDL -routine of the same name. Familiarize yourself with the utilization of this function through the notebook example provided on our Example page. +XRTpy provides a routine, *temperature_from_filter_ratio*, that employs the objects listed above to derive the temperature and emission measure in for a given pair of images using the filter ratio method. +This uses the same methods as in the SolarSoft IDL routine of the same name. +Familiarize yourself with the utilization of this function through the notebook example provided on our Example page. Enhancing Images Sharpness with Point Spread Function - Deconvolution --------------------------------------------------------------------- + Deconvolution is a powerful technique used to enhance image sharpness by mitigating the blurring effect -caused by the telescope's point spread function (PSF). It is particularly useful for removing the blurring -around sharp objects or features in the XRT image. To learn how to use *deconvolve*, refer to the notebook examples provided on our Example page. +caused by the telescope's point spread function (PSF). +It is particularly useful for removing the blurring around sharp objects or features in the XRT image. +To learn how to use *deconvolve*, refer to the notebook examples provided on our Example page. Subtracting Light Leak from XRT Synoptic Composite Images --------------------------------------------------------- -We have developed a specialized function designed to subtract light leak, *remove_lightleak*, which refers to visible stray -light, from XRT synoptic composite images. By applying this function, you can effectively remove the -unwanted artifacts caused by light leak, resulting in cleaner and more accurate images for further analysis and interpretation. + +We have developed a specialized function designed to subtract light leak, *remove_lightleak*, which refers to visible stray light, from XRT synoptic composite images. +By applying this function, you can effectively remove the unwanted artifacts caused by light leak, resulting in cleaner and more accurate images for further analysis and interpretation. Explore our Example page for a notebook example that demonstrate the usage of this function. Abundance Model --------------- + The standard XRT temperature response routines are calculated assuming `CHIANTI`_ coronal abundances, :cite:t:`feldman:1992`. -Additionally, XRTpy offers the ability to choose two other sets of `CHIANTI`_ abundances i.e. Hybrid and Photospheric. -The Hybrid abundances are base on :cite:t:`Fludra:1999` and Photospheric abundances are base on :cite:t:`Grevesse:2007`. +Additionally, XRTpy offers the ability to choose two other sets of `CHIANTI`_ abundances i.e., Hybrid and Photospheric. +The Hybrid abundances are based on :cite:t:`Fludra:1999` and Photospheric abundances are base on :cite:t:`Grevesse:2007`. The `CHIANTI`_ files contain data and information about a plasma emission model, as a function of wavelength and temperature. Visit `XRT temperature response with other choice of abundances`_ for future detailed information. .. note:: + XRTpy has future plans to accept other plasma emission spectra models. -XRTpy defaults to using CHIANTI `"coronal"` abundance. You can specify the other abundances by defining the abundance type name, -such as `"hybrid"` or `"photospheric"` in the `abundance_model` parameter. For example: +XRTpy defaults to using CHIANTI's `"coronal"` abundance. +You can specify the other abundances by defining the abundance type name, such as `"hybrid"` or `"photospheric"` in the `abundance_model` parameter. -.. code-block:: bash +For example: - xrtpy.response.TemperatureResponseFundamental( - 'Al-poly', - '2022/07/04T23:43:12', - abundance_model = 'Hybrid' - ) +.. code-block:: python -The `abundance_model` parameter is used in the same format in `temperature_from_filter_ratio`. + xrtpy.response.TemperatureResponseFundamental( + "Al-poly", "2022/07/04T23:43:12", abundance_model="Hybrid" + ) +The ``abundance_model`` parameter is used in the same format in `temperature_from_filter_ratio`. Data Products ************* + The XRT website provides readily available `XRT data products`_, including both Level 1 and Level 2 data. -The `Level 1 Data`_ section contains an extensive archive of all Level 1 XRT data that has been calibrated using the `xrt_prep`_ routine, with units expressed in instrumental Data Numbers. -Additionally, for users interested in synoptic images, `Level 2 Synoptics`_ data is available, which consists of composite images from the twice-daily synoptic program. These images have been processed and are available in the archive. +The `Level 1 Data`_ section contains an extensive archive of all Level 1 XRT data that has been calibrated using the `xrt_prep`_ routine, with units expressed in Data Numbers. +Additionally, for users interested in synoptic images, `Level 2 Synoptics`_ data is available, which consists of composite images from the twice-daily synoptic program. +These images have been processed and are available in the archive. For more detailed information about our XRT data products, please visit the `XRT data products`_ site, where you can find comprehensive data resources and references. .. _Level 1 Data: https://xrt.cfa.harvard.edu/level1/ @@ -88,11 +95,14 @@ For more detailed information about our XRT data products, please visit the `XRT .. _XRT data products: https://xrt.cfa.harvard.edu/data_products/index.php .. _xrt_prep: https://xrt.cfa.harvard.edu/resources/documents/XAG/XAG.pdf +_xrtpy-getting-started-filters: + X-Ray Filter Channel -********************* +******************** -The XRT controls filter imaging using two sequentially positioned filter wheels, as shown in the diagram below. Each wheel houses a variety of filters. By rotating these wheels, scientists can select different filters to study the sun in multiple wavelengths, thereby enhancing the resolution and quality of solar images. -Refer to Section 3 in the `X-Ray Telescope Instrument Guide` in the `SolarSoft XRT Analysis Guide`_ for more information about the XRT filters. +XRT uses two sequentially positioned filter wheels, as shown in the diagram below, where each wheel houses a variety of filters. +By rotating these wheels, scientists can select different filters to study the Sun in different wavelengths, thereby enhancing the resolution and quality of solar images. +Refer to Section 3 in the `X-Ray Telescope Instrument Guide` in the `SolarSoft XRT Analysis Guide`_ for more information abo[ut the XRT filters. The existing filters are structured as follows: #. Filter Configuration @@ -112,20 +122,21 @@ The existing filters are structured as follows: - Aluminum Thick (*Al-thick*) - Beryllium Thick (*Be-thick*) #. *Open* - Each filter wheel has an empty position, named 'Open'. The open position is in place when a filter on the other filter wheel is being used. + Each filter wheel has an empty position, named 'Open'. + The open position is in place when a filter on the other filter wheel is being used. #. *G-band* - The G-Band filter allows visible light into the telescope and onto the CCD. XRTpy does not - calculate the effective area or the temperature response for the G-Band filter. + The G-Band filter allows visible light into the telescope and onto the CCD. + XRTpy does not calculate the effective area or the temperature response for the G-Band filter. .. note:: - Filters are expressed by their abbreviation when used in XRTpy. For example, if we want to explore the filter channel - that selects the titanium-on-polyimide filter, then the string would be ``'Ti-poly'``. The process is the same for all XRT - filter channels. -.. image:: images/XRT_filter_wheels_Sun_View_Diagram.png + Filters are expressed by their abbreviation when used in XRTpy. + For example, if we want to explore the filter channel that selects the Titanium Polyimide filter, then the string would be ``'Ti-poly'``. + The process is the same for all XRT filter channels. + +.. image:: _static/images/XRT_filter_wheels_Sun_View_Diagram.png :alt: Diagram of the XRT Filter Wheels :align: center - :scale: 25% .. _CHIANTI: https://www.chiantidatabase.org/chianti_database_history.html .. _SolarSoft XRT Analysis Guide: https://xrt.cfa.harvard.edu/resources/documents/XAG/XAG.pdf diff --git a/docs/glossary.rst b/docs/glossary.rst index 715638b4..ad72dac6 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -1,6 +1,4 @@ -.. currentmodule:: xrtpy - -.. _glossary: +.. _xrtpy-glossary: ******** Glossary diff --git a/docs/images/XRTpy_logo copy.png b/docs/images/XRTpy_logo copy.png deleted file mode 100644 index 44be6548..00000000 Binary files a/docs/images/XRTpy_logo copy.png and /dev/null differ diff --git a/docs/images/hinode_satellite.png b/docs/images/hinode_satellite.png deleted file mode 100644 index b7cb2493..00000000 Binary files a/docs/images/hinode_satellite.png and /dev/null differ diff --git a/docs/index.rst b/docs/index.rst index 678f2edc..213cc318 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,38 +1,27 @@ -:tocdepth: 2 - .. _xrtpy-documentation: -.. image:: images/XRTpy_logo.png - :alt: XRTpy logo - :align: right - :scale: 40% - -################### +******************* 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`. +.. image:: _static/images/XRTpy_logo.png + :alt: XRTpy logo + +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 about_xrt + install getting_started examples + reference/index + acknowledging_xrtpy bibliography glossary - changelog/index feedback_communication - CODE_OF_CONDUCT contributing/index - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` + CODE_OF_CONDUCT + changelog/index diff --git a/docs/install.rst b/docs/install.rst index dda5da8b..a9aacafc 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -4,220 +4,132 @@ Installing XRTpy **************** -.. 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. +There are many ways to install Python, but even if you have Python installed somewhere on your computer we recommend following these instructions anyway. +That's because we will create a new Python environment. +As well as containing a Python installation, this environment provides an isolated place to install Python packages (like ``xrtpy``) without affecting any other current Python installation. +If you already have Python and ``conda`` working you can skip the next section. +Please note that XRTpy requires Python_ |minpython| or newer. .. 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 ∼March, then try installing it on the - second most recent version. - -.. _install-pip: + 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 ∼March, then try installing it on the second most recent version. -Installing XRTpy with pip -============================ +`If you are using Anaconda, we recommend that you uninstall it as the default package channel(s) have a restrictive license which means you might not be able to use it for free `__. +Instead, we recommend that you use miniforge which is a minimal installer that setups conda with the conda-forge channel, which is free to use for everyone. +If you are using miniforge, you can skip the next section -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: +Installing miniforge +-------------------- -.. code-block:: bash +If you don't already have a Python installation then we recommend installing Python with `miniforge `__. +This will install ``conda`` and automatically configure the default channel (a channel is a remote software repository) to be ``conda-forge``, which is where ``sunpy`` is available. - python -m pip install xrtpy +First, download the installer for your system and architecture from the links below: -On some systems, it might be necessary to specify the Python_ version -number by using ``python3``, ``python3.9``, ``python3.10``, or -``python3.11`` instead of ``python``. +.. grid:: 3 -To install XRTpy on Windows, run: + .. grid-item-card:: Linux -.. code-block:: bash + `x86-64 `__ - py -3.10 -m pip install xrtpy + `aarch64 `__ -The version of Python_ may be changed from ``3.10`` to another supported -Python |minpython|\ + release that has been installed on your computer. + `ppc64le `__ -For more detailed information, please refer to this tutorial on -`installing packages`_. + .. grid-item-card:: Windows + :link: https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Windows-x86_64.exe -.. _install-conda: + `x86-64 `__ -Installing XRTpy with Conda -============================== + .. grid-item-card:: Mac -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_. + `x86-64 `__ -After `installing Conda`_ or miniconda_, `xrtpy` can be installed -into an activated Conda_ environment by opening a terminal and running: + `arm64 (Apple + Silicon) `__ -.. code-block:: bash +Then select your platform to install miniforge: - conda install -c conda-forge xrtpy +.. tab-set:: -Here ``-c conda-forge`` indicates that `xrtpy` should be installed -from the conda-forge_ channel. + .. tab-item:: Linux & Mac + :sync: platform -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. + Linux & Mac Run the script downloaded above, with + ``bash ``. The following should work: -To create a new environment with `xrtpy` installed in it, run: + .. code-block:: console -.. code-block:: bash + bash Miniforge3-$(uname)-$(uname -m).sh - conda create -n env_name -c conda-forge xrtpy + Once the installer has completed, close and reopen your terminal. -where :samp:`{env_name}` is replaced by the name of the environment. To -activate this environment, run: + .. tab-item:: Windows + :sync: platform -.. code-block:: bash + Double click the executable file downloaded from + the links above. - conda activate env_name + Once the installer has completed you should have a new "miniforge + Prompt" entry in your start menu. -To update `xrtpy` to the most recent version within a currently -activated Conda_ environment, run: +In a new terminal (miniforge Prompt on Windows) run ``conda list`` to test that the install has worked. -.. 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:: +Installing xrtpy +---------------- - 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`_. +To install ``xrtpy``, start by launching a terminal (under a UNIX-like system) or the miniforge Prompt (under Windows). +Now we will create and activate a new virtual environment to install ``xrtpy`` into: -`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`. - -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 ---------------------------------- +.. code-block:: bash -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: + $ conda create --name xrtpy + # Only run the following two lines + # if you have NOT installed miniforge or added conda-forge to your channels + # Do not run these lines if you are using Anaconda + $ conda config --add channels conda-forge + $ conda config --set channel_priority strict + $ conda activate xrtpy -.. code:: bash +In this case the environment is named 'xrtpy'. +Feel free to change this to a different environment name. - git clone https://github.com/xrtpy/xrtpy.git +The benefit of using a virtual environment is that it allows you to install packages without affecting any other Python installation on your system. +This also means you can work on multiple projects (research or coding) with different package requirements without them interfering with each other. -The repository will be cloned inside a new subdirectory called -:file:`xrtpy`. +Now we have a fresh environment we can install ``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. +.. code-block:: bash -Building and installing ------------------------ + $ conda install xrtpy -To install the downloaded version of `xrtpy`, enter the :file:`xrtpy` -directory and run: +This will install ``xrtpy`` and all of its dependencies. +If you want to install another package later, you can run ``conda install ``. -.. code-block:: bash +pip +~~~ - pip install . +This is for installing ``xrtpy`` within a Python environment, where ``pip`` has been used to install all previous packages. +You will want to make sure you are using a `Python virtual environment `__. -If you expect to occasionally edit the source code, instead run: +Once the environment active, to acquire a full ``xrtpy`` installation: .. code-block:: bash - # For Bash - pip install -e .[developer] + $ pip install xrtpy - # For Zsh - 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! +.. warning:: + If you get a ``PermissionError`` this means that you do not have the required administrative access to install new packages to your Python installation. + Do **not** install any Python packages using ``sudo``. + This error implies you have an incorrectly configured virtual environment or it is not activated. .. 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! - -.. _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) + 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! diff --git a/docs/nitpick-exceptions b/docs/nitpick-exceptions new file mode 100644 index 00000000..9d9486a4 --- /dev/null +++ b/docs/nitpick-exceptions @@ -0,0 +1,6 @@ +# Prevents sphinx nitpicky mode picking up on optional +# (see https://github.com/sphinx-doc/sphinx/issues/6861) +# Even if it was "fixed", still broken +py:class optional +# See https://github.com/numpy/numpy/issues/10039 +py:obj numpy.datetime64 diff --git a/docs/notebooks/computing_functions/effective_area.ipynb b/docs/notebooks/computing_functions/effective_area.ipynb deleted file mode 100644 index d37ca8ee..00000000 --- a/docs/notebooks/computing_functions/effective_area.ipynb +++ /dev/null @@ -1,325 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Effective Area Analysis for X-Ray Telescope (XRT)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this example, we will explore the effective areas for different XRT filter channels, considering their respective thicknesses of the CCD contamination layer at a specific date and time. Understanding the effective areas is essential for accurately interpreting and quantifying X-ray signals. Let's dive into the details and calculations below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Import the xrtpy module for X-ray Telescope (XRT) calculations\n", - "import xrtpy" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Contents\n", - "\n", - "1. [Define Filter](#Define-a-Filter-Channel)\n", - "2. [Define Date & Time](#Define-a-date-and-time) \n", - "3. [Effective-Area-Fundamental](#EffectiveAreaFundamental)\n", - "4. [Effective Area Function](#Effective-Area-function)\n", - "5. [Plotting the Effective Area versus Wavelength](#Plotting-the-Effective-Area-versus-Wavelength)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Define a Filter Channel" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[xrtpy- X-Ray Filter Channel]: https://xrtpy.readthedocs.io/en/latest/getting_started.html\n", - "In XRT analysis, the filter channels play a crucial role in determining the effective areas. A filter channel refers to a specific configuration of filter materials. By defining the filter channel appropriately, we can accurately calculate the effective area for a given XRT configuration.\n", - "\n", - "Let's begin by defining a filter channel using its abbreviation. For example, if we want to explore the effective area for an aluminum-on-polyimide filter channel, we need to specify the relevant abbreviation. This step ensures that we consider the correct filter configuration in our calculations. Refer to the [xrtpy- X-Ray Filter Channel] section for more information. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Define the filter channel abbreviation\n", - "Filter = \"Al-poly\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Define a date and time" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[sunpy-time]: https://docs.sunpy.org/en/stable/guide/time.html\n", - "\n", - "Let's consider exploring the data captured approximately a year after the launch date. We need to define a specific date and time. We will use the format \"YYYY-MM-DD HH:MM:SS\" to represent the desired date and time. The date and time can be specified using various formats depending on your preference and data availability. Please refer to the [sunpy-time] documentation for detailed examples and further information on different date and time string formats. \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Define the date and time for analysis\n", - "date_time = \"2007-09-22T22:59:59\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## EffectiveAreaFundamental" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `EffectiveAreaFundamental` object plays a central role in calculating the effective area. It provides a range of functions and properties that are essential for this computation. By utilizing the `EffectiveAreaFundamental` object, we can accurately determine the effective area based on the specified filter channel, date, and time.\n", - "\n", - "To access the functionality of the EffectiveAreaFundamental object, we need to reference it by inserting the defined `Filter` and `date_time`. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Create an instance of the EffectiveAreaFundamental object\n", - "Effective_Area_Fundamental = xrtpy.response.EffectiveAreaFundamental(Filter, date_time)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Effective Area function" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To actually calculate the effective area function we call the `effective_area()` method of the `Effective_Area_Fundamental` object. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate the effective area\n", - "effective_area = Effective_Area_Fundamental.effective_area()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[astropy-quantity]: https://docs.astropy.org/en/stable/api/astropy.units.quantity.Quantity.html\n", - "\n", - "[astropy.units]: https://docs.astropy.org/en/stable/units/index.html\n", - "\n", - "\n", - "The `effective_area` function returns the effective area for a selected filter, date, and time as an [astropy-quantity] with [astropy.units]. \n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(\"Effective Area:\\n\", effective_area)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Plotting the Effective Area versus Wavelength" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To gain insights into the X-ray Telescope (XRT) observations, we will plot the effective area against the corresponding wavelengths. This visualization allows us to understand how the effective area varies across different wavelengths and provides valuable information for interpreting XRT data." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will utilize the `channel_wavelength` property within the Effective_Area_Fundamental object to get the wavelengths. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Wavelength unit in Angstroms A˚\n", - "wavelength = Effective_Area_Fundamental.channel_wavelength" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "To further analyze the effective area data, we will focus on the observations relative to the spacecraft launch date. This will allow us to identify any differences or trends in the effective area during the early stages of the mission. We will define the effective area data for the launch date in the same manner as previously shown." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Create an instance of the EffectiveAreaFundamental object for the launch date and time of the same filter channel\n", - "relative_launch_date_time = \"2006-09-22T22:59:59\"\n", - "\n", - "EAF_launch_date_time = xrtpy.response.EffectiveAreaFundamental(\n", - " Filter, relative_launch_date_time\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# launch date effective area\n", - "launch_date_effective_area = EAF_launch_date_time.effective_area()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create a plotting function that plots the effective area versus wavelegth." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def plot_effective_area():\n", - " import matplotlib.pyplot as plt\n", - "\n", - " plt.figure(figsize=(30, 13))\n", - "\n", - " plt.plot(\n", - " wavelength,\n", - " effective_area,\n", - " linewidth=8,\n", - " label=f\"{Filter} {date_time}\",\n", - " )\n", - "\n", - " plt.plot(\n", - " wavelength,\n", - " launch_date_effective_area,\n", - " linewidth=8,\n", - " label=f\"{Filter} {relative_launch_date_time}\",\n", - " )\n", - "\n", - " plt.title(\"XRT Effective Area\\nAl-Poly\", fontsize=30)\n", - " plt.xlabel(\"Wavelength (Å)\", fontsize=30)\n", - " plt.ylabel(\"Effective Area ($cm^{2}$)\", fontsize=30)\n", - " plt.legend(fontsize=30)\n", - "\n", - " plt.xticks(fontsize=27)\n", - " plt.yticks(fontsize=27)\n", - " plt.xlim(0, 60)\n", - "\n", - " plt.grid(color=\"lightgrey\")\n", - " plt.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Run `plot_effective_area` function to create the plot." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot_effective_area()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[Montana State University Solar Physics site]: http://solar.physics.montana.edu/HINODE/XRT/xrt_contam_db.html \n", - "[Narukage et. al. (2011)]: https://doi.org/10.1007/s11207-010-9685-2 \n", - "\n", - "\n", - "By plotting the effective area at the spacecraft launch date and comparing it to the effective area a year after, we can observe and analyze any differences. These differences arise from variations in the contamination layer thickness on the CCD which blocks some of the X-rays thus reducing the effective area. For detailed information about the calculation of the XRT CCD contaminant layer thickness, you can refer to the [Montana State University Solar Physics site].\n", - "\n", - "To further understand the factors contributing to the observed differences, additional information can be found in the research paper by [Narukage et. al. (2011)]. This paper provides valuable insights into the characteristics and behavior of the XRT instrument, which can aid in interpreting the effective area data." - ] - } - ], - "metadata": { - "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.11.0" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/notebooks/computing_functions/temperature_response.ipynb b/docs/notebooks/computing_functions/temperature_response.ipynb deleted file mode 100644 index 33fa6705..00000000 --- a/docs/notebooks/computing_functions/temperature_response.ipynb +++ /dev/null @@ -1,384 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "651705ab", - "metadata": {}, - "source": [ - "# Temperature Response Analysis for X-Ray Telescope (XRT)" - ] - }, - { - "cell_type": "markdown", - "id": "fa939b73", - "metadata": {}, - "source": [ - "This notebook explores the temperature response of X-ray channels in the X-Ray Telescope (XRT). The temperature response provides valuable insights into how the XRT instrument detects and responds to different temperatures of X-ray emissions. By assuming a specific spectral emission model at a given date, we can investigate the behavior of the XRT channels." - ] - }, - { - "cell_type": "markdown", - "id": "cf0b72e9", - "metadata": {}, - "source": [ - "To begin the analysis, we will import the necessary packages that enable us to perform the temperature response calculations and generate visualizations." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3adc142e", - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "\n", - "import xrtpy" - ] - }, - { - "cell_type": "markdown", - "id": "aeaf3280", - "metadata": {}, - "source": [ - "Let's dive in and explore the fascinating temperature response characteristics of the XRT!" - ] - }, - { - "cell_type": "markdown", - "id": "c15461c5", - "metadata": {}, - "source": [ - "## Contents\n", - "\n", - "1. [Define a Filter Channel](#Define-a-Filter-Channel)\n", - "2. [Define Date & Time](#Define-a-date-and-time) \n", - "3. [Temperature-Response-Fundamental](#TemperatureResponseFundamental)\n", - "4. [Temperature Response Function](#Temperature-Response-function)\n", - "5. [Plot Temperature Response](#Plotting-the-Temperature-Response)" - ] - }, - { - "cell_type": "markdown", - "id": "14415906", - "metadata": {}, - "source": [ - "## Define a Filter Channel" - ] - }, - { - "cell_type": "markdown", - "id": "14a820fe", - "metadata": {}, - "source": [ - "[xrtpy- X-Ray Filter Channel]: https://xrtpy.readthedocs.io/en/latest/getting_started.html\n", - "\n", - "A filter channel is defined by its common abbreviation, which represents a specific type of filter used to modify the X-ray radiation passing through. In this example, we will explore the carbon-on-polyimide filter (abbreviated as \"C-poly\").\n", - "\n", - "For detailed information about various filter channels and their characteristics, you can refer to the [xrtpy- X-Ray Filter Channel] section.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "745b98ae", - "metadata": {}, - "outputs": [], - "source": [ - "filter_ = \"C-poly\"" - ] - }, - { - "cell_type": "markdown", - "id": "f1dba447", - "metadata": {}, - "source": [ - "## Define a date and time" - ] - }, - { - "cell_type": "markdown", - "id": "9434fb73", - "metadata": {}, - "source": [ - "[sunpy-time]: https://docs.sunpy.org/en/stable/guide/time.html\n", - "\n", - "In order to analyze the temperature response, it is necessary to specify a date and time for the analysis. The date and time can be defined together using specific string formats. To explore the data captured a year after the launch date, we will define the date and time accordingly.\n", - "\n", - "For detailed examples and further information about date and time string formats, you can refer to the [sunpy-time] documentation." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3268b4b9", - "metadata": {}, - "outputs": [], - "source": [ - "date_time = \"2007-09-22T21:59:59\"" - ] - }, - { - "cell_type": "markdown", - "id": "8a98f3d5", - "metadata": {}, - "source": [ - "## TemperatureResponseFundamental" - ] - }, - { - "cell_type": "markdown", - "id": "b113a3ef", - "metadata": {}, - "source": [ - "The `TemperatureResponseFundamental` object is a crucial component that provides all the necessary functions and properties for calculating the temperature response in our analysis. By referencing this object, we can access the required methods and attributes for further calculations.\n", - "\n", - "To create a `TemperatureResponseFundamental` object, you need to provide the defined filter channel (`Filter`) and the desired date and time (`date_time`). Additionally, you can specify the abundance model of interest, such as `Photospheric`, which influences the temperature response calculations.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d8a24315", - "metadata": {}, - "outputs": [], - "source": [ - "Temperature_Response_Fundamental = xrtpy.response.TemperatureResponseFundamental(\n", - " filter_, date_time, abundance_model=\"Photospheric\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "453dbe8c", - "metadata": {}, - "source": [ - "## Temperature Response function" - ] - }, - { - "cell_type": "markdown", - "id": "f56c4b89", - "metadata": {}, - "source": [ - "\n", - "To calculate the temperature response, simply call the `temperature_response()` function on the `Temperature_Response_Fundamental` object. This function utilizes the specified filter, date, and abundance model to generate the temperature response as a result.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5dc098fd", - "metadata": {}, - "outputs": [], - "source": [ - "temperature_response = Temperature_Response_Fundamental.temperature_response()" - ] - }, - { - "cell_type": "markdown", - "id": "07a2b8ed", - "metadata": {}, - "source": [ - "[astropy-quantity]: https://docs.astropy.org/en/stable/api/astropy.units.quantity.Quantity.html\n", - "\n", - "[astropy.units]: https://docs.astropy.org/en/stable/units/index.html\n", - "\n", - "The `temperature_response()` function returns the temperature response for the selected filter, date, and time. The returned value is an [astropy-quantity] object with associated [astropy.units]." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0961f9e5", - "metadata": {}, - "outputs": [], - "source": [ - "print(\"Temperature Response:\\n\", temperature_response)" - ] - }, - { - "cell_type": "markdown", - "id": "b94ac326", - "metadata": {}, - "source": [ - "## Plotting the Temperature-Response" - ] - }, - { - "cell_type": "markdown", - "id": "b23d6157", - "metadata": {}, - "source": [ - "[chiantidatrbase.org]: https://www.chiantidatabase.org/\n", - "\n", - "In this section, we will visualize the temperature response by plotting the `temperature_response` function against the corresponding temperatures. It's important to note that the CHIANTI temperatures used in this plot are the temperatures of the solar plasma and are independent of the channel filter.\n", - "\n", - "The CHIANTI temperatures are stored in the `Temperature_Response_Fundamental` object and are provided in units of Kelvin (K). These temperatures serve as the independent variable for plotting the temperature response.\n", - "\n", - "By visualizing the temperature response, we can gain insights into how it varies with respect to temperature, providing a deeper understanding of the XRT channelcharacteristics.\n", - "\n", - "Additionally, if you wish to explore more details about the CHIANTI database, you can find further information at [chiantidatrbase.org].\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bc2b0b98", - "metadata": {}, - "outputs": [], - "source": [ - "CHIANTI_temperature = Temperature_Response_Fundamental.CHIANTI_temperature" - ] - }, - { - "cell_type": "markdown", - "id": "1e5be3e3", - "metadata": {}, - "source": [ - "[numpy.log10]: https://numpy.org/doc/stable/reference/generated/numpy.log10.html\n", - "We take the log of the `CHIANTI_temperature` for plotting, which compresses the scale and enhances the visibility of the variations for lower temperatures.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0a247d01", - "metadata": {}, - "outputs": [], - "source": [ - "log_CHIANTI_temperature = np.log10(CHIANTI_temperature.value)" - ] - }, - { - "cell_type": "markdown", - "id": "e0d954e8", - "metadata": {}, - "source": [ - "In addition, we will compare the data shortly after the spacecraft launch date with the current data. This allows us to identify any differences or variations in the temperature response over time.\n", - "\n", - "We define a new temperature response data for the launch date. The process for obtaining this data is the same as previously shown, where we specify the filter, launch date, and abundance model.\n", - "\n", - "By comparing the temperature response at the launch date with the current temperature response, we can gain insights into any changes that may have occurred over time. This comparison helps us understand the stability and evolution of the XRT." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01876a0b", - "metadata": {}, - "outputs": [], - "source": [ - "launch_date_time = \"2006-09-22T23:59:59\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0a31f268", - "metadata": {}, - "outputs": [], - "source": [ - "launch_date_temperature_response = xrtpy.response.TemperatureResponseFundamental(\n", - " filter_, launch_date_time, abundance_model=\"Photospheric\"\n", - ").temperature_response()" - ] - }, - { - "cell_type": "markdown", - "id": "eeb2df4c", - "metadata": {}, - "source": [ - "Create a plotting function that plots the `temperature_response` versus `log_CHIANTI_temperature` for the chosen filter, date, and time. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6868a101", - "metadata": {}, - "outputs": [], - "source": [ - "def plotting_temperature_response():\n", - " plt.figure(figsize=(30, 12))\n", - "\n", - " plt.plot(\n", - " log_CHIANTI_temperature,\n", - " np.log10(temperature_response.value),\n", - " linewidth=4,\n", - " label=f\"{filter_} {date_time}\",\n", - " )\n", - " plt.plot(\n", - " log_CHIANTI_temperature,\n", - " np.log10(launch_date_temperature_response.value),\n", - " linewidth=3,\n", - " label=f\"{filter_} {launch_date_time}\",\n", - " color=\"red\",\n", - " )\n", - "\n", - " plt.title(\"XRT Temperature Response\", fontsize=30)\n", - " plt.xlabel(\"Log(T) ($K$)\", fontsize=27)\n", - " plt.ylabel(\"$DN$ $cm^5$ $ s^-1$ $pix^-1$\", fontsize=27)\n", - " plt.legend(fontsize=30)\n", - "\n", - " plt.xticks(fontsize=25)\n", - " plt.yticks(fontsize=25)\n", - "\n", - " plt.grid()\n", - " plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "967f1713", - "metadata": {}, - "source": [ - "Run `plotting_temperature_response` function to create the plot." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9f36b383", - "metadata": {}, - "outputs": [], - "source": [ - "plotting_temperature_response()" - ] - }, - { - "cell_type": "markdown", - "id": "a116ead0", - "metadata": {}, - "source": [ - "[Montana State University Solar Physics site]: http://solar.physics.montana.edu/HINODE/XRT/xrt_contam_db.html\n", - "[Narukage et. al. (2011)]: https://doi.org/10.1007/s11207-010-9685-2 \n", - "\n", - "Plotting the temperature response at launch date and a year after highlights the differences. This is due to the contamination layer thickness on the CCD. Information about the XRT CCD contaminant layer thickness calculation can be found at [Montana State University Solar Physics site]. In addition, more information can be found referencing [Narukage et. al. (2011)]." - ] - } - ], - "metadata": { - "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.11.0" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/notebooks/data_analysis/Deconvolving_XRT_images.ipynb b/docs/notebooks/data_analysis/Deconvolving_XRT_images.ipynb deleted file mode 100644 index 900faee7..00000000 --- a/docs/notebooks/data_analysis/Deconvolving_XRT_images.ipynb +++ /dev/null @@ -1,120 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "1aa7ee5e", - "metadata": {}, - "source": [ - "# Using deconvolve to deconvolve images" - ] - }, - { - "cell_type": "markdown", - "id": "e3ee1e4a", - "metadata": {}, - "source": [ - "deconvolve can sharpen images using the point spread function derived for Hinode XRT " - ] - }, - { - "cell_type": "markdown", - "id": "6d3ff603", - "metadata": {}, - "source": [ - "Deconvolution is ordinarily used when wanting to remove the blurring around sharp objects or features caused by the telescope's point spread function. Here we show an example of its use for an XRT image taken during the transit of Venus in 2012. We download this data from the VSO using methods in SunPy." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4442702b", - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import sunpy.map\n", - "from sunpy.net import Fido\n", - "from sunpy.net import attrs as a\n", - "\n", - "from xrtpy.image_correction.deconvolve import deconvolve\n", - "\n", - "# Search for the data with a define time range and instrument\n", - "result = Fido.search(\n", - " a.Time(\"2012-06-05 21:58:39\", \"2012-06-05 21:59:00\"), a.Instrument(\"xrt\")\n", - ")\n", - "\n", - "data_file = Fido.fetch(result[0], progress=False)" - ] - }, - { - "cell_type": "markdown", - "id": "9414720e", - "metadata": {}, - "source": [ - "deconvolve takes a SunPy map as input and returns the deconvolved image and metadata as a SunPy map." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ebd15dbb", - "metadata": {}, - "outputs": [], - "source": [ - "# Create sunpy map from the fetched data\n", - "in_map = sunpy.map.Map(data_file)\n", - "\n", - "# Apply xrtpy deconvolution\n", - "out_map = deconvolve(in_map)" - ] - }, - { - "cell_type": "markdown", - "id": "3c34a2a1", - "metadata": {}, - "source": [ - "deconvolve uses the Richardson-Lucy deconvolution algorithm and takes a few optional input parameters including niter (no. of iterations to perform, 5 by default), pdf1keV (to use the point spread function defined at 1.0 keV rather than the default one defined at 560 eV) and verbose (False by default). Above we just used the default settings.\n", - "\n", - "To see the effects of the deconvolution we plot both the input and output images:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "94a60a68", - "metadata": {}, - "outputs": [], - "source": [ - "# Plotting the original and deconvolved images\n", - "fig = plt.figure(figsize=(10, 5))\n", - "ax1 = fig.add_subplot(1, 2, 1, projection=in_map)\n", - "in_map.plot(axes=ax1, title=\"Original Image\")\n", - "ax2 = fig.add_subplot(1, 2, 2, projection=out_map)\n", - "out_map.plot(axes=ax2, title=\"Deconvolved Image\")\n", - "fig.subplots_adjust(wspace=0.5)\n", - "plt.show()" - ] - } - ], - "metadata": { - "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.8.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/notebooks/data_analysis/Remove_lightleak.ipynb b/docs/notebooks/data_analysis/Remove_lightleak.ipynb deleted file mode 100644 index b300a1e9..00000000 --- a/docs/notebooks/data_analysis/Remove_lightleak.ipynb +++ /dev/null @@ -1,149 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a74f630b", - "metadata": {}, - "source": [ - "# Using the `remove_lightleak` function to analyze XRT composite images" - ] - }, - { - "cell_type": "markdown", - "id": "1ad4f399", - "metadata": {}, - "source": [ - "The `remove_lightleak` function is built to subtract light leak (visible stray light) image from XRT synoptic composite images. Level two synoptic composite image data is available at [xrt.cfa.harvard.edu](https://xrt.cfa.harvard.edu/data_products/index.php). This template will guide you through the method of using `remove_lightleak`." - ] - }, - { - "cell_type": "markdown", - "id": "5dfaf58c", - "metadata": {}, - "source": [ - "Begin by importing `remove_lightleak` function from XRTpy." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bc3b75d9", - "metadata": {}, - "outputs": [], - "source": [ - "from pathlib import Path\n", - "\n", - "import sunpy.map" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "57a48df5", - "metadata": {}, - "outputs": [], - "source": [ - "from astropy.utils.data import get_pkg_data_path\n", - "\n", - "from xrtpy.image_correction.remove_lightleak import remove_lightleak" - ] - }, - { - "cell_type": "markdown", - "id": "afe208c1", - "metadata": {}, - "source": [ - "This example will be using XRT synoptic data from the first day of summer of 2015." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d9e2a205", - "metadata": {}, - "outputs": [], - "source": [ - "directory = get_pkg_data_path(\"example_data\", package=\"xrtpy.image_correction.data\")\n", - "data_file = Path(directory) / \"comp_XRT20150621_055911.7.fits\"\n", - "\n", - "print(\"File used:\\n\", data_file.name)" - ] - }, - { - "cell_type": "markdown", - "id": "1d1c92c7", - "metadata": {}, - "source": [ - "Take on [`sunpy.map.Map`](https://docs.sunpy.org/en/stable/code_ref/map.html) to run the composite data file." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e2a1f65c", - "metadata": {}, - "outputs": [], - "source": [ - "in_map = sunpy.map.Map(data_file)" - ] - }, - { - "cell_type": "markdown", - "id": "e1b239db", - "metadata": {}, - "source": [ - "The `remove_lightleak` function takes a [`sunpy.map.Map`](https://docs.sunpy.org/en/stable/code_ref/map.html) as input and returns the composite image and metadata as a `Map`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6144be5e", - "metadata": {}, - "outputs": [], - "source": [ - "out_map = remove_lightleak(in_map)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bc66b8e2", - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "from matplotlib.colors import LogNorm\n", - "\n", - "fig = plt.figure()\n", - "ax1 = fig.add_subplot(1, 2, 1, projection=in_map)\n", - "in_map.plot(axes=ax1, title=\"Original Image\", norm=LogNorm(1.0, None))\n", - "ax2 = fig.add_subplot(1, 2, 2, projection=out_map)\n", - "out_map.plot(axes=ax2, title=\"Light Leak Subtracted Image\", norm=LogNorm(1.0, None))\n", - "fig.subplots_adjust(wspace=0.5)\n", - "plt.show()" - ] - } - ], - "metadata": { - "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.8.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/notebooks/data_analysis/Temperature_using_composites.ipynb b/docs/notebooks/data_analysis/Temperature_using_composites.ipynb deleted file mode 100644 index 98e9f7cd..00000000 --- a/docs/notebooks/data_analysis/Temperature_using_composites.ipynb +++ /dev/null @@ -1,156 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "84f543ec", - "metadata": {}, - "source": [ - "# Deriving temperatures using composite images and the filter ratio method" - ] - }, - { - "cell_type": "markdown", - "id": "210dadd6", - "metadata": {}, - "source": [ - "The `temperature_from_filter_ratio` routine in XTRpy derives the temperature and emission measure in XRT images by using two images taken at nearly the same time but using different filters. When doing this you can use standard XRT Level 1 data files or you can use \"composite\" images. Composite images are created from two or three images taken sequentially with the same pointing and filter but with different exposure times. Generally one wants to use either a long and short pair of exposures or a long-medium-short triple of exposures. Such composite images are made routinely for the synoptic archive of Hinode. The idea behind composite images is that pixels in the image that are saturated in the long exposure are replaced by pixels from the short (or medium) exposure that are not saturated and thus create an image with a greater dynamic range than you would get with a single image." - ] - }, - { - "cell_type": "markdown", - "id": "a2a60e43", - "metadata": {}, - "source": [ - "We start by importing `temperature_from_filter_ratio`." - ] - }, - { - "cell_type": "markdown", - "id": "03904c0f", - "metadata": {}, - "source": [ - "To use composite images, we need to generate their exposure maps, which are images where each pixel value is the exposure time of the image from which the pixel came. Most of the pixels will generally be from the long exposure image, but for the brightest part of the image, the pixels will come from the medium or short exposure image that was used to generate the composite image. The composite images that we'll use can be downloaded from the XRT archive." - ] - }, - { - "cell_type": "markdown", - "id": "93c47f6b", - "metadata": {}, - "source": [ - "For this example, we will use the `download_file` utility from `astropy` to download the composite files. We also use the routine `filename2repo_path` from `XRTpy` to find the correct URL for each file to be downloaded." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ef4d8a39", - "metadata": {}, - "outputs": [], - "source": [ - "from astropy.utils.data import download_file\n", - "\n", - "from xrtpy.response.temperature_from_filter_ratio import temperature_from_filter_ratio\n", - "from xrtpy.util.filename2repo_path import filename2repo_path\n", - "\n", - "filename1 = \"comp_XRT20210730_175810.1.fits\"\n", - "filename2 = \"comp_XRT20210730_175831.6.fits\"\n", - "url1 = filename2repo_path(filename1, join=True)\n", - "url2 = filename2repo_path(filename2, join=True)\n", - "# These files will go under your astropy cache directory, typically ~/.astropy/cache/download/url/\n", - "file1 = download_file(url1, allow_insecure=True)\n", - "file2 = download_file(url2, allow_insecure=True)" - ] - }, - { - "cell_type": "markdown", - "id": "51b1846e", - "metadata": {}, - "source": [ - "Then we need to calculate the exposure maps, which will be used with `temperature_from_filter_ratio`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "74e3e2d1", - "metadata": {}, - "outputs": [], - "source": [ - "from xrtpy.util.make_exposure_map import make_exposure_map\n", - "\n", - "expmap1 = make_exposure_map(file1)\n", - "expmap2 = make_exposure_map(file2)" - ] - }, - { - "cell_type": "markdown", - "id": "a6374f89", - "metadata": {}, - "source": [ - "Note that each call to this routine will result in more files being downloaded. Now we are ready to call `temperature_from_filter_ratio`. This routine takes Sunpy maps as input (not related to exposure maps)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "78cc7ab9", - "metadata": {}, - "outputs": [], - "source": [ - "from sunpy.map import Map\n", - "\n", - "map1 = Map(file1)\n", - "map2 = Map(file2)\n", - "T_EM = temperature_from_filter_ratio(map1, map2, expmap1=expmap1, expmap2=expmap2)" - ] - }, - { - "cell_type": "markdown", - "id": "49ec6f18", - "metadata": {}, - "source": [ - "`temperature_from_filter_ratio` returns a named tuple of maps: Tmap, EMmap, Terrmap, EMerrmap. To make a nice looking plot, we use `matplotlib`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4d3fd2bd", - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "fig = plt.figure()\n", - "T_e = T_EM.Tmap\n", - "m = Map(10.0**T_e.data, T_e.meta)\n", - "m.plot(vmin=8.0e5, vmax=3.0e6, cmap=\"turbo\")\n", - "m.draw_limb()\n", - "m.draw_grid()\n", - "cb = plt.colorbar()\n", - "plt.show()" - ] - } - ], - "metadata": { - "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.8.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/notebooks/data_analysis/Using_temperature_from_filter_ratio.ipynb b/docs/notebooks/data_analysis/Using_temperature_from_filter_ratio.ipynb deleted file mode 100644 index fa5501a5..00000000 --- a/docs/notebooks/data_analysis/Using_temperature_from_filter_ratio.ipynb +++ /dev/null @@ -1,257 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "642ac1b3", - "metadata": {}, - "source": [ - "# Using temperature_from_filter_ratio to analyze XRT data" - ] - }, - { - "cell_type": "markdown", - "id": "22b53fce", - "metadata": {}, - "source": [ - "This example demonstrates how to use the `temperature_from_filter_ratio` function from `xrtpy` to calculate the XRT temperature and emission measure in an image using the filter ratio method.\n", - "\n", - "**Note**: To run this example, you need additional dependencies. If you installed `xrtpy` from pip, you might need to install `sunpy[net]` separately. You can do this by running:\n", - "\n", - "```pip install sunpy[net]```" - ] - }, - { - "cell_type": "markdown", - "id": "f5f04496", - "metadata": {}, - "source": [ - "First we need to import `temperature_from_filter_ratio`." - ] - }, - { - "cell_type": "markdown", - "id": "8aee2bae", - "metadata": {}, - "source": [ - "As an example we will use the test data included in XRTpy, though data with the right characteristics in the XRT archive could also be used. It's necessary to use two images that are the same size and different filters. To get good results the images should have been taken close in time as well, ideally adjacent in time. Note that not all filter ratios produce good results. \n", - "\n", - "This data was generated using the IDL routine xrt_prep.pro from SolarSoft and is unnormalized. Data in the Level 1 archive are normalized, which is also okay to use, though the IDL routine `xrt_teem.pro` did not allow that. For normalized data the image data is multiplied by the exposure time before analysis. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b0dbae75", - "metadata": {}, - "outputs": [], - "source": [ - "import sunpy.map\n", - "from sunpy.net import Fido\n", - "from sunpy.net import attrs as a\n", - "\n", - "from xrtpy.response.temperature_from_filter_ratio import temperature_from_filter_ratio" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "da83268f", - "metadata": {}, - "outputs": [], - "source": [ - "result = Fido.search(\n", - " a.Time(\"2011-01-28 01:31:55\", \"2011-01-28 01:32:05\"), a.Instrument(\"xrt\")\n", - ")\n", - "\n", - "data_files = Fido.fetch(result, progress=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "681f4be1", - "metadata": {}, - "outputs": [], - "source": [ - "file1 = data_files[1]\n", - "file2 = data_files[0]\n", - "print(\"Files used:\\n\", file1, \"\\n\", file2)" - ] - }, - { - "cell_type": "markdown", - "id": "35dd0c83", - "metadata": {}, - "source": [ - "[Sunpy maps]:https://docs.sunpy.org/en/stable/code_ref/map.html\n", - "\n", - "`temperature_from_filter_ratio` uses [Sunpy maps] as input. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "48ac4220", - "metadata": {}, - "outputs": [], - "source": [ - "map1 = sunpy.map.Map(file1)\n", - "map2 = sunpy.map.Map(file2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "20f21153", - "metadata": {}, - "outputs": [], - "source": [ - "print(\n", - " map1.fits_header[\"TELESCOP\"],\n", - " map1.fits_header[\"INSTRUME\"],\n", - ")\n", - "print(\n", - " \"\\n File 1 used:\\n\",\n", - " file1,\n", - " \"\\n Observation date:\",\n", - " map1.fits_header[\"DATE_OBS\"],\n", - " map1.fits_header[\"TIMESYS\"],\n", - " \"\\n Filter Wheel 1:\",\n", - " map1.fits_header[\"EC_FW1_\"],\n", - " map1.fits_header[\"EC_FW1\"],\n", - " \"\\n Filter Wheel 2:\",\n", - " map1.fits_header[\"EC_FW2_\"],\n", - " map1.fits_header[\"EC_FW2\"],\n", - " \"\\n Dimension:\",\n", - " map1.fits_header[\"NAXIS1\"],\n", - " map1.fits_header[\"NAXIS1\"],\n", - ")\n", - "\n", - "print(\n", - " \"\\nFile 2 used:\\n\",\n", - " file2,\n", - " \"\\n Observation date:\",\n", - " map2.fits_header[\"DATE_OBS\"],\n", - " map2.fits_header[\"TIMESYS\"],\n", - " \"\\n Filter Wheel 1:\",\n", - " map2.fits_header[\"EC_FW1_\"],\n", - " map2.fits_header[\"EC_FW1\"],\n", - " \"\\n Filter Wheel 2:\",\n", - " map2.fits_header[\"EC_FW2_\"],\n", - " map2.fits_header[\"EC_FW2\"],\n", - " \"\\n Dimension:\",\n", - " map2.fits_header[\"NAXIS1\"],\n", - " map2.fits_header[\"NAXIS1\"],\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "905f4e11", - "metadata": {}, - "source": [ - "The `temperature_from_filter_ratio` function has several options, mirroring the IDL routine xrt_teem.pro in SolarSoft in most respects. A simple call with no extra parameters calculates the temperature and (volume) emission measure for the two images without any binning or masking of the data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ddc9862b", - "metadata": {}, - "outputs": [], - "source": [ - "T_EM = temperature_from_filter_ratio(map1, map2)\n", - "T_e = T_EM.Tmap" - ] - }, - { - "cell_type": "markdown", - "id": "d0ef85f3", - "metadata": {}, - "source": [ - "The output of `temperature_from_filter_ratio` is a namedtuple of SunPy maps with attributes `Tmap`, `EMmap`, `Terrmap`, and `EMerrmap`. As with the SolarSoft IDL routine xrt_teem.pro, the output images are logs of the quantities. `Tmap.data` is the electron temperature, `EMmap.data` is the volume emission measure, `Terrmap.data` is a measure of the uncertainties in the temperature determined for each pixel and `EMerrmap.data` is the same for the emission measure. Each map has data and associated metadata. To examine the results one can use `matplotlib` and `sunpy`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3ae1f53b", - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from sunpy.coordinates.sun import B0, angular_radius\n", - "from sunpy.map import Map\n", - "\n", - "# To avoid error messages from sunpy we add metadata to the header:\n", - "rsun_ref = 6.95700e08\n", - "hdr1 = map1.meta\n", - "rsun_obs = angular_radius(hdr1[\"DATE_OBS\"]).value\n", - "dsun = rsun_ref / np.sin(rsun_obs * np.pi / 6.48e5)\n", - "solarb0 = B0(hdr1[\"DATE_OBS\"]).value\n", - "hdr1[\"DSUN_OBS\"] = dsun\n", - "hdr1[\"RSUN_REF\"] = rsun_ref\n", - "hdr1[\"RSUN_OBS\"] = rsun_obs\n", - "hdr1[\"SOLAR_B0\"] = solarb0\n", - "\n", - "fig = plt.figure()\n", - "# We could create a plot simply by doing T_e.plot(), but here we choose to make a linear plot of T_e\n", - "m = Map((10.0**T_e.data, T_e.meta))\n", - "m.plot(title=\"Derived Temperature\", vmin=2.0e6, vmax=1.2e7, cmap=\"turbo\")\n", - "m.draw_limb()\n", - "m.draw_grid(linewidth=2)\n", - "cb = plt.colorbar(label=\"T (K)\")" - ] - }, - { - "cell_type": "markdown", - "id": "4e069966", - "metadata": {}, - "source": [ - "See the temperature_from_filter_ratio.py script for more information. Among the options are verbose output, binning the data by an integer factor (to increase the signal to noise), specifying a temperature range to examine, providing a mask for excluding regions of the images from the analysis, and setting error thresholds on the temperature and photon noise that differ from the default values." - ] - }, - { - "cell_type": "markdown", - "id": "94df8fee", - "metadata": {}, - "source": [ - "[Narukage et al. (2014, Solar Phys. 289, 1029)]:https://xrtpy.readthedocs.io/en/stable/bibliography.html\n", - "[Guidoni et al. (2015, ApJ 800, 54)]:https://xrtpy.readthedocs.io/en/stable/bibliography.html\n", - "\n", - "\n", - "These data were analyzed by [Guidoni et al. (2015, ApJ 800, 54)]. See also [Narukage et al. (2014, Solar Phys. 289, 1029)]. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9fb5dcfa-f5c8-4a80-bf8e-442afe4916b6", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "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.8.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/notebooks/getting_started/A_Practical_Guide_to_Data_Extraction_and_Visualization.ipynb b/docs/notebooks/getting_started/A_Practical_Guide_to_Data_Extraction_and_Visualization.ipynb deleted file mode 100644 index 1d41d727..00000000 --- a/docs/notebooks/getting_started/A_Practical_Guide_to_Data_Extraction_and_Visualization.ipynb +++ /dev/null @@ -1,1176 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "5889d1e9", - "metadata": {}, - "source": [ - "[Hinode X-Ray Telescope]:https://xrt.cfa.harvard.edu/\n", - "\n", - "# Hinode-XRT: A Practical Guide to Data Extraction and Visualization\n", - "\n", - "This notebook provides a step-by-step guide on how to download, process, and visualize solar observation data from the [Hinode X-Ray Telescope], making it accessible for research and analysis.\n", - "\n", - "*Created by Joy Velasquez. Version 1 - February 29, 2024*" - ] - }, - { - "cell_type": "markdown", - "id": "2c79b374", - "metadata": {}, - "source": [ - "## Introduction\n", - "\n", - "This notebook is designed as a preliminary guide to handle solar observation data specifically from the Hinode X-Ray Telescope (XRT). While this example does not directly utilize `xrtpy` functionalities, it lays the groundwork for handling and understanding XRT data, which can be further processed and analyzed using `xrtpy`.\n", - "\n", - "Here's what we'll cover:\n", - "- **Downloading XRT Data**: Step-by-step instructions to download XRT data for a specified period of interest.\n", - "- **Data Filtering**: Use custom functions for filtering and refining the downloaded data.\n", - "- **Visualization and Movie Creation**: Explore methods to visualize the data and compile it into movie format, providing a dynamic view of solar observations.\n", - "\n", - "Whether for research analysis or as a stepping stone to using `xrtpy` for more advanced applications, this guide aims to equip you with the fundamental skills necessary for effective data manipulation and visualization in solar physics. \n" - ] - }, - { - "cell_type": "markdown", - "id": "99e5293f", - "metadata": {}, - "source": [ - "## Table of Contents\n", - "1. [Importing Necessary Packages](#importing-necessary-packages)\n", - "2. [Using Fido to Search and Download XRT Data](#using-fido-to-search-and-download-xrt-data)\n", - "3. [Inspecting the Downloaded Data](#inspecting-the-downloaded-data)\n", - "4. [Exploring Functions to Enhance Data Quality](#exploring-functions-to-enhance-data-quality)\n", - " - 4.1 [Filtering FITS Files Through Selected Filter](#filtering-fits-files-through-selected-filter)\n", - " - 4.2 [Filtering FITS Files Through Pixel Size](#filtering-fits-files-through-pixel-size)\n", - " - 4.3 [Filtering FITS Files by Exposure Time](#filtering-fits-files-by-exposure-time)\n", - "5. [Navigating FITS Images](#navigating-fits-images)\n", - "6. [Removing Unwanted FITS Files](#removing-unwanted-fits-files)\n", - "7. [Visualizing Solar Dynamics by Creating a Movie from XRT FITS Data](#visualizing-solar-dynamics-by-creating-a-movie-from-xrt-fits-data)\n" - ] - }, - { - "cell_type": "markdown", - "id": "b8c49bf6", - "metadata": {}, - "source": [ - "### Importing Necessary Packages" - ] - }, - { - "cell_type": "markdown", - "id": "76671fc6", - "metadata": {}, - "source": [ - "Before we begin, let's import all the necessary Python packages and modules required for this notebook. Key packages include:\n", - "\n", - "- `sunpy`: An open-source Python library for Solar Physics data analysis.\n", - "- `matplotlib`: A library for creating static, animated, and interactive visualizations in Python.\n", - "- `astropy`: Used for astronomy and astrophysics data processing.\n", - "\n", - "These packages, among others, will enable us to download, inspect, filter, and visualize the XRT data effectively.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cbbd8a2d", - "metadata": {}, - "outputs": [], - "source": [ - "# Standard library imports for file and temporary directory management\n", - "import os\n", - "import tempfile\n", - "\n", - "# Counting occurrences of unique elements\n", - "# creating and managing images and videos\n", - "import imageio\n", - "import ipywidgets as widgets\n", - "import matplotlib.pyplot as plt\n", - "\n", - "# SunPy library for solar physics data analysis\n", - "import sunpy.map\n", - "\n", - "# Astropy units module for handling physical quantities\n", - "from astropy import units as u\n", - "\n", - "# IPython and ipywidgets for interactive widgets in the notebook\n", - "from IPython.display import (\n", - " Video, # For embedding videos in the notebook\n", - " clear_output,\n", - " display,\n", - ")\n", - "\n", - "# SunPy modules for querying and downloading solar data\n", - "from sunpy.net import Fido\n", - "from sunpy.net import attrs as a\n", - "\n", - "# #******************************************\n", - "# #Command to ensure necessary libraries are installed (uncomment and run if needed)\n", - "# !pip install sunpy matplotlib imageio ipywidgets\n", - "# #******************************************" - ] - }, - { - "cell_type": "markdown", - "id": "b5ef5aa9", - "metadata": {}, - "source": [ - "\n", - "## Using Fido to Search and Download XRT Data" - ] - }, - { - "cell_type": "markdown", - "id": "2420734d", - "metadata": {}, - "source": [ - "[SunPy]:https://sunpy.org/\n", - "[Fido]:https://docs.sunpy.org/en/stable/generated/api/sunpy.net.Fido.html#sunpy.net.Fido\n", - "\n", - "### Searching for Hinode XRT Data\n", - "\n", - "[Fido] is a unified interface provided by [SunPy] for querying and downloading data across various solar physics data sources and missions. In this section, we'll focus on using Fido to find and retrieve data from the Hinode X-Ray Telescope (XRT).\n", - "\n", - "We'll walk through the process of defining a search query, which includes specifying a time range and selecting the instrument, to fetch targeted datasets effectively. " - ] - }, - { - "cell_type": "markdown", - "id": "107d208b", - "metadata": {}, - "source": [ - "In this section, we'll focus on the observation of [Active Region (AR) 13234](https://www.solarmonitor.org/region_pop.php?date=20230223&type=hxrt_flter®ion=13234) by Hinode-XRT. Recorded on May 21, 2023, around 18:51 UT, this region, located near the solar limb, showcased active flaring activities, presenting an intriguing case for study.\n", - "\n", - "For those interested in further exploring flare activities observed by the Hinode mission, the [XRT Flare Catalog](https://xrt.cfa.harvard.edu/flare_catalog/) offers a comprehensive database.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e05834db", - "metadata": {}, - "outputs": [], - "source": [ - "# Define the time range of interest for solar observations\n", - "time_range = a.Time(\"2021-05-21 18:51:00\", \"2021-05-22 01:59:54\")\n", - "\n", - "# Specify the instrument as 'xrt' to search for Hinode X-Ray Telescope data\n", - "instrument = a.Instrument(\"xrt\")\n", - "\n", - "\n", - "# This will return a catalog of available XRT data during the specified period\n", - "xrt_downloaded_files = Fido.search(time_range, instrument)\n", - "\n", - "# Display the search results\n", - "print(xrt_downloaded_files)" - ] - }, - { - "cell_type": "markdown", - "id": "af5e9f4d", - "metadata": {}, - "source": [ - "#### Downloading Hinode XRT Data Using `Fido.fetch`\n", - "\n", - "Having identified the desired Hinode XRT data with `Fido.search`, we proceed to download the datasets using the `Fido.fetch` function. This function accepts the search results as its input and facilitates the data download to a designated directory on your local system.\n", - "\n", - "In the next code cell, we illustrate the utilization of `Fido.fetch` to procure our previously identified data. This demonstration includes specifying a target directory for the downloads. Additionally, we'll introduce handling techniques for managing the download outputs.\n", - "\n", - "**Note**: If no directory is specified, `Fido.fetch` defaults to downloading files to a SunPy-managed directory. You can customize the download location by providing a path to the `path` parameter of `Fido.fetch`.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6c241846", - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "# Note: Depending on the amount of data and network speed, this process can take some time.\n", - "# The `progress` parameter in `Fido.fetch` controls the display of the download progress bar.\n", - "# Setting `progress=False` disables the progress bar, which can be useful for cleaner output,\n", - "# especially when running this in a script or automated pipeline. By default, we keep it True\n", - "# for this interactive session to monitor the download progress.\n", - "\n", - "# This will download the files to the default SunPy data directory or a specified path.\n", - "# Replace `xrt_downloaded_files` with your search results variable if different.\n", - "xrt_files_results = Fido.fetch(xrt_downloaded_files, progress=True)\n", - "\n", - "# If you wish to specify a different download directory, you can do so by adding the `path` parameter:\n", - "# xrt_files_results = Fido.fetch(xrt_downloaded_files, path='/desired/download/directory/', progress=True)" - ] - }, - { - "cell_type": "markdown", - "id": "4dc907b5", - "metadata": {}, - "source": [ - "XRT follows standard Flexible Image Transport System ([FITS](https://fits.gsfc.nasa.gov/)) file naming conventions.\n" - ] - }, - { - "cell_type": "markdown", - "id": "22f2b99e", - "metadata": {}, - "source": [ - "\n", - "## Inspecting the Downloaded Data" - ] - }, - { - "cell_type": "markdown", - "id": "33d78610", - "metadata": {}, - "source": [ - "Once the download is complete, it's important to inspect the data to ensure that what we have collected is suitable for our analysis. This step involves checking the basic information about the downloaded files, such as their names, file sizes, and data types. This information can help us verify that the download was successful and that we have the correct data for our project.\n", - "\n", - "We will demonstrate practical methods to retrieve and display these details using Python's standard utilities along with SunPy-specific functions." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "66441923", - "metadata": {}, - "outputs": [], - "source": [ - "# total number of files downloaded using Fido\n", - "num_files = len(xrt_files_results)\n", - "print(f\"Number of files downloaded: {num_files}\")\n", - "\n", - "# few examples of file names to understand the naming convention\n", - "print(\"\\nSample file names:\")\n", - "for file in xrt_files_results[:5]:\n", - " print(file)\n", - "\n", - "# Example of inspecting a single file from the downloaded dataset\n", - "# Here, we choose a file arbitrarily (the 85th file) for inspection\n", - "sample_file_index = 84 # Adjust the index as desired\n", - "sample_data = sunpy.map.Map(xrt_files_results[sample_file_index])\n", - "\n", - "# Print information about the sample file\n", - "# This includes metadata like observation time, instrument, and data dimensions\n", - "print(f\"\\nSample data info for file number {sample_file_index + 1}:\")\n", - "print(sample_data)\n", - "\n", - "# Visualize the data from the sample file\n", - "# This step is crucial for a quick quality check and to familiarize with the data\n", - "plt.figure(figsize=(10, 8))\n", - "sample_data.peek() # 'peek' method generates a quick-look plot of the data\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "bd7f1676", - "metadata": {}, - "source": [ - "Having successfully collected the Hinode-XRT data, we now have several exciting options at our disposal. We can analyze the FITS files to understand the solar phenomena, visualize the observations in image form, or even create a dynamic movie showcasing a solar event. However, we can take further step towards cleaning up some of the data we have downloaded following the *Exploring Functions to Enhance Data Quality* sections below, which is **optional**. " - ] - }, - { - "cell_type": "markdown", - "id": "f926c721", - "metadata": {}, - "source": [ - "\n", - "## Exploring Functions to Enhance Data Quality" - ] - }, - { - "cell_type": "markdown", - "id": "73757bf1", - "metadata": {}, - "source": [ - "In the following sections, I introduce a series of custom functions aimed at filtering and refining the downloaded Hinode-XRT data. These functions are designed to be user-friendly and accessible, serving as a practical toolset for both novice and experienced users. \n", - "\n", - "\n", - "\n", - "### Why Enhance Data Quality?\n", - "\n", - "The Sun, as observed by Hinode-XRT, presents dynamic and complex phenomena. Filtering the data helps isolate specific events or features, ensuring that subsequent analyses or visualizations focus on the most relevant and high-quality data. These enhancements are **optional** but highly recommended to achieve a clearer, more meaningful understanding of the solar data collected.\n" - ] - }, - { - "cell_type": "markdown", - "id": "833a6cc1", - "metadata": {}, - "source": [ - "\n", - "### Filtering FITS Files Through Selected Filter" - ] - }, - { - "cell_type": "markdown", - "id": "62e7c934", - "metadata": {}, - "source": [ - "Identifying the type of data contained within Hinode XRT FITS files can be challenging, as the file titles do not provide sufficient information. To address this, I have developed a function that leverages `sunpy.map` to read the header information of each FITS file. This process allows us to identify and count the unique filters present within the dataset. \n", - "\n", - "To utilize this function, simply run the provided code in the next cell. When prompted, enter your desired filter criteria. This intuitive approach enables you to effectively narrow down your dataset to include only the most relevant observations for your analysis." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "20262c07", - "metadata": {}, - "outputs": [], - "source": [ - "def normalize_string(s):\n", - " \"\"\"\n", - " Normalize a string for comparison by converting to lowercase, replacing hyphens and underscores with spaces, and removing 'open'.\n", - "\n", - " Parameters:\n", - " - s (str): The string to normalize.\n", - "\n", - " Returns:\n", - " - str: The normalized string.\n", - " \"\"\"\n", - " return (\n", - " s.lower()\n", - " .replace(\"open\", \"\")\n", - " .strip(\"- \")\n", - " .replace(\"_\", \" \")\n", - " .replace(\"-\", \" \")\n", - " .strip()\n", - " )\n", - "\n", - "\n", - "## I have plans to update this function at a later time to allow users to collect FITS for more than one filter.\n", - "\n", - "\n", - "def filter_fits_files_by_XRT_filter(fits_files):\n", - " \"\"\"\n", - " Filters FITS files by XRT filter criteria, accommodating flexible user input formats. It enhances readability and ensures valid input by normalizing filter names.\n", - "\n", - " Parameters:\n", - " - fits_files (list): List of FITS file paths.\n", - "\n", - " Returns:\n", - " - filtered_files (list): List of file paths that match the user-selected XRT channel filter.\n", - "\n", - " Raises:\n", - " - ValueError: If the user input does not match any available filter.\n", - " \"\"\"\n", - " measurement_info = {}\n", - "\n", - " for file_path in fits_files:\n", - " from sunpy.map import Map\n", - "\n", - " sunpy_map = Map(file_path)\n", - " measurement = sunpy_map.measurement\n", - " # Normalize measurement for consistent comparison\n", - " normalized_measurement = normalize_string(measurement)\n", - " if normalized_measurement in measurement_info:\n", - " measurement_info[normalized_measurement] += 1\n", - " else:\n", - " measurement_info[normalized_measurement] = 1\n", - "\n", - " # Display available filters and their counts\n", - " filters_output = \"\\n\".join(\n", - " [f\"{key.title()}: {value} files\" for key, value in measurement_info.items()]\n", - " )\n", - " print(f\"The files have the following filters and counts:\\n{filters_output}\")\n", - " filter_choice = input(\"Please select an XRT channel filter of interest: \")\n", - " normalized_filter_choice = normalize_string(filter_choice)\n", - "\n", - " # Validate user input\n", - " if normalized_filter_choice not in measurement_info:\n", - " raise ValueError(\n", - " \"Invalid filter choice. Please enter a valid XRT channel filter from the list provided.\"\n", - " )\n", - "\n", - " filtered_files = []\n", - " for file_path in fits_files:\n", - " sunpy_map = Map(file_path)\n", - " normalized_measurement = normalize_string(sunpy_map.measurement)\n", - " if normalized_filter_choice in normalized_measurement:\n", - " filtered_files.append(file_path)\n", - "\n", - " name_of_filter = filter_choice.title()\n", - " print(f\"\\nFilter choice: {name_of_filter}\")\n", - " print(\n", - " f\"You have {len(filtered_files)} FITS files that match the '{name_of_filter}' filter.\"\n", - " )\n", - " print(\"Be sure to store this data as a new variable.\")\n", - "\n", - " return filtered_files" - ] - }, - { - "cell_type": "markdown", - "id": "1539a632", - "metadata": {}, - "source": [ - "In this example, we'll be investigating the `Al-Poly` filter on the XRT. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "122165bc", - "metadata": {}, - "outputs": [], - "source": [ - "# Assuming xrt_files_results is a list of FITS file paths\n", - "# My new variable name is reflected base on the filter of interest\n", - "xrt_Al_poly_Obs_FITs = filter_fits_files_by_XRT_filter(xrt_files_results)" - ] - }, - { - "cell_type": "markdown", - "id": "942fec9e", - "metadata": {}, - "source": [ - "\n", - "### Filtering FITS Files Through Pixel Size" - ] - }, - { - "cell_type": "markdown", - "id": "f9a8251f", - "metadata": {}, - "source": [ - "Filtering Hinode XRT FITS files by pixel dimensions, measured in units of pixels (`pix`), is a practical approach to ensure data uniformity. We refer to these **dimensions** within the context of `sunpy.map.Map`.\n", - "\n", - "XRT images typically have dimensions of `[384x384, 512x512, or 1024x1024]`, although any specific area of the CCD can be read out. For comprehensive details, please refer to the [SolarSoft XRT Analysis Guide](https://xrt.cfa.harvard.edu/resources/documents/XAG/XAG.pdf).\n" - ] - }, - { - "cell_type": "markdown", - "id": "d233ee89", - "metadata": {}, - "source": [ - "The function `filter_fits_files_by_XRT_dimensions` simplifies the process of selecting FITS files based on pixel dimensions. Upon running this function, you'll encounter a prompt displaying the available dimensions within your dataset. After selecting a preferred option, the function will generate a new list of FITS files filtered according to the specified dimensions. To utilize this functionality, execute the function in the cell below and follow the instructions in the subsequent steps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fca60980", - "metadata": {}, - "outputs": [], - "source": [ - "def filter_fits_files_by_XRT_dimensions(fits_files):\n", - " \"\"\"\n", - " Filters FITS files by their dimensions, allowing for flexible input formatting.\n", - " Provides up to three attempts for input, with error handling for invalid formats.\n", - "\n", - " Parameters:\n", - " - fits_files (list): List of paths to the FITS files.\n", - "\n", - " Returns:\n", - " - A list of file paths that match the user-selected dimensions.\n", - " \"\"\"\n", - " dimension_counts = {}\n", - "\n", - " # Determine the unique dimensions of all FITS files and count them\n", - " for file_path in fits_files:\n", - " xrt_map = sunpy.map.Map(file_path)\n", - " # Construct a tuple for dimensions to facilitate comparison\n", - " dimensions_tuple = (xrt_map.dimensions.x.value, xrt_map.dimensions.y.value)\n", - " dimensions_str = f\"{dimensions_tuple[0]:.0f}, {dimensions_tuple[1]:.0f}\"\n", - " dimension_counts[dimensions_str] = dimension_counts.get(dimensions_str, 0) + 1\n", - "\n", - " print(\n", - " \"Unique dimensions (in pixels) found in the dataset and their counts:\\n x:pix , y:pix\"\n", - " )\n", - " for dimensions, count in sorted(dimension_counts.items()):\n", - " print(f\"{dimensions}: {count} files\")\n", - "\n", - " attempts = 0\n", - " while attempts < 3:\n", - " chosen_dimensions_str = input(\n", - " \"\\nPlease enter the dimensions of interest (e.g., '384, 384'): \"\n", - " )\n", - " try:\n", - " x_dim, y_dim = (\n", - " int(dim.strip()) for dim in chosen_dimensions_str.split(\",\")\n", - " )\n", - " chosen_dimensions_tuple = (x_dim, y_dim)\n", - " chosen_dimensions_str = (\n", - " f\"{x_dim}, {y_dim}\" # Reformatted string for comparison\n", - " )\n", - " except ValueError:\n", - " print(\"Invalid format. Please enter dimensions in the format 'X, Y'.\")\n", - " attempts += 1\n", - " continue\n", - "\n", - " # Check if the processed input matches any known dimensions\n", - " if chosen_dimensions_str in dimension_counts:\n", - " break # Valid dimension found; proceed with filtering\n", - "\n", - " print(f\"Error: '{chosen_dimensions_str}' is not a recognized dimension.\")\n", - " attempts += 1\n", - "\n", - " if attempts == 3:\n", - " print(\"\\nMaximum attempts reached. Please rerun and try again.\\n\")\n", - " return []\n", - "\n", - " filtered_files = []\n", - " for file_path in fits_files:\n", - " xrt_map = sunpy.map.Map(file_path)\n", - " if (\n", - " xrt_map.dimensions.x.value,\n", - " xrt_map.dimensions.y.value,\n", - " ) == chosen_dimensions_tuple:\n", - " filtered_files.append(file_path)\n", - "\n", - " print(\n", - " f\"\\nFound {len(filtered_files)} files matching the dimensions {chosen_dimensions_str}.\"\n", - " )\n", - " return filtered_files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d97daba4", - "metadata": {}, - "outputs": [], - "source": [ - "# For this example, I will continue to use xrt_Al_poly_Obs_FITs. The function will prompt you to select from\n", - "# available dimensions and return a new list containing only the files that match the selected dimensions.\n", - "\n", - "\n", - "# Now, call the function with your list of FITS file paths:\n", - "xrt_Al_poly_384_Obs_FITs = filter_fits_files_by_XRT_dimensions(xrt_Al_poly_Obs_FITs)" - ] - }, - { - "cell_type": "markdown", - "id": "3d418012", - "metadata": {}, - "source": [ - "### Filtering FITS Files by Exposure Time\n", - "\n", - "Different exposure times can significantly affect the quality and the type of data captured in each image. This section introduces a method to filter your dataset based on specific exposure time criteria, allowing for a more refined and targeted analysis.\n", - "\n", - "#### Why Filter by Exposure Time?\n", - "\n", - "Filtering by exposure time can help isolate images that are best suited for your research goals. For instance, shorter exposure times might be preferred for studying rapid solar events, while longer exposures could provide deeper insights into fainter solar features. This flexibility ensures that you can tailor your dataset to include only the most relevant images.\n", - "\n", - "#### How It Works\n", - "\n", - "The `filter_fits_by_exposure_time` function enables you to specify criteria for selecting images based on their exposure times. You can choose to include images with an exact exposure time, those with exposure times within a specified range, or images with exposure times above or below a certain threshold. This functionality is designed to give you maximum control over the composition of your dataset.\n", - "\n", - "#### Key Features:\n", - "- **Exact Match**: Retrieve images with a specific exposure time by entering the exact value in seconds.\n", - "- **Range Selection**: Specify a range of exposure times to include images that fall within this interval.\n", - "- **Above or Below a Threshold**: Filter images based on whether their exposure times are above or below a specified value.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b2136b56", - "metadata": {}, - "outputs": [], - "source": [ - "def get_exposure_time_counts(fits_files):\n", - " \"\"\"\n", - " Generates a dictionary of exposure times and their counts from FITS files.\n", - "\n", - " Parameters:\n", - " - fits_files (list): List of FITS file paths.\n", - "\n", - " Returns:\n", - " - Dictionary with exposure times as keys and counts and file paths as values.\n", - " \"\"\"\n", - " exposure_time_counts = {}\n", - " for file_path in fits_files:\n", - " map_ = sunpy.map.Map(file_path)\n", - " exposure_time = round(map_.exposure_time.to(u.s).value, 2)\n", - " if exposure_time not in exposure_time_counts:\n", - " exposure_time_counts[exposure_time] = {\"count\": 1, \"files\": [file_path]}\n", - " else:\n", - " exposure_time_counts[exposure_time][\"count\"] += 1\n", - " exposure_time_counts[exposure_time][\"files\"].append(file_path)\n", - " return exposure_time_counts\n", - "\n", - "\n", - "def display_exposure_time_counts(exposure_time_counts):\n", - " \"\"\"\n", - " Displays the exposure times and their counts.\n", - "\n", - " Parameters:\n", - " - exposure_time_counts (dict): Dictionary of exposure times and their counts.\n", - " \"\"\"\n", - " print(\"Exposure times in the dataset (in seconds) and their counts:\")\n", - " for time, info in exposure_time_counts.items():\n", - " print(f\"{time}s: {info['count']} file(s)\")\n", - "\n", - "\n", - "def filter_files_by_criteria(exposure_time_counts, criteria):\n", - " \"\"\"\n", - " Filters FITS files based on user-specified exposure time criteria.\n", - "\n", - " Parameters:\n", - " - exposure_time_counts (dict): Dictionary of exposure times and their counts.\n", - " - criteria (str): User-specified exposure time criteria.\n", - "\n", - " Returns:\n", - " - List of FITS file paths that match the exposure time criteria.\n", - " \"\"\"\n", - " filtered_files = []\n", - " if \"-\" in criteria:\n", - " lower, upper = map(float, criteria.split(\"-\"))\n", - " for time, info in exposure_time_counts.items():\n", - " if lower <= time <= upper:\n", - " filtered_files.extend(info[\"files\"])\n", - " elif criteria.startswith(\"<\"):\n", - " max_time = float(criteria[1:])\n", - " for time, info in exposure_time_counts.items():\n", - " if time < max_time:\n", - " filtered_files.extend(info[\"files\"])\n", - " elif criteria.startswith(\">\"):\n", - " min_time = float(criteria[1:])\n", - " for time, info in exposure_time_counts.items():\n", - " if time > min_time:\n", - " filtered_files.extend(info[\"files\"])\n", - " else:\n", - " exact_time = float(criteria)\n", - " for time, info in exposure_time_counts.items():\n", - " if time == exact_time:\n", - " filtered_files.extend(info[\"files\"])\n", - " return filtered_files\n", - "\n", - "\n", - "def filter_fits_by_exposure_time(fits_files):\n", - " \"\"\"\n", - " Filters FITS files based on exposure time criteria specified by the user.\n", - "\n", - " Parameters:\n", - " - fits_files (list): List of FITS file paths.\n", - "\n", - " Returns:\n", - " - List of FITS file paths that match the exposure time criteria.\n", - " \"\"\"\n", - " exposure_time_counts = get_exposure_time_counts(fits_files)\n", - " display_exposure_time_counts(exposure_time_counts)\n", - " criteria = input(\n", - " \"\\nEnter the exposure time criteria (e.g., '0.36' for exactly 0.36s, '<1.5' for less than 1.5s, '>1.5' for more than 1.5s, '2-120' for between 2s and 120s): \"\n", - " )\n", - " print(\"\\nSelected exposure time(s):\", criteria)\n", - " filtered_files = filter_files_by_criteria(exposure_time_counts, criteria)\n", - " print(f\"\\nFound {len(filtered_files)} files matching the criteria.\")\n", - " return filtered_files" - ] - }, - { - "cell_type": "markdown", - "id": "e6364f7e", - "metadata": {}, - "source": [ - "To use the `filter_fits_by_exposure_time` function, simply run the provided code with your list of FITS files. You will then be prompted to enter your exposure time criteria. The function will process your request and return a filtered list of FITS files that match your specified criteria, making it easier to proceed with a more focused analysis." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bee020c3", - "metadata": {}, - "outputs": [], - "source": [ - "# In this example we're using the filtered Al-Poly Filter & 384 by 384 pixels FITS\n", - "xrt_Al_poly_384_Obs_FITs_fixed_exposure_time = filter_fits_by_exposure_time(\n", - " xrt_Al_poly_384_Obs_FITs\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "45351527", - "metadata": {}, - "source": [ - "## Navigating FITS Images " - ] - }, - { - "cell_type": "markdown", - "id": "486afe2b", - "metadata": {}, - "source": [ - "Now, we have the capability to review images within our curated list of filtered FITS files. This enhanced navigation functionality not only facilitates sequential browsing but also introduces the ability to directly access a specific image within the dataset. Such a feature is invaluable for evaluating your dataset in detail, allowing you to identify and exclude FITS files that may not be relevant to your analysis or contain poor-quality images captured by the XRT." - ] - }, - { - "cell_type": "markdown", - "id": "cfde7c27", - "metadata": {}, - "source": [ - "Using the `view_fits_images` function, you can move forward or backward through the image dataset or jump to an image directly navigate to a specific image by entering its number in the dataset. This feature is particularly useful when dealing with large datasets, as it enables quick access to images of interest without the need to sequentially skim through potentially hundreds of files. Whether you're looking for a particular phase of a solar event or need to examine the quality of specific images, this tool enhances your workflow by making data access more efficient and user-friendly." - ] - }, - { - "cell_type": "markdown", - "id": "a8e58fd2", - "metadata": {}, - "source": [ - "You may find the need to remove certain images or FITS data that are not relevant or of poor quality for your analysis. To facilitate this, maintain a list with either the index numbers or the titles of the FITS files. This metadata is readily available each time you view an image in the dataset. In a later section titled **Removing-unwanted-FITS-Files**, we will introduce functions designed specifically for cleaning your dataset, leveraging the list you've compiled during the review process." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5304a6e7", - "metadata": {}, - "outputs": [], - "source": [ - "def view_fits_images(fits_files):\n", - " \"\"\"\n", - " Displays FITS images one at a time with navigation buttons and an option to jump to a specific image.\n", - "\n", - " Parameters:\n", - " - fits_files (list): List of paths to the FITS files.\n", - " \"\"\"\n", - "\n", - " current_index = [0] # Use a list to allow modifications from inner functions\n", - "\n", - " def show_image(index=None):\n", - " \"\"\"Displays the image at the current index and clears the previous output.\"\"\"\n", - " if index is not None:\n", - " # Safely update the current index based on user input\n", - " current_index[0] = max(0, min(index, len(fits_files) - 1))\n", - "\n", - " clear_output(wait=True) # Clear the previous image and controls\n", - " display(\n", - " widgets.HBox([prev_button, next_button, jump_input, jump_button])\n", - " ) # Redisplay the controls\n", - "\n", - " fits_path = fits_files[current_index[0]]\n", - " sunpy_map = sunpy.map.Map(fits_path)\n", - "\n", - " # Display FITS file name and image counter\n", - " print(\n", - " f\"File: {fits_path.split('/')[-1]} (Image {current_index[0] + 1} of {len(fits_files)})\"\n", - " )\n", - "\n", - " plt.figure(figsize=(6, 6))\n", - " sunpy_map.plot()\n", - " plt.show()\n", - "\n", - " update_buttons_status()\n", - "\n", - " def go_next():\n", - " \"\"\"Go to the next image.\"\"\"\n", - " if current_index[0] < len(fits_files) - 1:\n", - " current_index[0] += 1\n", - " show_image()\n", - "\n", - " def go_prev():\n", - " \"\"\"Go to the previous image.\"\"\"\n", - " if current_index[0] > 0:\n", - " current_index[0] -= 1\n", - " show_image()\n", - "\n", - " def jump_to_image():\n", - " \"\"\"Jump to the image number entered by the user.\"\"\"\n", - " try:\n", - " index = int(jump_input.value) - 1 # Convert to 0-based index\n", - " show_image(index)\n", - " except ValueError:\n", - " print(\"Please enter a valid image number.\")\n", - "\n", - " def update_buttons_status():\n", - " \"\"\"Updates the status of next/prev buttons based on the current index.\"\"\"\n", - " next_button.disabled = current_index[0] >= len(fits_files) - 1\n", - " prev_button.disabled = current_index[0] <= 0\n", - "\n", - " # Create navigation buttons\n", - " next_button = widgets.Button(description=\"Next\")\n", - " prev_button = widgets.Button(description=\"Previous\")\n", - " next_button.on_click(go_next)\n", - " prev_button.on_click(go_prev)\n", - "\n", - " # Create jump to image widgets\n", - " jump_input = widgets.Text(\n", - " description=\"Jump to Image:\", placeholder=\"Enter image number\"\n", - " )\n", - " jump_button = widgets.Button(description=\"Go\")\n", - " jump_button.on_click(jump_to_image)\n", - "\n", - " # Initially display buttons and the first image\n", - " display(widgets.HBox([prev_button, next_button, jump_input, jump_button]))\n", - " show_image()" - ] - }, - { - "cell_type": "markdown", - "id": "92a92fbc", - "metadata": {}, - "source": [ - "### Simple and Intuitive Use\n", - "\n", - "To navigate through your FITS images dataset:\n", - "\n", - "1. **Navigation**: Use the \"Next\" or \"Previous\" buttons to move sequentially through your dataset, one image at a time.\n", - "2. **Direct Jump**: If you want to view a specific image, enter its number in the \"Jump to Image\" field and click \"Go\". The image number should correspond to its sequential position in your list of FITS files, allowing direct and straightforward access to any image in your dataset.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9a83991e", - "metadata": {}, - "outputs": [], - "source": [ - "# We're going to use our filtered FITS data set: xrt_Al_poly_384_Obs_FITs\n", - "view_fits_images(xrt_Al_poly_384_Obs_FITs_fixed_exposure_time)" - ] - }, - { - "cell_type": "markdown", - "id": "93a04e6b", - "metadata": {}, - "source": [ - "### Removing Unwanted FITS Files \n", - "\n", - "#### Strategy for Removal: \n", - "The removal process involves three main steps:\n", - "\n", - "#### Identification: \n", - "While reviewing images, note the index numbers or title filename of those you wish to exclude. Keeping track of these details as you go can streamline the removal process.\n", - "\n", - "#### Compilation: \n", - "Organize the identified indices or filenames into a Python list. This step formalizes your removal list, making the next step straightforward.\n", - "\n", - "#### Execution: \n", - "With the list prepared, you'll use a specific function to remove the unwanted files from your dataset. This function will be based on whether you're working with indices or filenames.\n", - "\n", - "#### Implementation Details\n", - "This section will introduce two functions tailored to your method of identification — one for index numbers and another for filenames. You can choose the one that best fits your workflow.\n" - ] - }, - { - "cell_type": "markdown", - "id": "74951466", - "metadata": {}, - "source": [ - "After reviewing the FITS images using the `view_fits_images` function, you may identify some images that you wish to remove from your dataset. This could be due to poor quality, irrelevance to your study, or any other reason. Below we provide a straightforward method to facilitate this, allowing you to easily remove these unwanted files from your dataset.\n", - "\n", - "##### Strategy for Removal\n", - "\n", - "1. **Identification**: While reviewing images, note the index number(s) or FITS filename(s) of those you wish to exclude. \n", - "\n", - "\n", - "2. **Compilation**: Create a Python [list](https://docs.python.org/3/tutorial/datastructures.html) with these indices as integers or FITS filename as a string.\n", - "\n", - "3. **Execution**: With the list prepared, you'll use a specific function to remove the unwanted files from your dataset. This function will be based on whether you're working with indices or filenames.\n", - "\n", - "##### Implementation\n", - "\n", - "Depending on your preference for using image numbers or filenames for identification, you can use one of the two provided functions.\n", - "\n", - "##### Using Index Numbers to Remove Files\n", - "\n", - "For cases where you've identified unwanted images by their index position number in the dataset, the `remove_fits_by_index` function will do the removal." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "685e2307", - "metadata": {}, - "outputs": [], - "source": [ - "def remove_fits_by_index(original_list, indices_to_remove):\n", - " \"\"\"\n", - " Removes FITS files from the dataset based on their index numbers.\n", - "\n", - " Parameters:\n", - " - original_list (list): The original list of FITS file paths.\n", - " - indices_to_remove (list): A list of index numbers representing the FITS files to remove.\n", - "\n", - " Returns:\n", - " - A new list with the specified FITS files removed.\n", - " \"\"\"\n", - " return [\n", - " item for idx, item in enumerate(original_list) if idx not in indices_to_remove\n", - " ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c2f2ab42", - "metadata": {}, - "outputs": [], - "source": [ - "# Example usage of the remove_fits_by_index function\n", - "indices_to_remove = [\n", - " 2,\n", - " 5,\n", - " 7,\n", - "] # Assuming these are the indices of images to remove, based on their order in the dataset\n", - "\n", - "# Generate the updated list excluding specified FITS files\n", - "updated_index_xrt_Al_poly_384_Obs = remove_fits_by_index(\n", - " xrt_Al_poly_384_Obs_FITs_fixed_exposure_time, indices_to_remove\n", - ")\n", - "\n", - "# Print the new length of the file list\n", - "print(\"New length of file list:\", len(updated_index_xrt_Al_poly_384_Obs))\n", - "\n", - "# Optionally, print the first and last filenames in the updated list to show the range of the dataset\n", - "if updated_index_xrt_Al_poly_384_Obs:\n", - " print(\n", - " \"First file in the list:\", updated_index_xrt_Al_poly_384_Obs[0].split(\"/\")[-1]\n", - " )\n", - " print(\n", - " \"Last file in the list:\", updated_index_xrt_Al_poly_384_Obs[-1].split(\"/\")[-1]\n", - " )\n", - "else:\n", - " print(\"The list is now empty.\")" - ] - }, - { - "cell_type": "markdown", - "id": "11561344", - "metadata": {}, - "source": [ - "##### Using FITS filename to remove file\n", - "If you prefer noting down filenames:\n", - "\n", - "##### Using FITS Filenames to Remove Files\n", - "\n", - "If you find it more intuitive to work with filenames rather than index numbers, the following method allows you to remove unwanted images by their filenames. This can be particularly useful when the filenames contain descriptive information about the data, making them easier to identify without viewing each image sequentially.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2480daea", - "metadata": {}, - "outputs": [], - "source": [ - "def remove_fits_by_filename(original_list, filenames_to_remove):\n", - " \"\"\"\n", - " Removes FITS files from the dataset based on their filenames.\n", - "\n", - " Parameters:\n", - " - original_list (list): The original list of FITS file paths.\n", - " - filenames_to_remove (list): A list of filenames representing the FITS files to remove.\n", - "\n", - " Returns:\n", - " - A new list with the specified FITS files removed.\n", - " \"\"\"\n", - " return [\n", - " item for item in original_list if item.split(\"/\")[-1] not in filenames_to_remove\n", - " ]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9385f185", - "metadata": {}, - "outputs": [], - "source": [ - "# Example usage of the remove_fits_by_filename function\n", - "filenames_to_remove = [\n", - " \"l1_xrt20210521_185300_6.fits\",\n", - " \"l1_xrt20210521_185720_2.fits\",\n", - " \"l1_xrt20210521_190120_3.fits\",\n", - "] # Example filenames of images to remove\n", - "\n", - "# Generate the updated list excluding the specified FITS files\n", - "updated_FITS_xrt_Al_poly_384_Obs = remove_fits_by_filename(\n", - " xrt_Al_poly_384_Obs_FITs_fixed_exposure_time, filenames_to_remove\n", - ")\n", - "\n", - "# Print the new length of the file list\n", - "print(\"New length of file list:\", len(updated_FITS_xrt_Al_poly_384_Obs))\n", - "\n", - "# Optionally, print the first and last filenames in the updated list to show the range of the dataset\n", - "if updated_FITS_xrt_Al_poly_384_Obs:\n", - " print(\"First file in the list:\", updated_FITS_xrt_Al_poly_384_Obs[0].split(\"/\")[-1])\n", - " print(\"Last file in the list:\", updated_FITS_xrt_Al_poly_384_Obs[-1].split(\"/\")[-1])\n", - "else:\n", - " print(\"The list is now empty.\")" - ] - }, - { - "cell_type": "markdown", - "id": "fdf3db70", - "metadata": {}, - "source": [ - "\n", - "## Visualizing Solar Dynamics by Creating a Movie from XRT FITS Data" - ] - }, - { - "cell_type": "markdown", - "id": "bc025ab8", - "metadata": {}, - "source": [ - "Creating a movie from FITS files is an excellent way to visualize data, particularly for dynamic solar phenomena observed by the Hinode XRT. We can accomplish this using SunPy to handle FITS files and matplotlib, along with imageio, to create the animation." - ] - }, - { - "cell_type": "markdown", - "id": "87c9e991", - "metadata": {}, - "source": [ - "The `create_solar_movie_from_FITS` function generates a movie (MP4 format) from the FITS files you provide. If you're interested in customizing this process, you can review and modify the function as needed. To proceed with creating a movie using the default settings, run the cell containing the function below. Then, move to the following cell for instructions on how to use this function in your workflow." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4ee1372d", - "metadata": {}, - "outputs": [], - "source": [ - "def create_solar_movie_from_FITS(\n", - " fits_files, output_file=\"solar_movie.mp4\", fps=5, processing=True\n", - "):\n", - " \"\"\"\n", - " Creates a movie from a sequence of FITS files.\n", - "\n", - " Parameters:\n", - " - fits_files (list): List of paths to the FITS files.\n", - " - output_file (str): Path where the output movie will be saved.\n", - " - fps (int): Frames per second for the output movie.\n", - " - processing (bool): If True, prints processing messages. Default is True.\n", - " \"\"\"\n", - " # Create a temporary directory to store the frames\n", - " frames_dir = tempfile.mkdtemp()\n", - " frames = []\n", - "\n", - " if processing:\n", - " print(f\"Starting to process {len(fits_files)} FITS files.\\n\")\n", - "\n", - " for i, file_path in enumerate(fits_files):\n", - " if processing:\n", - " print(f\"Processing file {i+1}/{len(fits_files)}: {file_path}\")\n", - " # Load the FITS file as a SunPy Map\n", - " xrt_map = sunpy.map.Map(file_path)\n", - "\n", - " # Plotting the SunPy Map\n", - " fig = plt.figure(figsize=(8, 8))\n", - " ax = plt.subplot(projection=xrt_map)\n", - " xrt_map.plot(axes=ax)\n", - "\n", - " # Adding title and labels\n", - " plt.title(\n", - " f'XRT {xrt_map.measurement} {xrt_map.date.strftime(\"%Y-%m-%d %H:%M:%S\")}'\n", - " )\n", - " ax.set_xlabel(\"Helioprojective Longitude (Solar-X)\")\n", - " ax.set_ylabel(\"Helioprojective Latitude (Solar-Y)\")\n", - " plt.tight_layout()\n", - "\n", - " # Saving the frame\n", - " frame_path = os.path.join(frames_dir, f\"frame_{i:04d}.png\")\n", - " plt.savefig(frame_path)\n", - " plt.close(fig)\n", - " frames.append(frame_path)\n", - " if processing:\n", - " print(f\"Saved frame {i+1}/{len(fits_files)}\")\n", - "\n", - " if processing:\n", - " print(\"\\nStarting to compile the movie.\\n\")\n", - "\n", - " # Compile the movie from saved frames\n", - " with imageio.get_writer(output_file, fps=fps) as writer:\n", - " for frame_path in frames:\n", - " image = imageio.imread(frame_path)\n", - " writer.append_data(image)\n", - "\n", - " # Cleanup: Remove temporary frames and directory\n", - " for frame_path in frames:\n", - " os.remove(frame_path)\n", - " os.rmdir(frames_dir)\n", - "\n", - " if processing:\n", - " print(\n", - " f\"\\nMovie created: {output_file}\\nAll done!\\nMake sure to download the movie to your local machine to see it.\"\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0dbd03c2", - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "# Specify the output file name for the movie\n", - "solar_movie_example = \"solar_movie_example.mp4\"\n", - "\n", - "# Create the movie from the list of FITS files\n", - "# Using our Al-Poly by 384X384 filtered FITs files\n", - "create_solar_movie_from_FITS(\n", - " xrt_Al_poly_384_Obs_FITs_fixed_exposure_time,\n", - " output_file=solar_movie_example,\n", - " fps=15,\n", - " processing=True,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1444b45f", - "metadata": {}, - "outputs": [], - "source": [ - "# from IPython.display import Video\n", - "\n", - "# Display the created movie within the notebook. Might to add \"embed=True\" to enable videos directly into a Jupyter Notebook\n", - "Video(solar_movie_example)" - ] - }, - { - "cell_type": "markdown", - "id": "272a9ca0", - "metadata": {}, - "source": [ - "### **A Note from Joy, an xrtpy dev**\n", - "\n", - "As an enthusiast of the Hinode X-Ray Telescope (XRT) and a developer for XRTpy, I created this guide to simplify the process of accessing and analyzing Hinode-XRT data using Python. The functions and methods presented in this guide are designed to serve as a starting point, and they are not currently part of the official `xrtpy` library. I encourage you to adapt and modify these functions to fit your specific research needs and preferences.\n", - "\n", - "#### Contributing to XRTpy\n", - "\n", - "If you're interested in contributing to the guide or the XRTpy project itself, we warmly welcome your input and collaboration. You can engage with us through [XRTpy's GitHub repository](https://github.com/HinodeXRT/xrtpy/pulls). Whether it's by suggesting features, improving documentation, or adding new functionalities, your contributions can significantly impact the scientific community's ability to study the Sun.\n", - "\n", - "#### Contact and Sharing\n", - "\n", - "Should you have any questions, or if you wish to share how you've utilized this guide in your work, please don't hesitate to reach out via email at [xrtpy@cfa.harvard.edu](mailto:xrtpy@cfa.harvard.edu). If you share or present your work based on this guide, please ensure to reference it appropriately.\n", - "\n", - "Thank you for exploring the Hinode-XRT data through this guide and XRTpy. Your feedback and contributions are what make our community thrive.\n" - ] - } - ], - "metadata": { - "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.8.5" - }, - "nbsphinx": { - "execute": "never" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/notebooks/getting_started/channel.ipynb b/docs/notebooks/getting_started/channel.ipynb deleted file mode 100644 index 7ba03ffa..00000000 --- a/docs/notebooks/getting_started/channel.ipynb +++ /dev/null @@ -1,361 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Channel Properties - Exploring XRT Instrument Configuration" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will explore the X-Ray Telescope (XRT) instrument properties using XRTpy's `Channel` object. The Channel object provides convenient methods and attributes to access and analyze various aspects of the XRT instrument configuration.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Import the xrtpy package\n", - "import xrtpy" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[xrtpy- X-Ray Filter Channel]: https://xrtpy.readthedocs.io/en/latest/getting_started.html\n", - "\n", - "Begin by defining a filter channel by its common abbreviation. In this example we will be exploring the titanium-on-polyimide filter. For detailed information about various filter channels and their characteristics, you can refer to the [xrtpy- X-Ray Filter Channel] section." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Define the filter channel abbreviation\n", - "Filter = \"Ti-poly\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To further explore the properties and characteristics of the defined filter channel, we will create a Channel object using `xrtpy.response.Channel`. By inserting the `Filter` variable as an input to the `xrtpy.response.Channel` object, we can conveniently work with the properties associated with the titanium-on-polyimide filter." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "channel = xrtpy.response.Channel(Filter)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now that we have created our `channel` object, we can delve into the X-Ray Telescope (XRT) instrument and its properties. We will start by examining basic information about the XRT instrument." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Display relevant information about the selected filter, observatory, and instrument\n", - "print(\"Selected filter:\", channel.name)\n", - "print(\"\\nObservatory:\", channel.observatory)\n", - "print(\"Instrument:\", channel.instrument)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### **Note: Instrument Properties**\n", - "###### It is important to note that most instrument properties of the X-Ray Telescope (XRT) remain the same regardless of the specific filter being used. This means that many characteristics and specifications of the XRT instrument, such as its dimensions, field of view, and detector properties, are independent of the selected filter." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Contents\n", - "\n", - "1. [Charge-Coupled Device](#Charge-Coupled-Device-(CCD))\n", - "2. [Entrance Filter](#Entrance-Filter) \n", - "3. [Focus-Filter](#Focus-Filter)\n", - "4. [Geometry](#Geometry)\n", - "5. [Mirror 1 and 2](#Mirror)\n", - "6. [Instrument Plotting](#Instrument-Plotting)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Charge-Coupled-Device (CCD)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `channel.ccd` object reviews properties associated with the Charge-Coupled-Device (CCD) camera of the X-Ray Telescope (XRT) instrument.\n", - "\n", - "We can explore various characteristics of the CCD camera, such as its quantum_efficiency and pixel size to list a few." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(channel.ccd.ccd_name)\n", - "\n", - "print(\"\\nPixel size: \", channel.ccd.ccd_pixel_size)\n", - "\n", - "print(\"Full well: \", channel.ccd.ccd_full_well)\n", - "print(\"Gain left: \", channel.ccd.ccd_gain_left)\n", - "print(\"Gain right: \", channel.ccd.ccd_gain_right)\n", - "print(\"eV pre electron: \", channel.ccd.ccd_energy_per_electron)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Entrance Filter" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can explore the XRT entrance filter properties utilizing `channel.entrancefilter` object. \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(channel.entrancefilter.entrancefilter_name)\n", - "print(\"Material: \", channel.entrancefilter.entrancefilter_material)\n", - "print(\"Thickness: \", channel.entrancefilter.entrancefilter_thickness)\n", - "print(\"Density: \", channel.entrancefilter.entrancefilter_density)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Focus-Filter" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "[X-Ray Filter Channel]: https://xrtpy.readthedocs.io/en/latest\n", - "\n", - "The XRT data is recorded through nine X-ray filters, which are implemented using two filter wheels. By utilizing the `channel.filter_#` notation, where `#` represents filter wheel 1 or 2, we can explore detailed information about the selected XRT channel filter.\n", - "\n", - "We are exploring the titanium-on-polyimide filter located in filter wheel 2, we will be utilizing the `channel.filter_2` object. This enables us to gather specific information about the properties and characteristics of this particular filter.\n", - "\n", - "It's worth noting that exploring the other filter will yield the result \"Open,\" as it's not use. For more comprehensive information about the XRT filters, you can refer to the [X-Ray Filter Channel] documentation." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(\"Filter Wheel:\", channel.filter_2.filter_name)\n", - "print(\"\\nFilter material:\", channel.filter_2.filter_material)\n", - "print(\"Thickness: \", channel.filter_2.filter_thickness)\n", - "print(\"Density: \", channel.filter_2.filter_density)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Geometry" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can explore geometry factors in the XRT using `channel.geometry`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(channel.geometry.geometry_name)\n", - "print(\"\\nFocal length:\", channel.geometry.geometry_focal_len)\n", - "print(\"Aperture Area:\", channel.geometry.geometry_aperture_area)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Mirror" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The XRT is equipped with two mirrors, each having a unique configuration. We can access the properties of these mirrors using the `channel_mirror_#` notation, where `#` represents the first or second mirror surface. In this example, we will explore several XRT properties related to mirror 1 using the `channel_mirror_1` object. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(channel.mirror_1.mirror_name)\n", - "print(\"Material: \", channel.mirror_1.mirror_material)\n", - "print(\"Density: \", channel.mirror_1.mirror_density)\n", - "print(\"Graze_angle: \", channel.mirror_1.mirror_graze_angle)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Instrument Plotting" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Plotting XRT properties - Transmittance" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define the XRT transmission in `channel` by referencing transmission." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "transmission = channel.transmission" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define the XRT wavelength in `channel` by referencing wavelength." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "wavelength = channel.wavelength" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create a plotting function that plots the `transmission` versus `wavelength`. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def plot_transmission():\n", - " import matplotlib.pyplot as plt\n", - "\n", - " plt.figure(figsize=(10, 6))\n", - "\n", - " plt.plot(wavelength, transmission, label=f\"{channel.name}\")\n", - "\n", - " plt.title(\"X-Ray Telescope\", fontsize=15)\n", - " plt.xlabel(r\"$\\lambda$ [Å]\", fontsize=15)\n", - " plt.ylabel(r\"Transmittance\", fontsize=15)\n", - " plt.legend(fontsize=20)\n", - " plt.xlim(-5, 80)\n", - " plt.xticks(fontsize=15)\n", - " plt.yticks(fontsize=15)\n", - "\n", - " plt.grid(color=\"lightgrey\")\n", - " plt.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Run `plot_transmission` function to create the plot." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plot_transmission()" - ] - } - ], - "metadata": { - "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.8.5" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/notebooks/getting_started/units.ipynb b/docs/notebooks/getting_started/units.ipynb deleted file mode 100644 index 754c7fa8..00000000 --- a/docs/notebooks/getting_started/units.ipynb +++ /dev/null @@ -1,724 +0,0 @@ -{ - "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, k_B\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/reference/image_correction.rst b/docs/reference/image_correction.rst new file mode 100644 index 00000000..a5add193 --- /dev/null +++ b/docs/reference/image_correction.rst @@ -0,0 +1,5 @@ +************************ +`xrtpy.image_correction` +************************ + +.. automodapi:: xrtpy.image_correction diff --git a/docs/reference/index.rst b/docs/reference/index.rst new file mode 100644 index 00000000..fd6b8fe1 --- /dev/null +++ b/docs/reference/index.rst @@ -0,0 +1,10 @@ +******************* +xrtpy API Reference +******************* + +.. toctree:: + :maxdepth: 1 + :caption: Contents: + :glob: + + * diff --git a/docs/reference/response.rst b/docs/reference/response.rst new file mode 100644 index 00000000..ec4c9282 --- /dev/null +++ b/docs/reference/response.rst @@ -0,0 +1,5 @@ +**************** +`xrtpy.response` +**************** + +.. automodapi:: xrtpy.response diff --git a/docs/reference/util.rst b/docs/reference/util.rst new file mode 100644 index 00000000..266e10c6 --- /dev/null +++ b/docs/reference/util.rst @@ -0,0 +1,5 @@ +************ +`xrtpy.util` +************ + +.. automodapi:: xrtpy.util diff --git a/docs/reference/xrtpy.rst b/docs/reference/xrtpy.rst new file mode 100644 index 00000000..c1bbe85c --- /dev/null +++ b/docs/reference/xrtpy.rst @@ -0,0 +1,5 @@ +******* +`xrtpy` +******* + +.. automodapi:: xrtpy diff --git a/docs/response/index.html b/docs/response/index.html deleted file mode 100644 index 3cbb92aa..00000000 --- a/docs/response/index.html +++ /dev/null @@ -1,30 +0,0 @@ -.. _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/examples/README.txt b/examples/README.txt new file mode 100644 index 00000000..264c1806 --- /dev/null +++ b/examples/README.txt @@ -0,0 +1,5 @@ +*************** +Example Gallery +*************** + +The gallery contains examples of how to use ``xrtpy``. diff --git a/examples/channels.py b/examples/channels.py new file mode 100644 index 00000000..64160508 --- /dev/null +++ b/examples/channels.py @@ -0,0 +1,103 @@ +""" +================================================== +Channel - Exploring XRT's Instrument Configuration +================================================== + +This example explores the X-Ray Telescope (XRT) instrument properties +using XRTpy's `Channel` object. It provides convenient methods and attributes +to access and analyze various aspects of the XRT instrument configuration. +""" + +import matplotlib.pyplot as plt + +import xrtpy + +############################################################################## +# We begin by defining a filter channel by its common abbreviation. +# In this example we will be exploring the titanium-on-polyimide filter. +# For detailed information about various filter channels and their characteristics, you can refer to :ref:`xrtpy-getting-started-filters`. +# +# To explore the properties and characteristics of a defined filter channel, we will create a +# `xrtpy.response.Channel`. By passing in the filter name as an input, we can work +# with the properties associated with the titanium-on-polyimide filter. + +channel = xrtpy.response.Channel("Ti-poly") + +############################################################################## +# Now that we have created our `channel` object, we can delve into the XRT instrument and its properties. +# We will start by examining basic information about the XRT instrument. + +print("Selected filter:", channel.name) +print("\nObservatory:", channel.observatory) +print("Instrument:", channel.instrument) + +############################################################################## +# It is important to note that most instrument properties of XRT remain the same +# regardless of the specific filter being used. This means that many characteristics +# and specifications of the XRT instrument, such as its dimensions, +# field of view, and detector properties, are independent of the selected filter. + +############################################################################## +# We can explore various characteristics of the the Charge-Coupled-Device (CCD) +# camera camera, such as its quantum efficiency and pixel size to list a few. + +print(channel.ccd.ccd_name) +print("\nPixel size: ", channel.ccd.ccd_pixel_size) +print("Full well: ", channel.ccd.ccd_full_well) +print("Gain left: ", channel.ccd.ccd_gain_left) +print("Gain right: ", channel.ccd.ccd_gain_right) +print("eV pre electron: ", channel.ccd.ccd_energy_per_electron) + +############################################################################## +# We can explore the XRT entrance filter properties utilizing `channel.entrancefilter`. + +print(channel.entrancefilter.entrancefilter_name) +print("Material: ", channel.entrancefilter.entrancefilter_material) +print("Thickness: ", channel.entrancefilter.entrancefilter_thickness) +print("Density: ", channel.entrancefilter.entrancefilter_density) + +############################################################################## +# XRT data is recorded through nine X-ray filters, which are implemented using two filter wheels. +# +# By utilizing the ``channel.filter_#`` notation, where ``#`` represents filter wheel 1 or 2, +# we can explore detailed information about the selected XRT channel filter. +# +# It's worth noting that sometimes the other filter will yield the result "Open," as it's not use. +# For more comprehensive information about the XRT filters, you can refer to :ref:`xrtpy-getting-started-filters`. + +print("Filter Wheel:", channel.filter_2.filter_name) +print("\nFilter material:", channel.filter_2.filter_material) +print("Thickness: ", channel.filter_2.filter_thickness) +print("Density: ", channel.filter_2.filter_density) + +############################################################################## +# We can explore geometry factors in the XRT using `channel.geometry`. + +print(channel.geometry.geometry_name) +print("\nFocal length:", channel.geometry.geometry_focal_len) +print("Aperture Area:", channel.geometry.geometry_aperture_area) + +############################################################################## +# The XRT is equipped with two mirrors and We can access the properties of these +# mirrors using the ``channel_mirror_#`` notation, where ``#`` represents the first or second mirror surface. + +print(channel.mirror_1.mirror_name) +print("Material: ", channel.mirror_1.mirror_material) +print("Density: ", channel.mirror_1.mirror_density) +print("Graze_angle: ", channel.mirror_1.mirror_graze_angle) + +############################################################################## +# Finally we can explore the XRT transmission properties + +plt.figure() + +plt.plot(channel.wavelength, channel.transmission, label=f"{channel.name}") +plt.title(f"{channel.name} filter") +plt.xlabel(r"$\lambda$ [Å]") +plt.ylabel(r"Transmittance") +# The full range goes up to 400 Å, but we will limit it to 80 Å for better visualization +plt.xlim(0, 80) +plt.grid(color="lightgrey") +plt.tight_layout() + +plt.show() diff --git a/examples/deconvolving.py b/examples/deconvolving.py new file mode 100644 index 00000000..96953d1e --- /dev/null +++ b/examples/deconvolving.py @@ -0,0 +1,44 @@ +""" +======================= +Deconvolving XRT Images +======================= + +This example demonstrates deconvolvoing X-Ray Telescope (XRT) images using the `~.deconvolve` function in XRTpy. +""" + +import matplotlib.pyplot as plt +import sunpy.map +from sunpy.net import Fido +from sunpy.net import attrs as a + +from xrtpy.image_correction.deconvolve import deconvolve + +############################################################################## +# We will search for XRT data from the Virtual Solar Observatory (VSO) and fetch the first result. + +result = Fido.search( + a.Time("2012-06-05 21:58:39", "2012-06-05 21:59:00"), a.Instrument("xrt") +) +data_file = Fido.fetch(result[0]) + +############################################################################## +# Typically most deconvolve routines use the Richardson-Lucy deconvolution algorithm. + +xrt_map = sunpy.map.Map(data_file) +deconv_map = deconvolve(xrt_map) + +############################################################################## +# To see the effects of the deconvolution we plot both the before and after images. + +fig = plt.figure(figsize=(15, 10)) + +ax = fig.add_subplot(121, projection=xrt_map) +xrt_map.plot(axes=ax, title="Original") +ax1 = fig.add_subplot(122, projection=deconv_map) +deconv_map.plot(axes=ax1, title="Deconvolved") + +ax1.coords[1].set_ticks_visible(False) +ax1.coords[1].set_ticklabel_visible(False) +fig.tight_layout() + +plt.show() diff --git a/examples/effective_area.py b/examples/effective_area.py new file mode 100644 index 00000000..0c51f3fe --- /dev/null +++ b/examples/effective_area.py @@ -0,0 +1,75 @@ +""" +======================= +Effective Area Analysis +======================= + +In this example, we will explore the effective areas for different XRT filter channels. +Understanding the effective areas is important for accurately interpreting and quantifying the data. +""" + +import matplotlib.pyplot as plt + +import xrtpy + +############################################################################## +# Let us begin by defining a filter channel using its abbreviation. +# For example, if we want to explore the effective area for an aluminum-on-polyimide filter +# channel, we need to specify the relevant abbreviation. + +xrt_filter = "Al-poly" + +############################################################################## +# `~.EffectiveAreaFundamental` allows us to accurately determine the effective area +# based on the specified filter channel, date, and time. + +date_time = "2023-09-22T22:59:59" +eaf = xrtpy.response.EffectiveAreaFundamental(xrt_filter, date_time) + +############################################################################## +# To actually calculate the effective area function we can call :meth:`~Effective_Area_Fundamental.effective_area`. + +effective_area = eaf.effective_area() +print("Effective Area:\n", effective_area) + +############################################################################## +# Differences overtime arise from an increase of the contamination layer on the +# CCD which blocks some of the X-rays thus reducing the effective area. +# For detailed information about the calculation of the XRT CCD contaminant layer thickness, +# you can refer to +# `Montana State University `__. +# +# Additional information is provided by +# `Narukage et. al. (2011) `__. + +relative_launch_date_time = "2006-09-22T22:59:59" +eaf_launch = xrtpy.response.EffectiveAreaFundamental( + xrt_filter, relative_launch_date_time +) +launch_effective_area = eaf_launch.effective_area() + +############################################################################## +# Finally, we can plot how the effective area has changed over time. + +plt.figure() + +plt.plot( + eaf.channel_wavelength, + effective_area, + label=f"{date_time}", +) +plt.plot( + eaf.channel_wavelength, + launch_effective_area, + label=f"{relative_launch_date_time}", +) + +plt.title("XRT Effective Area - Al-Poly") +plt.xlabel("Wavelength (Å)") +plt.ylabel("Effective Area ($cm^{2}$)") +plt.legend() +plt.xlim(0, 60) + +plt.grid(color="lightgrey") +plt.tight_layout() + +plt.show() diff --git a/examples/remove_lightleak.py b/examples/remove_lightleak.py new file mode 100644 index 00000000..1c3d6a17 --- /dev/null +++ b/examples/remove_lightleak.py @@ -0,0 +1,48 @@ +""" +=================== +Removing Light Leak +=================== + +In this example, we show how to remove the light leak (visible stray light) +from XRT synoptic composite images. +""" + +from pathlib import Path + +import astropy.units as u +import matplotlib.pyplot as plt +import sunpy.map +from astropy.utils.data import get_pkg_data_path + +from xrtpy.image_correction.remove_lightleak import remove_lightleak + +############################################################################## +# This example will be using XRT synoptic data from the first day of summer of 2015. +# This is stored in the ``example_data`` directory of the `xrtpy` package. + +directory = get_pkg_data_path("data/example_data", package="xrtpy.image_correction") +data_file = Path(directory) / "comp_XRT20150621_055911.7.fits" +xrt_map = sunpy.map.Map(data_file) + +############################################################################## +# Removing the light leak from the composite image is done using the `~.remove_lightleak` function. + +lightleak_map = remove_lightleak(xrt_map) + +############################################################################## +# Finally, we plot the original and light leak subtracted images side by side. + +fig = plt.figure(figsize=(12, 6)) + +ax = fig.add_subplot(121, projection=xrt_map) +xrt_map.plot(axes=ax, title="Original", clip_interval=(1, 99.9) * u.percent) +ax1 = fig.add_subplot(122, projection=lightleak_map) +lightleak_map.plot( + axes=ax1, title="Light Leak Subtracted", clip_interval=(1, 99.9) * u.percent +) + +ax1.coords[1].set_ticks_visible(False) +ax1.coords[1].set_ticklabel_visible(False) +fig.tight_layout() + +plt.show() diff --git a/examples/sorting_data.py b/examples/sorting_data.py new file mode 100644 index 00000000..ff2cb915 --- /dev/null +++ b/examples/sorting_data.py @@ -0,0 +1,79 @@ +""" +========================= +Filtering and Visualizing +========================= + +This example provides a simple overview of filtering and visualizing XRT data. +""" + +import astropy.units as u +import matplotlib.pyplot as plt +import sunpy.map +from sunpy.net import Fido +from sunpy.net import attrs as a + +############################################################################## +# To start we will download a range of XRT data from the Virtual Solar Observatory (VSO). +# The goal is to acquire a large set of files we can sort through and visualize. + +query = Fido.search( + a.Time("2021-05-21 18:51:00", "2021-05-22 00:00:00"), a.Instrument("xrt") +) +print(query) + +############################################################################## +# This query will return a large number of files, this is due to the fact we do not +# specify any additional filters. We can filter the data by specifying additional +# attributes in the query. +# +# For wavelength, we use a range that focuses the data to return only Al-Poly filter images. +# This will cut the results down in half. + +query = Fido.search( + a.Time("2021-05-21 18:51:00", "2021-05-22 00:00:00"), + a.Instrument("xrt"), + a.Wavelength(4 * u.nm, 5 * u.nm), +) +print(query) + +############################################################################## +# Now we will download the data. +# As this is still over 100 files, this process can take some time. + +xrt_files = Fido.fetch(query) + +############################################################################## +# We can now load the data into a `~sunpy.map.MapSequence` and create a animation. + +xrt_seq = sunpy.map.Map(xrt_files, sequence=True) + +xrt_seq.peek() + +############################################################################## +# You might notice that there is a jump in the sequence. +# The size of the data and the pointing changes. +# We can exclude these images by filtering the data further. + +xrt_seq_filtered_shape = sunpy.map.Map( + [m for m in xrt_seq if m.data.shape == (384, 384)], sequence=True +) + +xrt_seq_filtered_shape.peek() + +############################################################################## +# In fact, `sunpy.map.Map` provides many attributes that can be used to filter the data. +# This provides a lot of flexibility in how you can filter the data for your science objective. +# +# For example, we can filter the data by the exposure time or the detector. + +xrt_seq_filtered_exp_time = sunpy.map.Map( + [m for m in xrt_seq_filtered_shape if m.exposure_time < 0.1 * u.s], sequence=True +) + +xrt_seq_filtered_exp_time.peek() + +############################################################################## +# If you want to save this animation to a file, you can use the ``save`` method. +# For more information on how to use this method, `see the matplotlib documentation `__. + +plt.show() diff --git a/examples/temperature_from_filter_ratios.py b/examples/temperature_from_filter_ratios.py new file mode 100644 index 00000000..d67e127f --- /dev/null +++ b/examples/temperature_from_filter_ratios.py @@ -0,0 +1,69 @@ +""" +================================================ +Calculating the temperature and emission measure +================================================ + +In this example, we will showcase how to use the filter method to calculate +the temperature and emission measure of the X-ray Telescope (XRT) on Hinode. +""" + +import matplotlib.pyplot as plt +import sunpy.map +from astropy.visualization import ImageNormalize, LogStretch +from sunpy.net import Fido +from sunpy.net import attrs as a + +from xrtpy.response.temperature_from_filter_ratio import temperature_from_filter_ratio + +############################################################################## +# To start, we will get XRT data via ``sunpy``. +# +# It is important to use images that same size and with the smallest time separation. +# Note that not all filter ratios produce good results. + +query = Fido.search( + a.Time("2011-01-28 01:31:55", "2011-01-28 01:32:05"), a.Instrument("xrt") +) +data_files = Fido.fetch(query) +xrt_map_1 = sunpy.map.Map(data_files[0]) +xrt_map_2 = sunpy.map.Map(data_files[1]) + +############################################################################## +# The `~.temperature_from_filter_ratio` function has several options, mirroring +# the IDL routine xrt_teem.pro in SolarSoft in most respects.A simple call with +# no extra parameters calculates the temperature and (volume) emission measure +# for the two images without any binning or masking of the data. + +T_EM = temperature_from_filter_ratio(xrt_map_1, xrt_map_2) + +############################################################################## +# The output is a namedtuple with attributes ``Tmap``, ``EMmap``, ``Terrmap``, and ``EMerrmap``. +# As with the SolarSoft IDL routine xrt_teem.pro, the output images are logs of the quantities. +# +# `Tmap` is the electron temperature, ``EMmap`` is the volume emission measure, ``Terrmap`` +# is a measure of the uncertainties in the temperature determined for each pixel and ``EMerrmap`` +# is the same for the emission measure. + +T_e = T_EM.Tmap + +fig = plt.figure() + +ax = plt.subplot(projection=T_e) +T_e.plot( + title="Derived Temperature", + cmap="inferno", + norm=ImageNormalize(vmin=6, vmax=7, stretch=LogStretch(10)), +) +T_e.draw_limb() +T_e.draw_grid() +plt.colorbar(label="T (K)") +plt.tight_layout() + +plt.show() + +############################################################################## +# If you want to do the same for Level 2 synoptic composite images, you have to use +# `~.make_exposure_map` to generate the exposure maps for the composite images. +# This is then passed to `~.temperature_from_filter_ratio` as the ``expmap1`` and ``expmap2`` arguments. +# Otherwise without accounting for the different exposure time per pixel, +# the temperature and emission measure will be incorrect. diff --git a/examples/temperature_response.py b/examples/temperature_response.py new file mode 100644 index 00000000..031d5153 --- /dev/null +++ b/examples/temperature_response.py @@ -0,0 +1,88 @@ +""" +==================== +Temperature Response +==================== + +In this example, we will explore the temperature response of the filters on XRT. +The temperature response provides important information on how XRT responds to +the different temperatures of X-ray emissions. +""" + +import matplotlib.pyplot as plt +import numpy as np + +import xrtpy + +############################################################################## +# A filter channel is defined by its common abbreviation, which represents +# a specific type of filter used to modify the X-ray radiation observed. +# In this example, we will explore the carbon-on-polyimide filter (abbreviated as "C-poly"). + +xrt_filter = "C-poly" + +############################################################################## +# `~.TemperatureResponseFundamental` provides the functions and properties for +# calculating the temperature response. + +date_time = "2023-09-22T21:59:59" +tpf = xrtpy.response.TemperatureResponseFundamental( + xrt_filter, date_time, abundance_model="Photospheric" +) + +############################################################################## +# To calculate the temperature response,we can do the following: + +temperature_response = tpf.temperature_response() +print("Temperature Response:\n", temperature_response) + +############################################################################## +# We will now visualize the temperature response function using CHIANTI. +# These temperatures are of the plasma and are independent of the channel filter. +# +# We use the log of the these temperatures, to enhance the visibility of the +# variations at lower temperatures. + +chianti_temperature = np.log10(tpf.CHIANTI_temperature.to_value()) + +############################################################################## +# Differences overtime arise from an increase of the contamination layer on the +# CCD which blocks some of the X-rays thus reducing the effective area. +# For detailed information about the calculation of the XRT CCD contaminant layer thickness, +# you can refer to +# `Montana State University `__. +# +# Additional information is provided by +# `Narukage et. al. (2011) `__. + + +launch_datetime = "2006-09-22T23:59:59" + +launch_temperature_response = xrtpy.response.TemperatureResponseFundamental( + xrt_filter, launch_datetime, abundance_model="Photospheric" +).temperature_response() + +############################################################################## +# Now we can plot the temperature response versus the log of the CHIANTI temperature +# and compare the results for the launch date and the chosen date. + +plt.figure() + +plt.plot( + chianti_temperature, + np.log10(temperature_response.value), + label=f"{date_time}", +) +plt.plot( + chianti_temperature, + np.log10(launch_temperature_response.value), + label=f"{launch_datetime}", + color="red", +) + +plt.title("XRT Temperature Response") +plt.xlabel("Log(T) ($K$)") +plt.ylabel("$DN$ $cm^5$ $ s^-1$ $pix^-1$") +plt.legend() +plt.grid() + +plt.show() diff --git a/pyproject.toml b/pyproject.toml index f2c2631b..b183da91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,17 +71,26 @@ docs = [ "nbsphinx >= 0.9", "numpydoc >= 1.5.0", "pillow >= 9.1.0", + "pydata_sphinx_theme", "pygments >= 2.12.0", "sphinx >= 7.3.0", + "sphinx_automodapi >= 0.17.0", + "sphinx_rtd_theme >= 2.0.0", + "sphinx-automodapi>=0.14.1", "sphinx-changelog >= 1.5.0", + "sphinx-changelog>=1.5.0", "sphinx-codeautolink >= 0.15.2", "sphinx-copybutton >= 0.5.2", + "sphinx-copybutton>=0.5.0", + "sphinx-design>=0.2.0", "sphinx-gallery >= 0.16.0", + "sphinx-gallery>=0.13.0", "sphinx-hoverxref >= 1.4.0", + "sphinx-hoverxref>=1.3.0", "sphinx-issues >= 4.1.0", - "sphinx_automodapi >= 0.17.0", - "sphinx_rtd_theme >= 2.0.0", "sphinxcontrib-bibtex >= 2.6.2", + "sphinxext-opengraph>=0.6.0", + "sunpy-sphinx-theme>=2.0.3", "sunpy[net] >= 4.0.0", "towncrier >= 23.11.0", ] @@ -166,8 +175,7 @@ ignore = [ [tool.ruff.lint.per-file-ignores] "__init__.py" = ["E402", "F401", "F402", "F403"] # ignore import errors -"docs/notebooks/computing_functions/temperature_response.ipynb" = ["A001"] # filter variable shadows Python builtin -"docs/notebooks/getting_started/A_Practical_Guide_to_Data_Extraction_and_Visualization.ipynb" = ["PTH106", "PTH107", "PTH118"] # should switch to using pathlib here later +"examples/*" = ["INP001"] # is part of an implicit namespace package. [tool.ruff.lint.flake8-import-conventions.aliases] "astropy.units" = "u"