diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7042bd1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +.venv +.idea +*.egg-info +*.pyc +temp +dist +build +.pytest_cache +.DS_Store +docs/_build +.ipynb_checkpoints diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..f7841fb --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,26 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + apt_packages: + - libproj-dev + - libgeos-dev + - graphviz + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/conf.py + + +# Optionally declare the Python requirements required to build your docs +python: + install: + - requirements: requirements.txt diff --git a/Manifest.in b/Manifest.in new file mode 100644 index 0000000..e53b9cb --- /dev/null +++ b/Manifest.in @@ -0,0 +1,2 @@ +include PYPI-README.rst +include license.txt \ No newline at end of file diff --git a/PYPI-README.rst b/PYPI-README.rst new file mode 100644 index 0000000..25cac19 --- /dev/null +++ b/PYPI-README.rst @@ -0,0 +1,25 @@ +========= +GDT-HETE2 +========= + +The GDT-HETE2 is an extension to Gamma-ray Data Tools that adds functions specific to the hete2 mission. + +Normal Installation +------------------- + +If you don't plan to contribute code to the project, the recommended install method is installing from PyPI using: + +.. code-block:: sh + + pip install astro-gdt-hete2 + gdt-data init + +The ``gdt-data init`` is required to initialize the library after installation of astro-gdt. You do not need to +perform the initialization again if astro-gdt was already installed and initialized. There is no harm in running +it again "just in case". + +Contributing Code or Documentation +---------------------------------- + +If you plan to help with the development or documentation of astro-gdt-hete2, then please visit our github site at +https://github.com/USRA-STI/gdt-hete2. \ No newline at end of file diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..09c3379 --- /dev/null +++ b/README.rst @@ -0,0 +1,63 @@ +========= +GDT-HETE2 +========= + +The GDT-HETE2 is an extension to Gamma-ray Data Tools that adds functions specific to the hete2 mission. + +Normal Installation +------------------- + +If you don't plan to contribute code to the project, the recommended install method is installing from PyPI using: + +.. code-block:: sh + + pip install astro-gdt-hete2 + gdt-data init + +The ``gdt-data init`` is required to initialize the library after installation of astro-gdt. You do not need to +perform the initialization again if astro-gdt was already installed and initialized. There is no harm in running +it again "just in case". + + +Writing Extensions using Namespace Packaging +-------------------------------------------- +This is an extension to astro-gdt and should should contain a directory 'gdt' with a subdirectory 'missions' which will hold the extension code +in a package directory named after the mission. + +For example, GDT-HETE2 has the following directory layout:: + + . + ├── config + ├── dist + ├── docs + ├── src + │   └── gdt + │      └── missions + │      └── hete2 + │      └── __init__.py + └── tests + └── missions + └── hete2 + + +Since GDT-HETE2 uses namespace packaging, both ``src/gdt`` and ``src/gdt/missions`` do not contain a file named +``__init__.py``. This is because they are Namespace packages. + +Notice that directory ``src/gdt/mission/hete2`` contains an `__init__.py` file +signalling to Python that those directories are regular packages. + +You can learn more about Namespace packages by reading `PEP-420 `_. + +Helping with Documentation +-------------------------- + +You can contribute additions and changes to the documentation. In order to use sphinx to compile the documentation +source files, we recommend that you install the packages contained within ``requirments.txt``. + +To compile the documentation, use the following commands: + +.. code-block:: sh + + cd $PROJ_ROOT/docs + make html + diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_static/bootstrap-astropy.css b/docs/_static/bootstrap-astropy.css new file mode 100644 index 0000000..7565fee --- /dev/null +++ b/docs/_static/bootstrap-astropy.css @@ -0,0 +1,658 @@ +/*! + * Bootstrap v1.4.0 + * + * Copyright 2011 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Heavily modified by Kyle Barbary for the AstroPy Project for use with Sphinx. + */ + +@import url("basic.css"); + +body { + background-color: #ffffff; + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 18px; + color: #404040; +} + +/* Hyperlinks ----------------------------------------------------------------*/ + +a { + color: #0069d6; + text-decoration: none; + line-height: inherit; + font-weight: inherit; +} + +a:hover { + color: #00438a; + text-decoration: underline; +} + +/* Typography ----------------------------------------------------------------*/ + +h1,h2,h3,h4,h5,h6 { + color: #404040; + margin: 0.7em 0 0 0; + line-height: 1.5em; +} +h1 { + font-size: 24px; + margin: 0; +} +h2 { + font-size: 21px; + line-height: 1.2em; + margin: 1em 0 0.5em 0; + border-bottom: 1px solid #404040; +} +h3 { + font-size: 18px; +} +h4 { + font-size: 16px; +} +h5 { + font-size: 14px; +} +h6 { + font-size: 13px; + text-transform: uppercase; +} + +p { + font-size: 13px; + font-weight: normal; + line-height: 18px; + margin-top: 0px; + margin-bottom: 9px; +} + +ul, ol { + margin-left: 0; + padding: 0 0 0 25px; +} +ul ul, ul ol, ol ol, ol ul { + margin-bottom: 0; +} +ul { + list-style: disc; +} +ol { + list-style: decimal; +} +li { + line-height: 18px; + color: #404040; +} +ul.unstyled { + list-style: none; + margin-left: 0; +} +dl { + margin-bottom: 18px; +} +dl dt, dl dd { + line-height: 18px; +} +dl dd { + margin-left: 9px; +} +hr { + margin: 20px 0 19px; + border: 0; + border-bottom: 1px solid #eee; +} +strong { + font-style: inherit; + font-weight: bold; +} +em { + font-style: italic; + font-weight: inherit; + line-height: inherit; +} +.muted { + color: #bfbfbf; +} + +address { + display: block; + line-height: 18px; + margin-bottom: 18px; +} +code, pre { + padding: 0 3px 2px; + font-family: monospace; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +tt { + font-family: monospace; +} +code { + padding: 1px 3px; +} +pre { + display: block; + padding: 8.5px; + margin: 0 0 18px; + line-height: 18px; + border: 1px solid #ddd; + border: 1px solid rgba(0, 0, 0, 0.12); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + white-space: pre; + word-wrap: break-word; +} + +img { + margin: 9px 0; +} + +/* format inline code with a rounded box */ +tt, code { + margin: 0 2px; + padding: 0 5px; + border: 1px solid #ddd; + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 3px; +} + +code.xref, a code { + margin: 0; + padding: 0 1px 0 1px; + background-color: transparent; + border: none; +} + +/* all code has same box background color, even in headers */ +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt, +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code, +pre, code, tt { + background-color: #f8f8f8; +} + +/* override box for links & other sphinx-specifc stuff */ +tt.xref, a tt, tt.descname, tt.descclassname { + padding: 0 1px 0 1px; + border: none; +} + +/* override box for related bar at the top of the page */ +.related tt { + border: none; + padding: 0 1px 0 1px; + background-color: transparent; + font-weight: bold; +} + +th { + background-color: #dddddd; +} + +.viewcode-back { + font-family: sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} + +table.docutils { + border-spacing: 5px; + border-collapse: separate; +} + +/* Topbar --------------------------------------------------------------------*/ + +div.topbar { + height: 40px; + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 10000; + padding: 0px 10px; + background-color: #222; + background-color: #222222; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222)); + background-image: -moz-linear-gradient(top, #333333, #222222); + background-image: -ms-linear-gradient(top, #333333, #222222); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222)); + background-image: -webkit-linear-gradient(top, #333333, #222222); + background-image: -o-linear-gradient(top, #333333, #222222); + background-image: linear-gradient(to top, #333333, #222222); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); + overflow-x: hidden; + overflow-y: hidden; + width: 100%; +} + +div.topbar a.brand { + font-family: 'Source Sans Pro', sans-serif; + font-size: 26px; + color: #ffffff; + font-weight: 600; + text-decoration: none; + float: left; + display: block; + height: 32px; + padding: 8px 12px 0px 45px; + margin-left: -10px; + background: transparent url("gdt_logo.png") no-repeat 10px 4px; + /* background-image: url("gdt_logo.png"), none; */ + background-size: 32px 32px; +} + +#logotext1 { +} + +#logotext2 { + font-weight:200; + color: #ee00ff; /* #ff5000 */ +} +#logotext3 { + font-weight:200; +} + +div.topbar .brand:hover, div.topbar ul li a.homelink:hover { + background-color: #333; +} + +div.topbar ul { + font-size: 110%; + list-style-type: none; + margin: 0; + padding: 0 0 0 10px; + float: right; + color: #bfbfbf; + text-align: center; + text-decoration: none; + height: 100%; +} +div.topbar ul li { + float: left; + display: inline-block; + height: 30px; + margin: 5px; + padding: 0px; +} + +div.topbar ul li a { + color: #bfbfbf; + text-decoration: none; + padding: 5px; + display: block; + height: auto; + text-align: center; + vertical-align: middle; + border-radius: 4px; +} + +div.topbar ul li a:hover { + color: #ffffff; + text-decoration: none; +} + +div.dropdown { + position: relative; /* Fixed this to relative */ + display: inline-block; + z-index: 999999; +} + +div.dropdown-content { + display: none; /* Fix this at none */ + background-color: DimGray; + color: White; + width: 235px; + height: 155px; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + padding-top: 3px; + padding-right: 15px; + position: fixed; +} + +div.dropdown:hover .dropdown-content { + display: block; +} + +div.dropdown-content a { + display: block; +} + +div.dropdown-content a:hover { + color: white; +} + +div.dropdown a:hover { + color: #FF5000; +} + +div.dropdown z:hover { + color: #FF5000; + width: 10px; + display: none; +} + +div.dropdown z { + color: white; +} + +div.dropdown:after { + content: ""; + position: absolute; + right: -13px; + top: 9px; + width: 0; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid white; + z-index: 999999; +} + +div.dropdown:hover { + cursor: pointer; +} + +div.topbar ul li a.homelink { + width: 0px; + height: 0px; +} + +div.topbar form { + text-align: left; + margin: 0 0 0 5px; + position: relative; + filter: alpha(opacity=100); + -khtml-opacity: 1; + -moz-opacity: 1; + opacity: 1; +} + +div.topbar input { + background-color: #444; + background-color: rgba(255, 255, 255, 0.3); + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: medium; + font-weight: 200; + line-height: 1; + padding: 4px 9px; + color: #ffffff; + color: rgba(255, 255, 255, 0.75); + border: 1px solid #111; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); + -webkit-transition: none; + -moz-transition: none; + -ms-transition: none; + -o-transition: none; + transition: none; +} +div.topbar input:-moz-placeholder { + color: #e6e6e6; +} +div.topbar input::-webkit-input-placeholder { + color: #e6e6e6; +} +div.topbar input:hover { + background-color: #bfbfbf; + background-color: rgba(255, 255, 255, 0.5); + color: #ffffff; +} +div.topbar input:focus, div.topbar input.focused { + outline: 0; + background-color: #ffffff; + color: #404040; + text-shadow: 0 1px 0 #ffffff; + border: 0; + padding: 5px 10px; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); +} + + +/* Relation bar (breadcrumbs, prev, next) ------------------------------------*/ + +div.related { + height: 21px; + width: auto; + margin: 0 10px; + position: relative; + top: 42px; + clear: both; + left: 0; + right: 0; + z-index: 999; + font-size: 100%; + vertical-align: middle; + background-color: #fff; + border-bottom: 1px solid #bbb; +} +div.related ul { + padding: 0; + margin: 0; +} + + +/* Footer --------------------------------------------------------------------*/ + +footer { + display: block; + margin: 10px 10px 0px; + padding: 10px 0 0 0; + border-top: 1px solid #bbb; +} +.pull-right { + float: right; + width: 30em; + text-align: right; +} + + +/* Sphinx sidebar ------------------------------------------------------------*/ + +div.sphinxsidebar { + font-size: inherit; + border-radius: 3px; + background-color: #eee; + border: 1px solid #bbb; + word-wrap: break-word; + /* overflow-wrap is the canonical name for word-wrap in the CSS3 text draft. + We include it here mainly for future-proofing. */ + overflow-wrap: break-word; +} + +div.sphinxsidebarwrapper { + padding: 0px 0px 0px 5px; +} + +div.sphinxsidebar h3 { + font-family: 'Trebuchet MS', sans-serif; + font-size: 1.4em; + font-weight: normal; + margin: 5px 0px 0px 5px; + padding: 0; + line-height: 1.6em; +} +div.sphinxsidebar h4 { + font-family: 'Trebuchet MS', sans-serif; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} +div.sphinxsidebar p { +} +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} +div.sphinxsidebar ul { + margin: 0px 0px 0px 5px; + padding: 0; +} + +div.sphinxsidebar ul ul { + margin-left: 15px; + list-style-type: disc; +} + +/* If showing the global TOC (toctree), + color the current page differently */ +div.sphinxsidebar a.current { + color: #404040; +} +div.sphinxsidebar a.current:hover { + color: #404040; +} + + +/* document, documentwrapper, body, bodywrapper ----------------------------- */ + +div.document { + margin-top: 72px; + margin-left: 10px; + margin-right: 10px; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.body { + background-color: #ffffff; + padding: 0 0 0px 20px; +} + +div.bodywrapper { + margin: 0 0 0 230px; + max-width: 55em; +} + + +/* Header links ------------------------------------------------------------- */ + +a.headerlink { + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #0069d6; + color: white; + text-decoration: none; +} + + +/* Admonitions and warnings ------------------------------------------------- */ + +/* Shared by admonitions and warnings */ +div.admonition, +div.warning { + padding: 0px; + border-radius: 3px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} +div.admonition p, +div.warning p { + margin: 0.5em 1em 0.5em 1em; + padding: 0; +} +div.admonition pre, +div.warning pre { + margin: 0.4em 1em 0.4em 1em; +} +div.admonition p.admonition-title, +div.warning p.admonition-title { + margin: 0; + padding: 0.1em 0 0.1em 0.5em; + color: white; + font-weight: bold; + font-size: 1.1em; +} +div.admonition ul, div.admonition ol, +div.warning ul, div.warning ol { + margin: 0.1em 0.5em 0.5em 3em; + padding: 0; +} + +/* Admonitions only */ +div.admonition { + border: 1px solid #609060; + background-color: #e9ffe9; +} +div.admonition p.admonition-title { + background-color: #70A070; +} + +/* Warnings only */ +div.warning { + border: 1px solid #900000; + background-color: #ffe9e9; +} +div.warning p.admonition-title { + background-color: #b04040; +} + + +/* Figures ------------------------------------------------------------------ */ + +.figure.align-center { + clear: none; +} + +/* This is a div for containing multiple figures side-by-side, for use with + * .. container:: figures */ +div.figures { + border: 1px solid #CCCCCC; + background-color: #F8F8F8; + margin: 1em; + text-align: center; +} + +div.figures .figure { + clear: none; + float: none; + display: inline-block; + border: none; + margin-left: 0.5em; + margin-right: 0.5em; +} + +.field-list th { + white-space: nowrap; +} + +table.field-list { + border-spacing: 0px; + margin-left: 1px; + border-left: 5px solid rgb(238, 238, 238) !important; +} + +table.field-list th.field-name { + display: inline-block; + padding: 1px 8px 1px 5px; + white-space: nowrap; + background-color: rgb(238, 238, 238); + border-radius: 0 3px 3px 0; + -webkit-border-radius: 0 3px 3px 0; +} diff --git a/docs/_static/gdt_favicon.ico b/docs/_static/gdt_favicon.ico new file mode 100644 index 0000000..93bc87f Binary files /dev/null and b/docs/_static/gdt_favicon.ico differ diff --git a/docs/_static/gdt_logo.png b/docs/_static/gdt_logo.png new file mode 100644 index 0000000..7fcd1cf Binary files /dev/null and b/docs/_static/gdt_logo.png differ diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html new file mode 100644 index 0000000..c95a3ec --- /dev/null +++ b/docs/_templates/layout.html @@ -0,0 +1,6 @@ +{# layout.html #} +{# Import the layout of the theme. #} +{% extends "!layout.html" %} + +{% set css_files = css_files + ['_static/override.css'] %} +{{ super() }} diff --git a/docs/api/gdt.missions.hete2.fregate.detectors.FregateDetectors.rst b/docs/api/gdt.missions.hete2.fregate.detectors.FregateDetectors.rst new file mode 100644 index 0000000..4c2c449 --- /dev/null +++ b/docs/api/gdt.missions.hete2.fregate.detectors.FregateDetectors.rst @@ -0,0 +1,23 @@ +FregateDetectors +================ + +.. currentmodule:: gdt.missions.hete2.fregate.detectors + +.. autoclass:: FregateDetectors + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~FregateDetectors.A + ~FregateDetectors.B + ~FregateDetectors.C + ~FregateDetectors.D + + .. rubric:: Attributes Documentation + + .. autoattribute:: A + .. autoattribute:: B + .. autoattribute:: C + .. autoattribute:: D diff --git a/docs/api/gdt.missions.hete2.fregate.lightcurve.FregateLightCurve.rst b/docs/api/gdt.missions.hete2.fregate.lightcurve.FregateLightCurve.rst new file mode 100644 index 0000000..0a4ca63 --- /dev/null +++ b/docs/api/gdt.missions.hete2.fregate.lightcurve.FregateLightCurve.rst @@ -0,0 +1,59 @@ +FregateLightCurve +================= + +.. currentmodule:: gdt.missions.hete2.fregate.lightcurve + +.. autoclass:: FregateLightCurve + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~FregateLightCurve.detectors + ~FregateLightCurve.filename + ~FregateLightCurve.gti + ~FregateLightCurve.hdulist + ~FregateLightCurve.headers + ~FregateLightCurve.num_dets + ~FregateLightCurve.num_hdus + + .. rubric:: Methods Summary + + .. autosummary:: + + ~FregateLightCurve.close + ~FregateLightCurve.column + ~FregateLightCurve.columns_as_array + ~FregateLightCurve.energy_bands + ~FregateLightCurve.get_column_names + ~FregateLightCurve.num_energy_bands + ~FregateLightCurve.open + ~FregateLightCurve.phaii + ~FregateLightCurve.time_bins + ~FregateLightCurve.time_energy_bins + ~FregateLightCurve.write + + .. rubric:: Attributes Documentation + + .. autoattribute:: detectors + .. autoattribute:: filename + .. autoattribute:: gti + .. autoattribute:: hdulist + .. autoattribute:: headers + .. autoattribute:: num_dets + .. autoattribute:: num_hdus + + .. rubric:: Methods Documentation + + .. automethod:: close + .. automethod:: column + .. automethod:: columns_as_array + .. automethod:: energy_bands + .. automethod:: get_column_names + .. automethod:: num_energy_bands + .. automethod:: open + .. automethod:: phaii + .. automethod:: time_bins + .. automethod:: time_energy_bins + .. automethod:: write diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..06419b4 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,89 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.append(os.path.abspath('../src')) +from gdt.missions.hete2 import __version__ + + +# -- Project information ----------------------------------------------------- + +project = 'The Gamma-ray Data Tools: HETE-2' +license = 'Apache 2.0' +author = 'Cleveland, Goldstein, and Kocevski' + +# The full version, including alpha/beta/rc tags +version = __version__ +release = __version__ + + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.viewcode', 'sphinx.ext.inheritance_diagram', + 'sphinx.ext.mathjax', 'sphinx.ext.napoleon', 'nbsphinx', + 'IPython.sphinxext.ipython_console_highlighting', + 'sphinx_automodapi.automodapi', 'sphinx.ext.intersphinx'] +# for external cross-references that are on the local machine, the relative +# path must be converted to an absolute path otherwise the intersphinx generates +# a broken link. +intersphinx_mapping = {'gdt-core': + ('https://astro-gdt.readthedocs.io/en/latest/', None)} + +napoleon_google_docstring = True +napoleon_use_ivar = False +napoleon_use_rtype = False +numpydoc_show_class_members = False + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] +mathjax_path="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" + + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +source_suffix = '.rst' + +# The name of the Pygments (syntax highlighting) style to use. +#pygments_style = 'friendly'#'sphinx' + + +# -- 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 = 'bootstrap-astropy' +html_theme_options = { + 'logotext1': 'gdt', # white, semi-bold + 'logotext2': '-hete2', # orange, light + 'logotext3': ':docs', # white, light + 'astropy_project_menubar': False + } + +html_favicon = '_static/gdt_favicon.ico' + +# 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'] + + +# -- PDF options ------------------------------------------------------------- +latex_documents = [('index', 'hete2-gammaray-data-tools.tex', project, author, 'manual')] + diff --git a/docs/images/Hete_om3.jpg b/docs/images/Hete_om3.jpg new file mode 100644 index 0000000..566f2da Binary files /dev/null and b/docs/images/Hete_om3.jpg differ diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..2c8b92e --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,106 @@ +.. _gdt-hete2: + +**************************************************** +Welcome to HETE-2 Tools Documentation! +**************************************************** + +.. figure:: images/Hete_om3.jpg +(Image from NASA/MIT) + +The HETE-2 Gamma-ray Data Tools (GDT) is a toolkit for HETE-2 data built on the +:external:ref:`GDT Core Package`. + + +The HETE-2 Satellite was launched on October 9, 2000 and operated until March 2008. +HETE-2 had three instruments: The gamma-ray instrument (FREGATE) sensitive in the 6--400keV +energy range, the Wide-field X-ray Monitor (WXM) sensitive in the 2--25keV energy range, and +the Soft X-ray Camera (SXC) sensitive in the 0.5--10keV energy range. + +Currently the toolkit is limited to reading the publicly available lightcurve files from the +FREGATE instrument. Future versions may include decoding the raw telemetry files available +as 'ipp' files when more information describing the data format becomes available. + +.. rubric:: Citing + +If you use the HETE-2 Gamma-ray Data Tools in your research and publications, +we would definitely appreciate an appropriate acknowledgment and citation! We +suggest the following BibTex: + +:: + + @misc{GDT-HETE2, + author = {Adam Goldstein and William H. Cleveland and Daniel Kocevski}, + title = {HETE-2 Gamma-ray Data Tools: v1.0.0}, + year = 2024, + url = {https://github.com/USRA-STI/gdt-hete2} + } + + +.. rubric:: Acknowledgments + +The creation of the Compton Gamma-ray Data Tools were funded by the NASA's +Astrophysics Data Analysis Program (ADAP) via grant number 80NSSC21K0651. + +*************** +Getting Started +*************** +.. toctree:: + :maxdepth: 1 + + install + +****************** +User Documentation +****************** + +HETE-2 Definitions +================= +.. toctree:: + :maxdepth: 1 + + missions/hete2/time + +FREGATE +========= + +Instrument Definitions +---------------------- + +.. toctree:: + :maxdepth: 1 + + missions/hete2/fregate/detectors + +Data Types +---------- + +.. toctree:: + :maxdepth: 1 + + missions/hete2/fregate/lightcurve + +Data Finders and Catalogs +------------------------- + +.. toctree:: + :maxdepth: 1 + + missions/hete2/fregate/finders + +---- + +******* +License +******* +.. toctree:: + :maxdepth: 1 + + license + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/install.rst b/docs/install.rst new file mode 100644 index 0000000..cb9ff42 --- /dev/null +++ b/docs/install.rst @@ -0,0 +1,128 @@ +.. _install: + + +Installation +============ + +.. Note:: Requires: Python >=3.8 + + Tested on: + + * macOS Monterey (12.6.4) - Ventura (13.2.1) + +How to Install +-------------- + + +The GDT-HETE2 package can be installed from PyPI using: + +.. code-block:: sh + + pip install astro-gdt-hete2 + gdt-data init + + +.. _download_test_data: + + +Downloading Test/Tutorial Data +------------------------------ +To download the data files used in the documentation and for testing, you need +to run the ``gdt-data`` script after installation. The downloader +script is designed so that you can download data from specific missions, or +download all of the test/tutorial data. To see the list of available missions + +.. code-block:: sh + + gdt-data --help + +If you want to download the HETE-2 test/tutorial data only, for example: + +.. code-block:: sh + + gdt-data download hete2-fregate + +Or to download all of the data: + +.. code-block:: sh + + gdt-data download --all + +The data are downloaded to a default directory. To access the data from the GDT, +there is a variable at the main level that stores the path dictionary for each +mission. To access the HETE-2 test data directory: + + >>> from gdt.core import data_path + >>> hete2_path = data_path.joinpath('hete2-fregate') + +Once you are done using the data, you can delete the data files with the following command: + +.. code-block:: sh + + gdt-data clean hete2-fregate + +or delete all of the data with: + +.. code-block:: sh + + gdt-data clean --all + +---- + +Quickstart +---------- +To load the GDT-HETE2 package within your python environment, simply:: + + >>> import gdt.missions.hete2 as hete2 + + +How to Uninstall +---------------- + +To uninstall: + +.. code-block:: sh + + gdt-data clean hete2-fregate + pip uninstall astro-gdt-hete2 + +There are also a number of files for the tools that are copied into your +``$HOME/.gammaray_data_tools`` directory. You can delete these files if you +wish. + + +Known Issues +------------ +* **There appears to be some differences arising between installations on Mac ARM + processors (M1 and M2 chips) and other Mac or Linux processors.** As of now, + this only shows up when using some of the minimizers provided through + scipy.optimize.minimize for spectral fitting. Users can test for the presence + of these differences by running the unit tests. The known failures on Mac ARM + processors are: + + * test_fitting.py::TestSpectralFitterOne::test_hessian + * test_fitting.py::TestSpectralFitterOne::test_jacobian + * test_fitting.py::TestSpectralFitterOne::test_residuals + + The current understanding is that differences arise in spectral fit values + above machine precision, but represent < 1% relative errors on the fit values + themselves. The exact origin of these differences is unclear, but may be + related to the underlying C or FORTRAN libraries and compilers that are used + to compile scipy. Further investigation is ongoing. + +* **The virtual environment is using your system ipython (or other package) + install.** This can sometimes happen if you didn't install ipython (or other + package) in the virtual environment. Try installing ipython (or other package) + and restart your virtual environment. + +* **You observe the following error**:: + + ImportError: No module named '_tkinter' + + This is a situation where Matplotlib is using the ``tkinter`` backend for + plotting. You would see this error if you don't have ``tkinter`` installed. + You don't need to install ``tkinter`` if you don't want to; instead, you can + create a file named `matplotlibrc` in your working directory that contains the + following:: + + backend : Agg \ No newline at end of file diff --git a/docs/license.rst b/docs/license.rst new file mode 100644 index 0000000..4262aae --- /dev/null +++ b/docs/license.rst @@ -0,0 +1,181 @@ +.. _license: + +Apache License +============== +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +____________________________________________________________ + +1. **Definitions.** + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. **Grant of Copyright License.** Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. **Grant of Patent License.** Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. **Redistribution.** You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. **Submission of Contributions.** Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. **Trademarks.** This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. **Disclaimer of Warranty.** Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. **Limitation of Liability.** In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. **Accepting Warranty or Additional Liability.** While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +**END OF TERMS AND CONDITIONS** diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..954237b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/missions/hete2/fregate/detectors.rst b/docs/missions/hete2/fregate/detectors.rst new file mode 100644 index 0000000..a21b2b5 --- /dev/null +++ b/docs/missions/hete2/fregate/detectors.rst @@ -0,0 +1,58 @@ +.. _fregate-detectors: +.. |FregateDetectors| replace:: :class:`~gdt.missions.hete2.fregate.detectors.FregateDetectors` +.. |Detectors| replace:: :class:`~gdt.core.detector.Detectors` + +************************************************************************ +Fregate Detector Definitions (:mod:`gdt.missions.hete2.fregate.detectors`) +************************************************************************ +The |FregateDetectors| class contains the naming and orientation definitions of the +FREGATE detectors. + +There are four FREGATE detectors ("A", "B", "C", and "D") that are aimed in the same +direction with two dectectors positioned on two sides of the Wide Field X-ray Monitor. +You can see the layout of the detectors below, the FREGATE detectors are the ones +marked with 'F' (image from MIT). + +.. figure:: figures/topview.gif + +We can easily retrieve a detector definition by using standard "dot" notation: + + >>> from gdt.missions.hete2.fregate.detectors import FregateDetectors + >>> FregateDetectors.A + + +We can retrieve the string name of the detector: + + >>> FregateDetectors.C.name + 'C' + +There is also a standard detector indexing scheme that is used for all FREGATE +detectors: + + >>> FregateDetectors.B.number + 1 + +Since the |FregateDetectors| class inherits from the |Detectors| base class, we +can also retrieve the pointing information of a FREGATE detector: + + >>> # detector azimuth, zenith + >>> FregateDetectors.from_str('A').pointing() + (, ) + + >>> # detector elevation + FregateDetectors.B.elevation + + +We can also iterate over all FREGATE detectors: + + >>> # the list of detector names + >>> print([det.name for det in FregateDetectors]) + ['A', 'B', 'C', 'D'] + + +Reference/API +============= + +.. automodapi:: gdt.missions.hete2.fregate.detectors + :inherited-members: + diff --git a/docs/missions/hete2/fregate/figures/lightcurve_plot.png b/docs/missions/hete2/fregate/figures/lightcurve_plot.png new file mode 100644 index 0000000..803e6ec Binary files /dev/null and b/docs/missions/hete2/fregate/figures/lightcurve_plot.png differ diff --git a/docs/missions/hete2/fregate/figures/topview.gif b/docs/missions/hete2/fregate/figures/topview.gif new file mode 100644 index 0000000..352c6ce Binary files /dev/null and b/docs/missions/hete2/fregate/figures/topview.gif differ diff --git a/docs/missions/hete2/fregate/lightcurve.rst b/docs/missions/hete2/fregate/lightcurve.rst new file mode 100644 index 0000000..9405348 --- /dev/null +++ b/docs/missions/hete2/fregate/lightcurve.rst @@ -0,0 +1,109 @@ +.. _fregate-lightcurve: +.. |FregateLightCurve| replace:: :class:`~gdt.missions.hete2.fregate.lightcurve.FregateLightCurve` +.. |FitsFileContextManager| replace:: :class:`~gdt.core.file.FitsFileContextManager` +.. |Phaii| replace:: :class:`~gdt.core.phaii.Phaii` +.. |TimeEnergyBins| replace:: :class:`~gdt.core.data_primitives.TimeEnergyBins` +.. |TimeBins| replace:: :class:`~gdt.core.data_primitives.TimeBins` +.. |Gti| replace:: :class:`~gdt.core.data_primitives.Gti` + +************************************************************************ +FregateLightCurve (:mod:`gdt.missions.hete2.fregate.lightcurve`) +************************************************************************ + +The |FregateLightCurve| class allows the user to load a FREGATE light curve +fits file from HEASARC and extract the |TimeBins|, |TimeEnergyBins|, |Phaii|, +and |Gti| data objects from it. + +The FREGATE light curve file is a FITS file that has 1 primary extension, 4 detector data +extensions, and a GTI extension. + +The 4 detector extensions contains counts in 4 energy ranges that overlap with each other. +Because of this, you must specify and energy band index (0 through 3) when extracting the +time bins, time energy bins, and PHA-II data from the file. + +Examples +-------- +First we will create a FregateLightCurve object using a sample file downloaded with gdt-data: + + +>>> from gdt.core import data_path +>>> lc_file = data_path / 'hete2-fregate' / 'GAMMA_sum_20020531.lc' +>>> lc_obj = FregateLightCurve.open(lc_file) + +Now let's retrieve some basic information about the file. + +The number of detectors in the file: + +>>> lc_obj.num_dets +4 + +The detectors values in the file: + +>>> lc_obj.detectors +[, + , + , + ] + +The time zero value and GTI contained in the file: + +>>> lc_obj.time_zero +706916972.2000004 +>>> lc_obj.gti + + +Because the file has overlapping energy ranges that are incompatible with some analysis functions, you have +to specify both the detector you are interested in and the energy band index. + +The energy band index has a range of 0 to 3 and the energy bounds can be found for each detector with: + +>>> lc_obj.energy_bands('A') +array([[ 8., 40.], + [ 8., 70.], + [ 32., 400.], + [ 400., 1000.]]) + +The above shows that 0 = 8 -- 40 keV, 1 = 8 -- 70 keV, 2 = 32 -- 400 keV and 3 = 400 -- 1000 keV + + +To retrieve the time bins for detector 'A' for the energy range of 8 -- 70keV: + +>>> lc_obj.time_bin('A', 1) + + +The counts for each bin can be retrieved with: + +>>> lc_obj.time_bins('A', 1).counts +array([250.2, 219.7, 265.5, ..., 256.3, 265.5, 253.3], dtype='>f4') + +The time_energy_bin can be retrieved in a similar manner with: + +>>> lc_obj.time_energy_bins('A', 1) + + + +To retrieve a PHA II object and use it to plot a light curve do the following: + +>>> import matplotlib.pyplot as plt +>>> from gdt.core.plot.lightcurve import Lightcurve +>>> pha = lc_file.phaii('A', 0) +>>> plot = Lightcurve(data=pha.to_lightcurve()) +>>> plt.show() + +.. figure:: figures/lightcurve_plot.png + + + +Reference/API +============= + +.. automodapi:: gdt.missions.hete2.fregate.lightcurve + :inherited-members: + diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/license.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..301182d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,14 @@ +astro-gdt +pyproj>=1.9.6 +numpy>=1.17.3 +scipy>=1.1.0 +matplotlib +astropy>=5.1 +healpy>=1.12.4 +pytest + +Sphinx +astropy-sphinx-theme +nbsphinx +ipython +sphinx-automodapi diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..e7c593f --- /dev/null +++ b/setup.py @@ -0,0 +1,86 @@ +# CONTAINS TECHNICAL DATA/COMPUTER SOFTWARE DELIVERED TO THE U.S. GOVERNMENT WITH UNLIMITED RIGHTS +# +# Contract No.: CA 80MSFC17M0022 +# Contractor Name: Universities Space Research Association +# Contractor Address: 7178 Columbia Gateway Drive, Columbia, MD 21046 +# +# Copyright 2023 by Universities Space Research Association (USRA). All rights reserved. +# +# Developed by: Cori Fletcher +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# Based on the work by: +# William Cleveland and Adam Goldstein +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# and +# Daniel Kocevski +# National Aeronautics and Space Administration (NASA) +# Marshall Space Flight Center +# Astrophysics Branch (ST-12) +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License +# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing permissions and limitations under the +# License. +# +import sys +from pathlib import Path + +from setuptools import setup, find_namespace_packages + +if __name__ == '__main__': + pwd = Path(__file__).parent + sys.path.append(str(pwd / 'src')) + import gdt.missions.hete2 as hete2 + + setup( + name="astro-gdt-hete2", + version=hete2.__version__, + description="Gamma-ray Data Tools: hete2 Mission", + long_description=(pwd / "PYPI-README.rst").read_text(), + author='C. Fletcher', + url='https://github.com/USRA-STI/gdt-hete2', + packages=find_namespace_packages(where='src', include=["*"]), + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache Software License", + "Operating System :: MacOS", + "Operating System :: POSIX :: Linux", + "Topic :: Scientific/Engineering :: Astronomy", + "Topic :: Software Development :: Libraries", + ], + license_files=['license.txt'], + keywords=['astronomy', 'gammaray', 'gamma-ray', 'usra'], + package_dir={"": "src"}, + package_data={ + 'gdt.data': ['hete2-fregate.urls'] + }, + include_package_data=True, + python_requires='>=3.8', + install_requires=[ + 'astro-gdt>=2.0.0', + 'pyproj>=1.9.6', + 'numpy>=1.17.3', + 'scipy>=1.1.0', + 'matplotlib>=3.7.1', + 'astropy>=3.1', + 'healpy>=1.12.4', + 'cartopy>=0.21.1', + ], + project_urls={ + 'Documentation': 'https://astro-gdt-hete2.readthedocs.io/en/latest/', + 'Source': 'https://github.com/USRA-STI/gdt-hete2', + 'Tracker': 'https://github.com/USRA-STI/gdt-hete2/issues', + } + + ) diff --git a/src/gdt/data/hete2-fregate.urls b/src/gdt/data/hete2-fregate.urls new file mode 100644 index 0000000..f86632d --- /dev/null +++ b/src/gdt/data/hete2-fregate.urls @@ -0,0 +1,3 @@ +https://heasarc.gsfc.nasa.gov/FTP/hete2/data/GRBS/lightcurves/GAMMA_sum_20020531.lc +https://heasarc.gsfc.nasa.gov/FTP/hete2/data/timeline/hete_sc_aspect.txt +https://heasarc.gsfc.nasa.gov/FTP/hete2/data/timeline/sc_aspect.dat diff --git a/src/gdt/missions/hete2/__init__.py b/src/gdt/missions/hete2/__init__.py new file mode 100644 index 0000000..a24c3f4 --- /dev/null +++ b/src/gdt/missions/hete2/__init__.py @@ -0,0 +1,38 @@ +# CONTAINS TECHNICAL DATA/COMPUTER SOFTWARE DELIVERED TO THE U.S. GOVERNMENT +# WITH UNLIMITED RIGHTS +# +# Grant No.: 80NSSC21K0651 +# Grantee Name: Universities Space Research Association +# Grantee Address: 425 3rd Street SW, Suite 950, Washington DC 20024 +# +# Copyright (c) 2024 by Universities Space Research Association (USRA). All rights reserved. +# +# Developed by: +# William Cleveland +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# This work is a derivative of the Gamma-ray Data Tools (GDT), including the Core and Fermi packages, originally +# developed by the following: +# +# William Cleveland and Adam Goldstein +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# Daniel Kocevski +# National Aeronautics and Space Administration (NASA) +# Marshall Space Flight Center +# Astrophysics Branch (ST-12) +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under the License. + +__version__ = '1.0.0' diff --git a/src/gdt/missions/hete2/fregate/__init__.py b/src/gdt/missions/hete2/fregate/__init__.py new file mode 100644 index 0000000..2532ee1 --- /dev/null +++ b/src/gdt/missions/hete2/fregate/__init__.py @@ -0,0 +1,36 @@ +# CONTAINS TECHNICAL DATA/COMPUTER SOFTWARE DELIVERED TO THE U.S. GOVERNMENT +# WITH UNLIMITED RIGHTS +# +# Grant No.: 80NSSC21K0651 +# Grantee Name: Universities Space Research Association +# Grantee Address: 425 3rd Street SW, Suite 950, Washington DC 20024 +# +# Copyright (c) 2024 by Universities Space Research Association (USRA). All rights reserved. +# +# Developed by: +# William Cleveland +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# This work is a derivative of the Gamma-ray Data Tools (GDT), including the Core and Fermi packages, originally +# developed by the following: +# +# William Cleveland and Adam Goldstein +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# Daniel Kocevski +# National Aeronautics and Space Administration (NASA) +# Marshall Space Flight Center +# Astrophysics Branch (ST-12) +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under the License. diff --git a/src/gdt/missions/hete2/fregate/detectors.py b/src/gdt/missions/hete2/fregate/detectors.py new file mode 100644 index 0000000..cb4ab59 --- /dev/null +++ b/src/gdt/missions/hete2/fregate/detectors.py @@ -0,0 +1,77 @@ +# CONTAINS TECHNICAL DATA/COMPUTER SOFTWARE DELIVERED TO THE U.S. GOVERNMENT +# WITH UNLIMITED RIGHTS +# +# Grant No.: 80NSSC21K0651 +# Grantee Name: Universities Space Research Association +# Grantee Address: 425 3rd Street SW, Suite 950, Washington DC 20024 +# +# Copyright (c) 2024 by Universities Space Research Association (USRA). All rights reserved. +# +# Developed by: +# William Cleveland +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# This work is a derivative of the Gamma-ray Data Tools (GDT), including the Core and Fermi packages, originally +# developed by the following: +# +# William Cleveland and Adam Goldstein +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# Daniel Kocevski +# National Aeronautics and Space Administration (NASA) +# Marshall Space Flight Center +# Astrophysics Branch (ST-12) +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under the License. +import astropy.units as u +from gdt.core.detector import Detectors + +__all__ = ['FregateDetectors'] + + +class FregateDetectors(Detectors): + """The FREGATE detector name and orientation definitions. + + .. rubric:: Attributes Summary + .. autosummary:: + + azimuth + elevation + full_name + number + zenith + + .. autosummary:: + + from_full_name + from_num + from_str + pointing + skycoord + + .. rubric:: Attributes Documentation + + .. autoattribute:: full_name + .. autoattribute:: number + + .. rubric:: Methods Documentation + + .. automethod:: from_full_name + .. automethod:: from_num + .. automethod:: from_str + """ + A = ('FREGATEA', 0, 0 * u.deg, 180 * u.deg) + B = ('FREGATEB', 1, 0 * u.deg, 180 * u.deg) + C = ('FREGATEC', 2, 0 * u.deg, 180 * u.deg) + D = ('FREGATED', 3, 0 * u.deg, 180 * u.deg) diff --git a/src/gdt/missions/hete2/fregate/lightcurve.py b/src/gdt/missions/hete2/fregate/lightcurve.py new file mode 100644 index 0000000..dba7b14 --- /dev/null +++ b/src/gdt/missions/hete2/fregate/lightcurve.py @@ -0,0 +1,305 @@ +# CONTAINS TECHNICAL DATA/COMPUTER SOFTWARE DELIVERED TO THE U.S. GOVERNMENT +# WITH UNLIMITED RIGHTS +# +# Grant No.: 80NSSC21K0651 +# Grantee Name: Universities Space Research Association +# Grantee Address: 425 3rd Street SW, Suite 950, Washington DC 20024 +# +# Copyright (c) 2024 by Universities Space Research Association (USRA). All rights reserved. +# +# Developed by: +# William Cleveland +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# This work is a derivative of the Gamma-ray Data Tools (GDT), including the Core and Fermi packages, originally +# developed by the following: +# +# William Cleveland and Adam Goldstein +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# Daniel Kocevski +# National Aeronautics and Space Administration (NASA) +# Marshall Space Flight Center +# Astrophysics Branch (ST-12) +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under the License. +# CONTAINS TECHNICAL DATA/COMPUTER SOFTWARE DELIVERED TO THE U.S. GOVERNMENT +# WITH UNLIMITED RIGHTS +# +# Grant No.: 80NSSC21K0651 +# Grantee Name: Universities Space Research Association +# Grantee Address: 425 3rd Street SW, Suite 950, Washington DC 20024 +# +# Copyright (c) 2024 by Universities Space Research Association (USRA). All rights reserved. +# +# Developed by: +# William Cleveland +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# This work is a derivative of the Gamma-ray Data Tools (GDT), including the Core and Fermi packages, originally +# developed by the following: +# +# William Cleveland and Adam Goldstein +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# Daniel Kocevski +# National Aeronautics and Space Administration (NASA) +# Marshall Space Flight Center +# Astrophysics Branch (ST-12) +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under the License. +import warnings +from dataclasses import dataclass +from typing import Optional, Union, List, Dict + +import astropy.io.fits as fits +import numpy as np +from astropy.time import Time + +from gdt.core.file import FitsFileContextManager +from gdt.core.phaii import Phaii +from gdt.core.data_primitives import Gti, TimeEnergyBins, TimeBins + +from .detectors import FregateDetectors + +__all__ = ['FregateLightCurve', 'FregatePhaii'] + + +@dataclass +class FregateLightCurveData: + tstart: np.ndarray + counts: np.ndarray + energy_bands: np.ndarray + time_delta: float + + +class FregatePhaii(Phaii): + """Subclass Phaii to provide default header definitions for the Phaii extracted + from the light curve files.""" + + def _build_hdulist(self): + """create FITS and primary header""" + hdulist = fits.HDUList() + primary_hdu = fits.PrimaryHDU() + hdulist.append(primary_hdu) + + """ create the ebounds extension""" + ebounds_hdu = self._ebounds_table() + hdulist.append(ebounds_hdu) + + """create the spectrum extension""" + spectrum_hdu = self._spectrum_table() + hdulist.append(spectrum_hdu) + + """ create the GTI extension""" + gti_hdu = self._gti_table() + hdulist.append(gti_hdu) + + return hdulist + + def _ebounds_table(self): + chan_col = fits.Column(name='CHANNEL', format='1I', + array=np.arange(self.num_chans, dtype=int)) + emin_col = fits.Column(name='E_MIN', format='1E', unit='keV', + array=self.ebounds.low_edges()) + emax_col = fits.Column(name='E_MAX', format='1E', unit='keV', + array=self.ebounds.high_edges()) + + hdu = fits.BinTableHDU.from_columns([chan_col, emin_col, emax_col]) + + return hdu + + def _spectrum_table(self): + tstart = np.copy(self.data.tstart) + tstop = np.copy(self.data.tstop) + if self.trigtime is not None: + tstart += self.trigtime + tstop += self.trigtime + + counts_col = fits.Column(name='COUNTS', + format='{}I'.format(self.num_chans), + bzero=32768, bscale=1, unit='count', + array=self.data.counts) + expos_col = fits.Column(name='EXPOSURE', format='1E', unit='s', + array=self.data.exposure) + time_col = fits.Column(name='TIME', format='1D', unit='s', + bzero=self.trigtime, array=tstart) + endtime_col = fits.Column(name='ENDTIME', format='1D', unit='s', + bzero=self.trigtime, array=tstop) + hdu = fits.BinTableHDU.from_columns([counts_col, expos_col, + time_col, endtime_col]) + + return hdu + + def _gti_table(self): + tstart = np.array(self.gti.low_edges()) + tstop = np.array(self.gti.high_edges()) + + start_col = fits.Column(name='START', format='1D', unit='s', + bzero=self.trigtime, array=tstart) + stop_col = fits.Column(name='STOP', format='1D', unit='s', + bzero=self.trigtime, array=tstop) + hdu = fits.BinTableHDU.from_columns([start_col, stop_col]) + + return hdu + + +class FregateLightCurve(FitsFileContextManager): + """FREGATE lightcurve file containing PHAII from multiple detectors. + """ + + def __init__(self): + super().__init__() + self._data: Dict[FregateDetectors, FregateLightCurveData] = {} + self.time_zero: Optional[float] = None + self._gti: Optional[Gti] = None + + def _data_from_hdu(self, hdu: fits.BinTableHDU): + + detector = FregateDetectors.from_full_name(hdu.header['INSTRUME']) + + # Retrieve the data from the HDU + self._data[detector] = FregateLightCurveData( + tstart=hdu.data['TIME'], # Start time of each bin + counts=hdu.data['RATE'], # 2D array containing counts by energy band + energy_bands=np.array( # The energy bands defined in the light curve file + [[hdu.header['E_MIN1'] if 'E_MIN1' in hdu.header else 8.0, + hdu.header['E_MIN2'] if 'E_MIN2' in hdu.header else 8.0, + hdu.header['E_MIN3'] if 'E_MIN3' in hdu.header else 32.0, + hdu.header['E_MIN4'] if 'E_MIN4' in hdu.header else 400.0], + [hdu.header['E_MAX1'] if 'E_MAX1' in hdu.header else 40.0, + hdu.header['E_MAX2'] if 'E_MAX2' in hdu.header else 70.0, + hdu.header['E_MAX3'] if 'E_MAX3' in hdu.header else 400.0, + hdu.header['E_MAX4'] if 'E_MAX4' in hdu.header else 1000.0]]).T, + time_delta=hdu.header['TIMEDEL'] # The size of each bin in seconds + ) + t0 = Time(hdu.header['TIMEZERO'], format='decimalyear').gps # Time of the detection + if self.time_zero is None: + self.time_zero = t0 + elif self.time_zero != t0: + warnings.warn(f'Time zero value for detector {detector} is different from previous read time zero') + + @property + def detectors(self) -> List[FregateDetectors]: + """(list): The detectors in the file""" + return list(self._data.keys()) + + @property + def num_dets(self) -> int: + """(int): Number of detectors in the file""" + return len(self.detectors) + + @staticmethod + def _detector_from_value(value: Union[str, int, FregateDetectors]) -> FregateDetectors: + if isinstance(value, FregateDetectors): + index = value + elif isinstance(value, str): + try: + index = FregateDetectors.from_str(value) + except ValueError: + index = FregateDetectors.from_full_name(value) + elif isinstance(value, int): + index = FregateDetectors.from_num(value) + else: + raise TypeError('value must be a str, int, or FregateDetectors object') + return index + + def energy_bands(self, detector: Union[FregateDetectors, str, int]): + data = self._data[self._detector_from_value(detector)] + return data.energy_bands + + def num_energy_bands(self, detector: Union[FregateDetectors, str, int]): + return self.energy_bands(detector).shape[1] + + def time_bins(self, detector: Union[FregateDetectors, str, int], energy_band: int) -> TimeBins: + data = self._data[self._detector_from_value(detector)] + return TimeBins(counts=data.counts[:, energy_band], lo_edges=data.tstart, + hi_edges=data.tstart + data.time_delta, exposure=[data.time_delta] * data.counts.shape[0]) + + def time_energy_bins(self, detector: Union[str, int, FregateDetectors], energy_band: int) -> TimeEnergyBins: + """Retrieve the TimeEnergyBins object for the given detector. + + Args: + detector (str, int, or :class:`FregateDetectors`) + energy_band (int) + + Returns: + (:class:`TimeEnergyBins`) + """ + data = self._data[self._detector_from_value(detector)] + return TimeEnergyBins(counts=data.counts[:, energy_band].reshape(-1, 1), + tstart=data.tstart, tstop=data.tstart + data.time_delta, + exposure=[data.time_delta] * data.counts.shape[0], + emin=data.energy_bands[energy_band, 0].reshape(-1, 1), + emax=data.energy_bands[energy_band, 1].reshape(-1, 1)) + + def phaii(self, detector: Union[str, int, FregateDetectors], energy_band: int) -> Phaii: + """Retrieve the Phaii object for the given detector. + + Args: + detector (str, int, or :class:`FregateDetectors`) + energy_band (int) + + Returns: + (:class:`Phaii`) + """ + data = self._data[self._detector_from_value(detector)] + return FregatePhaii.from_data(self.time_energy_bins(detector, energy_band), + gti=self._gti, trigger_time=self.time_zero) + + @property + def gti(self) -> Gti: + """Retrieve the GTI extension data. + + Returns: + (:class:`Gti`) + """ + return self._gti + + @classmethod + def open(cls, file_path, **kwargs): + """Open a FREGATE file containing PHA time series from multiple detectors. + + Args: + file_path (str): The file path + + Returns: + (:class:`FregateLightCurve`) + """ + obj = super().open(file_path, **kwargs) + + # Populate the EnergyTimeBins + for i in range(1, len(obj.hdulist) - 1): + hdu = obj.hdulist[i] + obj._data_from_hdu(hdu) + + # Retrieve the GTI + data = obj.hdulist[-1].data + obj._gti = Gti.from_bounds(data['START'], data['STOP']) + obj.close() + return obj + + def __repr__(self): + return f'<{self.__class__.__name__}: {self.num_dets} detectors>' diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..45f26f5 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,40 @@ +# CONTAINS TECHNICAL DATA/COMPUTER SOFTWARE DELIVERED TO THE U.S. GOVERNMENT +# WITH UNLIMITED RIGHTS +# +# Grant No.: 80NSSC21K0651 +# Grantee Name: Universities Space Research Association +# Grantee Address: 425 3rd Street SW, Suite 950, Washington DC 20024 +# +# Copyright (c) 2024 by Universities Space Research Association (USRA). All rights reserved. +# +# Developed by: +# William Cleveland +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# This work is a derivative of the Gamma-ray Data Tools (GDT), including the Core and Fermi packages, originally +# developed by the following: +# +# William Cleveland and Adam Goldstein +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# Daniel Kocevski +# National Aeronautics and Space Administration (NASA) +# Marshall Space Flight Center +# Astrophysics Branch (ST-12) +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under the License. + +from pathlib import Path + +tests_path = Path(__file__).parent diff --git a/tests/missions/__init__.py b/tests/missions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/missions/hete2/__init__.py b/tests/missions/hete2/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/missions/hete2/fregate/__init__.py b/tests/missions/hete2/fregate/__init__.py new file mode 100644 index 0000000..2532ee1 --- /dev/null +++ b/tests/missions/hete2/fregate/__init__.py @@ -0,0 +1,36 @@ +# CONTAINS TECHNICAL DATA/COMPUTER SOFTWARE DELIVERED TO THE U.S. GOVERNMENT +# WITH UNLIMITED RIGHTS +# +# Grant No.: 80NSSC21K0651 +# Grantee Name: Universities Space Research Association +# Grantee Address: 425 3rd Street SW, Suite 950, Washington DC 20024 +# +# Copyright (c) 2024 by Universities Space Research Association (USRA). All rights reserved. +# +# Developed by: +# William Cleveland +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# This work is a derivative of the Gamma-ray Data Tools (GDT), including the Core and Fermi packages, originally +# developed by the following: +# +# William Cleveland and Adam Goldstein +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# Daniel Kocevski +# National Aeronautics and Space Administration (NASA) +# Marshall Space Flight Center +# Astrophysics Branch (ST-12) +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under the License. diff --git a/tests/missions/hete2/fregate/test_lightcurve.py b/tests/missions/hete2/fregate/test_lightcurve.py new file mode 100644 index 0000000..8e37807 --- /dev/null +++ b/tests/missions/hete2/fregate/test_lightcurve.py @@ -0,0 +1,103 @@ +# CONTAINS TECHNICAL DATA/COMPUTER SOFTWARE DELIVERED TO THE U.S. GOVERNMENT +# WITH UNLIMITED RIGHTS +# +# Grant No.: 80NSSC21K0651 +# Grantee Name: Universities Space Research Association +# Grantee Address: 425 3rd Street SW, Suite 950, Washington DC 20024 +# +# Copyright (c) 2024 by Universities Space Research Association (USRA). All rights reserved. +# +# Developed by: +# William Cleveland +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# This work is a derivative of the Gamma-ray Data Tools (GDT), including the Core and Fermi packages, originally +# developed by the following: +# +# William Cleveland and Adam Goldstein +# Universities Space Research Association +# Science and Technology Institute +# https://sti.usra.edu +# +# Daniel Kocevski +# National Aeronautics and Space Administration (NASA) +# Marshall Space Flight Center +# Astrophysics Branch (ST-12) +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under the License. + +import unittest +from gdt.core import data_path +from gdt.core.data_primitives import TimeBins, TimeEnergyBins, Gti + +from gdt.missions.hete2.fregate.detectors import FregateDetectors +from gdt.missions.hete2.fregate.lightcurve import FregateLightCurve, FregatePhaii + + +class TestFregateLightCurve(unittest.TestCase): + lc_file: FregateLightCurve + + @classmethod + def setUpClass(cls): + path = data_path / 'hete2-fregate' / 'GAMMA_sum_20020531.lc' + cls.lc_file = FregateLightCurve.open(path) + + @classmethod + def tearDownClass(cls): + cls.lc_file.close() + + def test_metadata(self): + self.assertEqual(self.lc_file.num_dets, 4) + self.assertEqual(self.lc_file.detectors, [FregateDetectors.A, FregateDetectors.B, + FregateDetectors.C, FregateDetectors.D]) + self.assertEqual(self.lc_file.time_zero, 706916972.2000004) + + def test_time_bins(self): + time_bin = self.lc_file.time_bins('A', 0) + self.assertEqual(type(time_bin), TimeBins) + self.assertAlmostEqual(time_bin.range[0], -403.381, places=3) + self.assertAlmostEqual(time_bin.range[1], 83885.53, places=2) + self.assertEqual(len(time_bin.counts), 73620) + + def test_time_energy_bins(self): + te_bins = self.lc_file.time_energy_bins('A', 0) + self.assertEqual(type(te_bins), TimeEnergyBins) + self.assertAlmostEqual(te_bins.tstart[0], -403.381, places=3) + self.assertAlmostEqual(te_bins.tstop[-1], 83885.53, places=2) + self.assertEqual(len(te_bins.counts), 73620) + self.assertEqual(te_bins.energy_range[0], 8.0) + self.assertEqual(te_bins.energy_range[1], 40.0) + + def test_phaii(self): + pha = self.lc_file.phaii('B', 2) + self.assertEqual(type(pha), FregatePhaii) + self.assertEqual(pha.ebounds.num_intervals, 1) + self.assertEqual(pha.ebounds.range[0], 32.0) + self.assertEqual(pha.ebounds.range[1], 400.0) + self.assertAlmostEqual(pha.time_range[0], -403.381, places=3) + self.assertAlmostEqual(pha.time_range[1], 83885.53, places=2) + self.assertAlmostEqual(pha.trigtime, 706916972.2000, places=4) + self.assertEqual(type(pha.gti), Gti) + self.assertEqual(pha.gti.num_intervals, 22) + self.assertAlmostEqual(pha.gti.range[0], -395.517, places=3) + self.assertAlmostEqual(pha.gti.range[1], 83884.219, places=3) + + def test_gti(self): + gti = self.lc_file.gti + self.assertEqual(type(gti), Gti) + self.assertEqual(gti.num_intervals, 22) + self.assertAlmostEqual(gti.range[0], -395.517, places=3) + self.assertAlmostEqual(gti.range[1], 83884.219, places=3) + + +if __name__ == '__main__': + unittest.main()