{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "642ac1b3",
   "metadata": {},
   "source": [
    "# Using temperature_from_filter_ratio to analyze XRT data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22b53fce",
   "metadata": {},
   "source": [
    "This example demonstrates how to use `temperature_from_filter_ratio` to calculate the temperature and emission measure in an image using the filter ratio method."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5f04496",
   "metadata": {},
   "source": [
    "First we need to import `temperature_from_filter_ratio`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58758bf1",
   "metadata": {},
   "outputs": [],
   "source": [
    "from xrtpy.response.temperature_from_filter_ratio import temperature_from_filter_ratio"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8aee2bae",
   "metadata": {},
   "source": [
    "As an example we will use the test data included in XRTpy, though data with the right characteristics in the XRT archive could also be used. It's necessary to use two images that are the same size and different filters. To get good results the images should have been taken close in time as well, ideally adjacent in time. Note that not all filter ratios produce good results. \n",
    "\n",
    "This data was generated using the IDL routine xrt_prep.pro from SolarSoft and is unnormalized. Data in the Level 1 archive are normalized, which is also okay to use, though the IDL routine `xrt_teem.pro` did not allow that. For normalized data the image data is multiplied by the exposure time before analysis. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b0dbae75",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sunpy.map\n",
    "\n",
    "from pathlib import Path\n",
    "from sunpy.net import attrs as a\n",
    "from sunpy.net import Fido"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "da83268f",
   "metadata": {},
   "outputs": [],
   "source": [
    "result = Fido.search(\n",
    "    a.Time(\"2011-01-28 01:31:55\", \"2011-01-28 01:32:05\"), a.Instrument(\"xrt\")\n",
    ")\n",
    "\n",
    "data_files = Fido.fetch(result, progress=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "681f4be1",
   "metadata": {},
   "outputs": [],
   "source": [
    "file1 = data_files[1]\n",
    "file2 = data_files[0]\n",
    "print(\"Files used:\\n\", file1, \"\\n\", file2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35dd0c83",
   "metadata": {},
   "source": [
    "[Sunpy maps]:https://docs.sunpy.org/en/stable/code_ref/map.html\n",
    "\n",
    "`temperature_from_filter_ratio` uses [Sunpy maps] as input. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "48ac4220",
   "metadata": {},
   "outputs": [],
   "source": [
    "map1 = sunpy.map.Map(file1)\n",
    "map2 = sunpy.map.Map(file2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "20f21153",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\n",
    "    map1.fits_header[\"TELESCOP\"],\n",
    "    map1.fits_header[\"INSTRUME\"],\n",
    ")\n",
    "print(\n",
    "    \"\\n File 1 used:\\n\",\n",
    "    file1,\n",
    "    \"\\n Observation date:\",\n",
    "    map1.fits_header[\"DATE_OBS\"],\n",
    "    map1.fits_header[\"TIMESYS\"],\n",
    "    \"\\n Filter Wheel 1:\",\n",
    "    map1.fits_header[\"EC_FW1_\"],\n",
    "    map1.fits_header[\"EC_FW1\"],\n",
    "    \"\\n Filter Wheel 2:\",\n",
    "    map1.fits_header[\"EC_FW2_\"],\n",
    "    map1.fits_header[\"EC_FW2\"],\n",
    "    \"\\n Dimension:\",\n",
    "    map1.fits_header[\"NAXIS1\"],\n",
    "    map1.fits_header[\"NAXIS1\"],\n",
    ")\n",
    "\n",
    "print(\n",
    "    \"\\nFile 2 used:\\n\",\n",
    "    file2,\n",
    "    \"\\n Observation date:\",\n",
    "    map2.fits_header[\"DATE_OBS\"],\n",
    "    map2.fits_header[\"TIMESYS\"],\n",
    "    \"\\n Filter Wheel 1:\",\n",
    "    map2.fits_header[\"EC_FW1_\"],\n",
    "    map2.fits_header[\"EC_FW1\"],\n",
    "    \"\\n Filter Wheel 2:\",\n",
    "    map2.fits_header[\"EC_FW2_\"],\n",
    "    map2.fits_header[\"EC_FW2\"],\n",
    "    \"\\n Dimension:\",\n",
    "    map2.fits_header[\"NAXIS1\"],\n",
    "    map2.fits_header[\"NAXIS1\"],\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "905f4e11",
   "metadata": {},
   "source": [
    "The `temperature_from_filter_ratio` function has several options, mirroring the IDL routine xrt_teem.pro in SolarSoft in most respects. A simple call with no extra parameters calculates the temperature and (volume) emission measure for the two images without any binning or masking of the data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ddc9862b",
   "metadata": {},
   "outputs": [],
   "source": [
    "T_EM = temperature_from_filter_ratio(map1, map2)\n",
    "T_e = T_EM.Tmap"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0ef85f3",
   "metadata": {},
   "source": [
    "The output of `temperature_from_filter_ratio` is a namedtuple of SunPy maps with attributes `Tmap`, `EMmap`, `Terrmap`, and `EMerrmap`. As with the SolarSoft IDL routine xrt_teem.pro, the output images are logs of the quantities. `Tmap.data` is the electron temperature, `EMmap.data` is the volume emission measure, `Terrmap.data` is a measure of the uncertainties in the temperature determined for each pixel and `EMerrmap.data` is the same for the emission measure. Each map has data and associated metadata. To examine the results one can use `matplotlib` and `sunpy`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3ae1f53b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "from sunpy.coordinates.sun import angular_radius, B0\n",
    "from sunpy.map import Map\n",
    "\n",
    "# To avoid error messages from sunpy we add metadata to the header:\n",
    "rsun_ref = 6.95700e08\n",
    "hdr1 = map1.meta\n",
    "rsun_obs = angular_radius(hdr1[\"DATE_OBS\"]).value\n",
    "dsun = rsun_ref / np.sin(rsun_obs * np.pi / 6.48e5)\n",
    "solarb0 = B0(hdr1[\"DATE_OBS\"]).value\n",
    "hdr1[\"DSUN_OBS\"] = dsun\n",
    "hdr1[\"RSUN_REF\"] = rsun_ref\n",
    "hdr1[\"RSUN_OBS\"] = rsun_obs\n",
    "hdr1[\"SOLAR_B0\"] = solarb0\n",
    "\n",
    "fig = plt.figure()\n",
    "# We could create a plot simply by doing T_e.plot(), but here we choose to make a linear plot of T_e\n",
    "m = Map((10.0**T_e.data, T_e.meta))\n",
    "m.plot(title=\"Derived Temperature\", vmin=2.0e6, vmax=1.2e7, cmap=\"turbo\")\n",
    "m.draw_limb()\n",
    "m.draw_grid(linewidth=2)\n",
    "cb = plt.colorbar(label=\"T (K)\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e069966",
   "metadata": {},
   "source": [
    "See the temperature_from_filter_ratio.py script for more information. Among the options are verbose output, binning the data by an integer factor (to increase the signal to noise), specifying a temperature range to examine, providing a mask for excluding regions of the images from the analysis, and setting error thresholds on the temperature and photon noise that differ from the default values."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94df8fee",
   "metadata": {},
   "source": [
    "[Narukage et al. (2014, Solar Phys. 289, 1029)]:https://xrtpy.readthedocs.io/en/stable/bibliography.html\n",
    "[Guidoni et al. (2015, ApJ 800, 54)]:https://xrtpy.readthedocs.io/en/stable/bibliography.html\n",
    "\n",
    "\n",
    "These data were analyzed by [Guidoni et al. (2015, ApJ 800, 54)]. See also [Narukage et al. (2014, Solar Phys. 289, 1029)]. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9fb5dcfa-f5c8-4a80-bf8e-442afe4916b6",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
