{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Add a FITS header to a spectrum file" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/kelle/miniforge3/envs/template-dev/lib/python3.13/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).\n", " warnings.warn(\n" ] } ], "source": [ "import sys\n", "\n", "import astropy.units as u\n", "import numpy as np\n", "\n", "sys.path.append('..')\n", "from astrodb_utils.fits import add_missing_keywords, add_observation_date, add_wavelength_keywords, check_header\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Make a new header" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use the astrodb_utils function `add_missing_keywords` to make a header object called `header` with the needed keywords set to None:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "COPY AND PASTE THE FOLLOWING COMMANDS INTO YOUR SCRIPT\n", "Replace with the appropriate value for your dataset\n", "If you're not sure of the correct value, use None\n", "If you started with a header object not called `header`, replace 'header' with the name of your header object\n", "Use the `astrodb_utils.fits.add_wavelength_keywords` function to add the SPEC_VAL, SPEC_BW, and SPECBAND keywords\n", "\n", "\n", "header.set('OBJECT', \"\")\n", "header.set('RA_TARG', \"\")\n", "header.set('DEC_TARG', \"\")\n", "header.set('DATE-OBS', \"\")\n", "header.set('INSTRUME', \"\")\n", "header.set('TELESCOP', \"\")\n", "header.set('TELAPSE', \"\")\n", "header.set('APERTURE', \"\")\n", "header.set('AUTHOR', \"\")\n", "header.set('TITLE', \"\")\n", "header.set('VOREF', \"\")\n", "header.set('VOPUB', \"\")\n", "header.set('CONTRIB1', \"\")\n", "header.set('SPEC_VAL', \"\")\n", "header.set('SPEC_BW', \"\")\n", "header.set('SPECBAND', \"\")\n" ] } ], "source": [ "header = add_missing_keywords()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Inspect the new header. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The header created with `add_missing_keywords` has several keywords but they are all set to `None`" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "OBJECT = / Name of observed object \n", "RA_TARG = / [deg] target position \n", "DEC_TARG= / [deg] target position \n", "DATE-OBS= / Date of observation \n", "INSTRUME= / Instrument name \n", "TELESCOP= / Telescope name \n", "TELAPSE = / [s] Total elapsed time (s) \n", "APERTURE= / [arcsec] slit width \n", "AUTHOR = / Authors of original dataset \n", "TITLE = / Dataset title \n", "VOREF = / URL, DOI, or bibcode of original publication \n", "VOPUB = / Publisher \n", "CONTRIB1= / Contributor who generated this header \n", "SPEC_VAL= / [angstrom] Characteristic spectral coordinate \n", "SPEC_BW = / [angstrom] width of spectrum \n", "SPECBAND= / SED.bandpass " ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "header " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Add the wavelength keywords" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use astrodb_utils `add_wavelength_keywords` function to generate and add the wavelength header keywords using the wavelength Quantity array." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "OBJECT = / Name of observed object \n", "RA_TARG = / [deg] target position \n", "DEC_TARG= / [deg] target position \n", "DATE-OBS= / Date of observation \n", "INSTRUME= / Instrument name \n", "TELESCOP= / Telescope name \n", "TELAPSE = / [s] Total elapsed time (s) \n", "APERTURE= / [arcsec] slit width \n", "AUTHOR = / Authors of original dataset \n", "TITLE = / Dataset title \n", "VOREF = / URL, DOI, or bibcode of original publication \n", "VOPUB = / Publisher \n", "CONTRIB1= / Contributor who generated this header \n", "SPEC_VAL= 5199.5 / [Angstrom] Characteristic spec coord \n", "SPEC_BW = 199.0 / [Angstrom] Width of spectrum \n", "SPECBAND= 'em.opt.V' / SED.bandpass \n", "TDMIN1 = 5100.0 / [Angstrom] Starting wavelength \n", "TDMAX1 = 5299.0 / [Angstrom] Ending wavelength \n", "HISTORY Wavelength keywords added by astrodb_utils.fits.add_wavelength_keywords " ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wavelength = np.arange(5100, 5300)*u.AA\n", "add_wavelength_keywords(header, wavelength)\n", "header # Notice the new keywords and values added to the header" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Add the observation date" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use the astrodb_utils function `add_observation_date` to add the observation date to the header." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Date of observation: Jan 01, 2021\n", "DATE-OBS set to : 2021-01-01.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/b3/lj1wwttj1wn62jczjjrcp8h80000gn/T/ipykernel_29950/383763279.py:1: DeprecationWarning: Parsing dates involving a day of month without a year specified is ambiguious\n", "and fails to parse leap day. The default behavior will change in Python 3.15\n", "to either always raise an exception or to use a different default year (TBD).\n", "To avoid trouble, add a specific year to the input & format.\n", "See https://github.com/python/cpython/issues/70647.\n", " add_observation_date(header, '1/1/21')\n" ] } ], "source": [ "add_observation_date(header, '1/1/21')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Check for any keywords that are still missing." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Run `add_missing_keywords`, this time with `header` as input, to see what keywords are still missing." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "COPY AND PASTE THE FOLLOWING COMMANDS INTO YOUR SCRIPT\n", "Replace with the appropriate value for your dataset\n", "If you're not sure of the correct value, use None\n", "If you started with a header object not called `header`, replace 'header' with the name of your header object\n", "Use the `astrodb_utils.fits.add_wavelength_keywords` function to add the SPEC_VAL, SPEC_BW, and SPECBAND keywords\n", "\n", "\n", "header.set('OBJECT', \"\")\n", "header.set('RA_TARG', \"\")\n", "header.set('DEC_TARG', \"\")\n", "header.set('INSTRUME', \"\")\n", "header.set('TELESCOP', \"\")\n", "header.set('TELAPSE', \"\")\n", "header.set('APERTURE', \"\")\n", "header.set('AUTHOR', \"\")\n", "header.set('TITLE', \"\")\n", "header.set('VOREF', \"\")\n", "header.set('VOPUB', \"\")\n", "header.set('CONTRIB1', \"\")\n" ] }, { "data": { "text/plain": [ "OBJECT = / Name of observed object \n", "RA_TARG = / [deg] target position \n", "DEC_TARG= / [deg] target position \n", "DATE-OBS= '2021-01-01' / date of the observation \n", "INSTRUME= / Instrument name \n", "TELESCOP= / Telescope name \n", "TELAPSE = / [s] Total elapsed time (s) \n", "APERTURE= / [arcsec] slit width \n", "AUTHOR = / Authors of original dataset \n", "TITLE = / Dataset title \n", "VOREF = / URL, DOI, or bibcode of original publication \n", "VOPUB = / Publisher \n", "CONTRIB1= / Contributor who generated this header \n", "SPEC_VAL= 5199.5 / [Angstrom] Characteristic spec coord \n", "SPEC_BW = 199.0 / [Angstrom] Width of spectrum \n", "SPECBAND= 'em.opt.V' / SED.bandpass \n", "TDMIN1 = 5100.0 / [Angstrom] Starting wavelength \n", "TDMAX1 = 5299.0 / [Angstrom] Ending wavelength \n", "HISTORY Wavelength keywords added by astrodb_utils.fits.add_wavelength_keywords " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "add_missing_keywords(header=header)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Set the remaining keywords by hand" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set any remaining keywords by hand using `header.set`. If the keyword is not known, assign `None`. The below values are just made up and not real." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "header.set('OBJECT', \"SIMP J013656.5+093347.3\")\n", "header.set('RA_TARG', 24.2356689249292 )\n", "header.set('DEC_TARG', 9.5631422127692)\n", "header.set('INSTRUME', \"NIRSPEC\")\n", "header.set('TELESCOP', \"JWST\")\n", "header.set('TELAPSE', None)\n", "header.set('APERTURE', None)\n", "header.set('AUTHOR', \"McCarthy et al.\")\n", "header.set('TITLE', \"An amazing paper\")\n", "header.set('VOREF', \"10.3847/1538-3881/aa9d8b\")\n", "header.set('VOPUB', \"SIMPLE Archive https://simple-bd-archive.org/\")\n", "header.set('CONTRIB1', \"Kelle Cruz\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Run `check_header`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use astrodb_utils `check_header` function to double check everything is as you expect it to be. If all mandatory keywords are set, this function will return `True`." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The following keywords are not set in the header:\n", "TELAPSE : [s] Total elapsed time (s)\n", "APERTURE : [arcsec] slit width\n", "coordinates converted to sexagesimal: 01h36m56.56054198s +09d33m47.31196597s\n", "SIMBAD results for object name SIMP J013656.5+093347.3: main_id ra ... matched_id \n", " deg ... \n", "----------------------- ----------------- ... -----------------------\n", "SIMP J013656.5+093347.3 24.23566892492917 ... SIMP J013656.5+093347.3\n", "coordinates converted to sexagesimal: 01h36m56.56054198s +09d33m47.31196597s\n", "Object name SIMP J013656.5+093347.3 found in SIMBAD\n", " main_id ra ... matched_id \n", " deg ... \n", "----------------------- ----------------- ... -----------------------\n", "SIMP J013656.5+093347.3 24.23566892492917 ... SIMP J013656.5+093347.3\n", "make sure SIMBAD coords match header coords\n", "DATE-OBS set to : 2021-01-01.\n", "Date of observation: Jan 01, 2021\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/b3/lj1wwttj1wn62jczjjrcp8h80000gn/T/ipykernel_29950/2868379340.py:1: DeprecationWarning: Parsing dates involving a day of month without a year specified is ambiguious\n", "and fails to parse leap day. The default behavior will change in Python 3.15\n", "to either always raise an exception or to use a different default year (TBD).\n", "To avoid trouble, add a specific year to the input & format.\n", "See https://github.com/python/cpython/issues/70647.\n", " check_header(header)\n" ] }, { "data": { "text/plain": [ "True" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "check_header(header)" ] } ], "metadata": { "kernelspec": { "display_name": "template-dev", "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.13.1" } }, "nbformat": 4, "nbformat_minor": 2 }