{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Non-coronagraphic angular differential imaging"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this tutorial, we will process and analyze an archival [SPHERE/ZIMPOL](https://www.eso.org/sci/facilities/paranal/instruments/sphere/inst.html) dataset of [HD 142527](https://ui.adsabs.harvard.edu/abs/2019A%26A...622A.156C/abstract) that was obtained with the narrowband H$\\alpha$ filter (*N_Ha*) and without coronagraph. A few ZIMPOL specific preprocessing steps were already done so we start the processing of the data with the bad pixel cleaning and image registration. There are pipeline modules available for dual-band simultaneous differential imaging (i.e. [SDIpreparationModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.psfpreparation.SDIpreparationModule) and [SubtractImagesModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.basic.SubtractImagesModule)) but for simplicity we only use the *N_Ha* data in this tutorial in combination with angular differential imaging."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Getting started"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's start by importing the required Python modules. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import configparser\n",
    "import tarfile\n",
    "import urllib.request\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from matplotlib.colors import LogNorm\n",
    "from matplotlib.patches import Circle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And also the pipeline and required modules of PynPoint."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pynpoint import Pypeline, FitsReadingModule, ParangReadingModule, \\\n",
    "                     StarExtractionModule, BadPixelSigmaFilterModule, \\\n",
    "                     StarAlignmentModule, FitCenterModule, ShiftImagesModule, \\\n",
    "                     PSFpreparationModule, PcaPsfSubtractionModule, \\\n",
    "                     FalsePositiveModule, SimplexMinimizationModule, \\\n",
    "                     FakePlanetModule, ContrastCurveModule, \\\n",
    "                     FitsWritingModule, TextWritingModule"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we will download a tarball with the preprocessed images and the parallactic angles."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('hd142527_zimpol_h-alpha.tgz', <http.client.HTTPMessage at 0x1454433d0>)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "urllib.request.urlretrieve('https://home.strw.leidenuniv.nl/~stolker/pynpoint/hd142527_zimpol_h-alpha.tgz',\n",
    "                           'hd142527_zimpol_h-alpha.tgz')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Will unpack the compressed archive file in a folder called *input*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "tar = tarfile.open('hd142527_zimpol_h-alpha.tgz')\n",
    "tar.extractall(path='input')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating the configuration file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "PynPoint requires a configuration file with the global settings and the FITS header keywords that have to be imported. The text file should be named `PynPoint_config.ini` (see [documentation](https://pynpoint.readthedocs.io/en/latest/configuration.html) for several instrument specific examples) and located in the working place of the pipeline.\n",
    "\n",
    "In this case, we don't need any of the header data but we set the pixel scale to 3.6 mas pixel$^{-1}$ with the `PIXSCALE` keyword. We also set the `MEMORY` keyword to `None` such that that all images of a dataset are loaded at once in the RAM when the data is processed by a certain pipeline module. The number of processes that is used by pipeline modules that support multiprocessing (see [overview of pipeline modules](https://pynpoint.readthedocs.io/en/latest/overview.html)) is set with the `CPU` keyword."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "config = configparser.ConfigParser()\n",
    "config.add_section('header')\n",
    "config.add_section('settings')\n",
    "config['settings']['PIXSCALE'] = '0.0036'\n",
    "config['settings']['MEMORY'] = 'None'\n",
    "config['settings']['CPU'] = '1'\n",
    "\n",
    "with open('PynPoint_config.ini', 'w') as configfile:\n",
    "    config.write(configfile)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initiating the Pypeline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can now initiate the `Pypeline` by setting the working, input, and output folders. The configuration file will be read and the HDF5 database is created in the working place since it does not yet exist."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "===============\n",
      "PynPoint v0.9.0\n",
      "===============\n",
      "\n",
      "Working place: ./\n",
      "Input place: input/\n",
      "Output place: ./\n",
      "\n",
      "Database: ./PynPoint_database.hdf5\n",
      "Configuration: ./PynPoint_config.ini\n",
      "\n",
      "Number of CPUs: 1\n",
      "Number of threads: not set\n"
     ]
    }
   ],
   "source": [
    "pipeline = Pypeline(working_place_in='./',\n",
    "                    input_place_in='input/',\n",
    "                    output_place_in='./')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Some routines by libraries such as `numpy` and `scipy` use multithreading. The number of threads can be set beforehand from the command line with the `OMP_NUM_THREADS` environment variable (e.g. `export OMP_NUM_THREADS=4`). This is in particular important if a pipeline module also uses multiprocessing."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Importing the images and parallactic angles"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will now import the images from the FITS files into the PynPoint database. This is done by first adding an instance of the [FitsReadingModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.readwrite.html#pynpoint.readwrite.fitsreading.FitsReadingModule) to the `Pypeline` with the `add_module` method and then running the module with the `run_module` method. The data is stored in the database with the name of the `image_tag` argument."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-----------------\n",
      "FitsReadingModule\n",
      "-----------------\n",
      "\n",
      "Module name: read\n",
      "Reading FITS files... [DONE]                      \n",
      "Output ports: zimpol (70, 1024, 1024), fits_header/cal_OBS091_0235_cam2.fits (868,), fits_header/cal_OBS091_0237_cam2.fits (868,), fits_header/cal_OBS091_0239_cam2.fits (868,), fits_header/cal_OBS091_0241_cam2.fits (868,), fits_header/cal_OBS091_0243_cam2.fits (868,), fits_header/cal_OBS091_0245_cam2.fits (868,), fits_header/cal_OBS091_0247_cam2.fits (868,)\n"
     ]
    }
   ],
   "source": [
    "module = FitsReadingModule(name_in='read',\n",
    "                           input_dir=None,\n",
    "                           image_tag='zimpol',\n",
    "                           overwrite=True,\n",
    "                           check=False,\n",
    "                           filenames=None,\n",
    "                           ifs_data=False)\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('read')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's check the shape of the imported dataset. There are 70 images of 1024 by 1024 pixels."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70, 1024, 1024)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pipeline.get_shape('zimpol')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will also import the parallactic angles from a plain text file (a FITS file would also work) by using the [ParangReadingModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.readwrite.html#pynpoint.readwrite.attr_reading.ParangReadingModule). The angles will be stored as the `PARANG` attribute to the dataset that was previously imported and has the database tag *zimpol*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-------------------\n",
      "ParangReadingModule\n",
      "-------------------\n",
      "\n",
      "Module name: parang\n",
      "Reading parallactic angles... [DONE]\n",
      "Number of angles: 70\n",
      "Rotation range: -14.31 - 34.36 deg\n",
      "Output port: zimpol (70, 1024, 1024)\n"
     ]
    }
   ],
   "source": [
    "module = ParangReadingModule(name_in='parang',\n",
    "                             data_tag='zimpol',\n",
    "                             file_name='parang.dat',\n",
    "                             input_dir=None,\n",
    "                             overwrite=True)\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('parang')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The attributes can be read from the database with the [get_attribute](https://pynpoint.readthedocs.io/en/latest/pynpoint.core.html?highlight=get_data#pynpoint.core.pypeline.Pypeline.get_attribute) method of the `Pypeline`. Let's have a look at the values of `PARANG`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-14.3082 , -13.9496 , -13.5902 , -13.23   , -12.8691 , -12.5074 ,\n",
       "       -12.145  , -11.782  , -11.4182 , -11.0538 ,  -6.43366,  -6.0622 ,\n",
       "        -5.69037,  -5.3182 ,  -4.9457 ,  -4.57291,  -4.19983,  -3.8265 ,\n",
       "        -3.45294,  -3.07917,   1.61837,   1.99275,   2.36701,   2.74112,\n",
       "         3.11507,   3.48882,   3.86237,   4.23567,   4.60872,   4.98149,\n",
       "         9.6373 ,  10.0041 ,  10.3703 ,  10.736  ,  11.101  ,  11.4653 ,\n",
       "        11.829  ,  12.192  ,  12.5543 ,  12.9158 ,  17.3717 ,  17.7218 ,\n",
       "        18.0711 ,  18.4193 ,  18.7666 ,  19.1129 ,  19.4581 ,  19.8024 ,\n",
       "        20.1456 ,  20.4878 ,  24.9167 ,  25.243  ,  25.568  ,  25.8919 ,\n",
       "        26.2145 ,  26.536  ,  26.8563 ,  27.1753 ,  27.4931 ,  27.8097 ,\n",
       "        31.7057 ,  32.0052 ,  32.3035 ,  32.6005 ,  32.8962 ,  33.1906 ,\n",
       "        33.4838 ,  33.7757 ,  34.0663 ,  34.3556 ])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pipeline.get_attribute('zimpol', 'PARANG', static=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Bad pixel correction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first processing module that we will use is the [BadPixelSigmaFilterModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.badpixel.BadPixelSigmaFilterModule) to correct bad pixels with a sigma filter. We replace outliers that deviate by more than 3$\\sigma$ from their neighboring pixels and iterate three times. \n",
    "\n",
    "The input port of `image_in_tag` points to the dataset that was imported by the `FitsReadingModule` and the output port of `image_out_tag` stores the processed / cleaned dataset in the database."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-------------------------\n",
      "BadPixelSigmaFilterModule\n",
      "-------------------------\n",
      "\n",
      "Module name: badpixel\n",
      "Input port: zimpol (70, 1024, 1024)\n",
      "Bad pixel sigma filter... [DONE]                      \n",
      "Output port: bad (70, 1024, 1024)\n"
     ]
    }
   ],
   "source": [
    "module = BadPixelSigmaFilterModule(name_in='badpixel',\n",
    "                                   image_in_tag='zimpol',\n",
    "                                   image_out_tag='bad',\n",
    "                                   map_out_tag=None,\n",
    "                                   box=9,\n",
    "                                   sigma=3.,\n",
    "                                   iterate=3)\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('badpixel')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Image centering"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we will crop the image around the brightest pixel at the position of the star with the [StarExtractionModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.extract.StarExtractionModule)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "--------------------\n",
      "StarExtractionModule\n",
      "--------------------\n",
      "\n",
      "Module name: extract\n",
      "Input port: bad (70, 1024, 1024)\n",
      "Extracting stellar position... [DONE]                      \n",
      "Output port: crop (70, 57, 57)\n"
     ]
    }
   ],
   "source": [
    "module = StarExtractionModule(name_in='extract',\n",
    "                              image_in_tag='bad',\n",
    "                              image_out_tag='crop',\n",
    "                              index_out_tag=None,\n",
    "                              image_size=0.2,\n",
    "                              fwhm_star=0.03,\n",
    "                              position=(476, 436, 0.1))\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('extract')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's have a look at the first image from the processed data that is now centered with pixel precision. The data van be read from the database by using the [get_data](https://pynpoint.readthedocs.io/en/latest/pynpoint.core.html?highlight=get_data#pynpoint.core.pypeline.Pypeline.get_data) method of the `Pypeline`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x145d1c690>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "data = pipeline.get_data('crop')\n",
    "plt.imshow(data[0, ], origin='lower')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After the approximate centering, we apply a relative alignment of the images with the [StarAlignmentModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.centering.StarAlignmentModule) by cross-correlating each images with 10 randomly selected images from the dataset. Each image is then shifted to the average offset from the cross-correlation with the 10 images."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-------------------\n",
      "StarAlignmentModule\n",
      "-------------------\n",
      "\n",
      "Module name: align\n",
      "Input port: crop (70, 57, 57)\n",
      "Aligning images... [DONE]                      \n",
      "Output port: aligned (70, 57, 57)\n"
     ]
    }
   ],
   "source": [
    "module = StarAlignmentModule(name_in='align',\n",
    "                             image_in_tag='crop',\n",
    "                             ref_image_in_tag=None,\n",
    "                             image_out_tag='aligned',\n",
    "                             interpolation='spline',\n",
    "                             accuracy=10,\n",
    "                             resize=None,\n",
    "                             num_references=10,\n",
    "                             subframe=0.1)\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('align')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As a third centering step, we use the [FitCenterModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.centering.FitCenterModule) to fit the PSF of the mean image with a 2D Moffat function. The best-fit parameters are stored in the database at the argument name of `fit_out_tag`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "---------------\n",
      "FitCenterModule\n",
      "---------------\n",
      "\n",
      "Module name: center\n",
      "Input port: aligned (70, 57, 57)\n",
      "Fitting the stellar PSF... [DONE]\n",
      "Output port: fit (70, 16)\n"
     ]
    }
   ],
   "source": [
    "module = FitCenterModule(name_in='center',\n",
    "                         image_in_tag='aligned',\n",
    "                         fit_out_tag='fit',\n",
    "                         mask_out_tag=None,\n",
    "                         method='mean',\n",
    "                         radius=0.1,\n",
    "                         sign='positive',\n",
    "                         model='moffat',\n",
    "                         filter_size=None,\n",
    "                         guess=(0., 0., 10., 10., 10000., 0., 0., 1.))\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('center')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The processed images from the `StarAlignmentModule` and the best-fit parameters from the `FitCenterModule` are now used as input for [ShiftImagesModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.centering.ShiftImagesModule). This module shifts all images by the (constant) offset such that the peak of the Moffat function is located in the center of the image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-----------------\n",
      "ShiftImagesModule\n",
      "-----------------\n",
      "\n",
      "Module name: shift\n",
      "Input ports: aligned (70, 57, 57), fit (70, 16)\n",
      "Shifting the images... [DONE]                      \n",
      "Output port: centered (70, 57, 57)\n"
     ]
    }
   ],
   "source": [
    "module = ShiftImagesModule(name_in='shift',\n",
    "                           image_in_tag='aligned',\n",
    "                           image_out_tag='centered',\n",
    "                           shift_xy='fit',\n",
    "                           interpolation='spline')\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('shift')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's have a look at the central part of the first image. The brightest pixel of the PSF is indeed in the center of the image as expected."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(17.0, 40.0)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "data = pipeline.get_data('centered')\n",
    "plt.imshow(data[0, ], origin='lower')\n",
    "plt.xlim(17, 40)\n",
    "plt.ylim(17, 40)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Masking the images"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before running the PSF subtraction, we use the [PSFpreparationModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.psfpreparation.PSFpreparationModule) to mask the central part of the PSF and we also create a outer mask with a diameter equal to the field of view of the image. The latter is achieved by simply setting the argument of `edge_size` to a value that is larger than the field of view."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "--------------------\n",
      "PSFpreparationModule\n",
      "--------------------\n",
      "\n",
      "Module name: prep1\n",
      "Input port: centered (70, 57, 57)\n",
      "Preparing images for PSF subtraction... [DONE]                      \n",
      "Output port: prep (70, 57, 57)\n"
     ]
    }
   ],
   "source": [
    "module = PSFpreparationModule(name_in='prep1',\n",
    "                              image_in_tag='centered',\n",
    "                              image_out_tag='prep',\n",
    "                              mask_out_tag=None,\n",
    "                              norm=False,\n",
    "                              cent_size=0.02,\n",
    "                              edge_size=0.2)\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('prep1')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's have a look at the first image and show it on a logarithmic color scale."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x145e778d0>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "data = pipeline.get_data('prep')\n",
    "max_flux = np.amax(data[0, ])\n",
    "plt.imshow(data[0, ], origin='lower', norm=LogNorm(vmin=0.01*max_flux, vmax=max_flux))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Later on, we require a PSF template for both the relative calibration and the estimation of detection limits. Therefore, we create another masked dataset from the centered images but this time we only mask pixels beyond 70 mas and do not use a central mask."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "--------------------\n",
      "PSFpreparationModule\n",
      "--------------------\n",
      "\n",
      "Module name: prep2\n",
      "Input port: centered (70, 57, 57)\n",
      "Preparing images for PSF subtraction... [DONE]                      \n",
      "Output port: psf (70, 57, 57)\n"
     ]
    }
   ],
   "source": [
    "module = PSFpreparationModule(name_in='prep2',\n",
    "                              image_in_tag='centered',\n",
    "                              image_out_tag='psf',\n",
    "                              mask_out_tag=None,\n",
    "                              norm=False,\n",
    "                              cent_size=None,\n",
    "                              edge_size=0.07)\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('prep2')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's have a look at the first image from this stack of PSF templates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x145ee56d0>"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "data = pipeline.get_data('psf')\n",
    "max_flux = np.amax(data[0, ])\n",
    "plt.imshow(data[0, ], origin='lower', norm=LogNorm(vmin=0.01*max_flux, vmax=max_flux))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PSF subtraction with PCA"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After masking the images, we will now run the PSF subtraction with an implementation of full-frame PCA. We use the [PcaPsfSubtractionModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.psfsubtraction.PcaPsfSubtractionModule) and set the argument of `pca_numbers` to a range from 1 to 30 principal components. This means that the mean- and median-collapsed residuals that are stored with the output ports to `res_mean_tag` and `res_median_tag` will contain 30 images, so with an increasing number of subtracted principal components. We will also store the PCA basis (i.e. the principal components) and apply an extra rotation of -133 deg such that north will be aligned with the positive *y* axis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-----------------------\n",
      "PcaPsfSubtractionModule\n",
      "-----------------------\n",
      "\n",
      "Module name: pca\n",
      "Input port: prep (70, 57, 57)\n",
      "Input parameters:\n",
      "   - Post-processing type: ADI\n",
      "   - Number of principal components: range(1, 31)\n",
      "   - Subtract mean: True\n",
      "   - Extra rotation (deg): -133.0\n",
      "Constructing PSF model... [DONE]\n",
      "Output ports: pca_mean (30, 57, 57), pca_median (30, 57, 57), pca_basis (30, 57, 57)\n"
     ]
    }
   ],
   "source": [
    "module = PcaPsfSubtractionModule(name_in='pca',\n",
    "                                 images_in_tag='prep',\n",
    "                                 reference_in_tag='prep',\n",
    "                                 res_mean_tag='pca_mean',\n",
    "                                 res_median_tag='pca_median',\n",
    "                                 basis_out_tag='pca_basis',\n",
    "                                 pca_numbers=range(1, 31),\n",
    "                                 extra_rot=-133.,\n",
    "                                 subtract_mean=True,\n",
    "                                 processing_type='ADI')\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('pca')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's have a look and the median-collapsed residuals after subtracting 15 principal components. The H$\\alpha$ emission from the accreting M dwarf companion HD 142527 B is clearly detected east / left of the central star."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x145f55550>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "data = pipeline.get_data('pca_median')\n",
    "plt.imshow(data[14, ], origin='lower')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's also have a look at the PCA basis that was stored at the *pca_basis* tag. Here we plot the second principal component."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x145fba810>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "data = pipeline.get_data('pca_basis')\n",
    "plt.imshow(data[1, ], origin='lower')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Signal-to-noise and false positive fraction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we have the residuals of the PSF subtraction, we can calculate the signal-to-noise ratio (S/N) and false positive fraction (FPF) of the detected signal as function of number of principal components that have been subtracted.\n",
    "\n",
    "To do so, we will first check at which pixel coordinates the aperture should be placed such that it encompasses most of the companion flux while excluding most of the (negative) self-subtraction regions. We will read the median-collapsed residuals with the `get_data` method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = pipeline.get_data('pca_median')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And we use the functionalities of `matplotlib` to overlay an aperture on the residuals after subtracting 15 principal components."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.patches.Circle at 0x145ffd050>"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "ax.imshow(data[14, ], origin='lower')\n",
    "aperture = Circle((11, 26), radius=5, fill=False, ls=':', lw=2., color='white')\n",
    "ax.add_artist(aperture)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we use the [FalsePositiveModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.fluxposition.FalsePositiveModule) to calculate both the S/N and FPF. We set position of the `aperture` to the coordinates that we tested and the radius of the aperture to 5 pixels. For the reference apertures, we will ignore the neighboring apertures to the companion (i.e. `ignore=True`) such that the self-subtraction regions will not bias the noise estimate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-------------------\n",
      "FalsePositiveModule\n",
      "-------------------\n",
      "\n",
      "Module name: snr\n",
      "Input port: pca_median (30, 57, 57)\n",
      "Input parameters:\n",
      "   - Aperture position = (11.0, 26.0)\n",
      "   - Aperture radius (pixels) = 5.00\n",
      "   - Optimize aperture position = False\n",
      "   - Ignore neighboring apertures = True\n",
      "   - Minimization tolerance = 0.01\n",
      "Calculating the S/N and FPF...\n",
      "Image 001/30 -> (x, y) = (11.00, 26.00), S/N = 5.54, FPF = 7.28e-04\n",
      "Image 002/30 -> (x, y) = (11.00, 26.00), S/N = 4.85, FPF = 1.43e-03\n",
      "Image 003/30 -> (x, y) = (11.00, 26.00), S/N = 5.75, FPF = 6.01e-04\n",
      "Image 004/30 -> (x, y) = (11.00, 26.00), S/N = 7.43, FPF = 1.53e-04\n",
      "Image 005/30 -> (x, y) = (11.00, 26.00), S/N = 10.16, FPF = 2.64e-05\n",
      "Image 006/30 -> (x, y) = (11.00, 26.00), S/N = 8.92, FPF = 5.54e-05\n",
      "Image 007/30 -> (x, y) = (11.00, 26.00), S/N = 8.35, FPF = 8.02e-05\n",
      "Image 008/30 -> (x, y) = (11.00, 26.00), S/N = 5.59, FPF = 6.99e-04\n",
      "Image 009/30 -> (x, y) = (11.00, 26.00), S/N = 7.81, FPF = 1.16e-04\n",
      "Image 010/30 -> (x, y) = (11.00, 26.00), S/N = 6.46, FPF = 3.25e-04\n",
      "Image 011/30 -> (x, y) = (11.00, 26.00), S/N = 7.34, FPF = 1.63e-04\n",
      "Image 012/30 -> (x, y) = (11.00, 26.00), S/N = 7.17, FPF = 1.86e-04\n",
      "Image 013/30 -> (x, y) = (11.00, 26.00), S/N = 6.97, FPF = 2.16e-04\n",
      "Image 014/30 -> (x, y) = (11.00, 26.00), S/N = 6.32, FPF = 3.66e-04\n",
      "Image 015/30 -> (x, y) = (11.00, 26.00), S/N = 8.25, FPF = 8.55e-05\n",
      "Image 016/30 -> (x, y) = (11.00, 26.00), S/N = 9.85, FPF = 3.16e-05\n",
      "Image 017/30 -> (x, y) = (11.00, 26.00), S/N = 9.98, FPF = 2.94e-05\n",
      "Image 018/30 -> (x, y) = (11.00, 26.00), S/N = 8.71, FPF = 6.31e-05\n",
      "Image 019/30 -> (x, y) = (11.00, 26.00), S/N = 11.85, FPF = 1.09e-05\n",
      "Image 020/30 -> (x, y) = (11.00, 26.00), S/N = 9.01, FPF = 5.23e-05\n",
      "Image 021/30 -> (x, y) = (11.00, 26.00), S/N = 6.85, FPF = 2.37e-04\n",
      "Image 022/30 -> (x, y) = (11.00, 26.00), S/N = 6.41, FPF = 3.39e-04\n",
      "Image 023/30 -> (x, y) = (11.00, 26.00), S/N = 7.57, FPF = 1.38e-04\n",
      "Image 024/30 -> (x, y) = (11.00, 26.00), S/N = 6.88, FPF = 2.33e-04\n",
      "Image 025/30 -> (x, y) = (11.00, 26.00), S/N = 5.45, FPF = 7.91e-04\n",
      "Image 026/30 -> (x, y) = (11.00, 26.00), S/N = 5.32, FPF = 8.99e-04\n",
      "Image 027/30 -> (x, y) = (11.00, 26.00), S/N = 4.38, FPF = 2.33e-03\n",
      "Image 028/30 -> (x, y) = (11.00, 26.00), S/N = 3.06, FPF = 1.11e-02\n",
      "Image 029/30 -> (x, y) = (11.00, 26.00), S/N = 4.45, FPF = 2.18e-03\n",
      "Image 030/30 -> (x, y) = (11.00, 26.00), S/N = 4.89, FPF = 1.37e-03\n",
      "Output port: snr (30, 6)\n"
     ]
    }
   ],
   "source": [
    "module = FalsePositiveModule(name_in='snr',\n",
    "                             image_in_tag='pca_median',\n",
    "                             snr_out_tag='snr',\n",
    "                             position=(11., 26.),\n",
    "                             aperture=5.*0.0036,\n",
    "                             ignore=True,\n",
    "                             optimize=False)\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('snr')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The results have been stored in the dataset with the tag *snr*. Let's plot the S/N as function of principal components that have been extracted. As expected, for a large number of components the S/N goes towards zero due to increased self-subtraction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Signal-to-noise ratio')"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "data = pipeline.get_data('snr')\n",
    "plt.plot(range(1, 31), data[:, 4], 'o')\n",
    "plt.xlabel('Principal components', fontsize=14)\n",
    "plt.ylabel('Signal-to-noise ratio', fontsize=14)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Relative photometric and astrometric calibration"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With the next analysis, we will measure the relative brightness and position of the companion. We will use the [SimplexMinimizationModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.fluxposition.SimplexMinimizationModule) to minimize the flux within a large aperture at the position of the companion while iterative injecting negative copies of the PSF. This procedure will be repeated for principal components in the range of 1 to 10. We need to specify two database tags as input, namely the stack of centered images and the PSF templates (i.e. the stack of masked images) that will be injected to remove the companion flux. Apart from an approximate position of the companion, the downhill simplex method of the minimization algorithm also requires an estimate (e.g. within ${\\sim} 1$ magnitude from the actual value) of the flux contrast."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-------------------------\n",
      "SimplexMinimizationModule\n",
      "-------------------------\n",
      "\n",
      "Module name: simplex\n",
      "Input ports: centered (70, 57, 57), psf (70, 57, 57)\n",
      "Input parameters:\n",
      "   - Number of principal components = range(1, 11)\n",
      "   - Figure of merit = gaussian\n",
      "   - Residuals type = median\n",
      "   - Absolute tolerance (pixels/mag) = 0.01\n",
      "   - Maximum offset = None\n",
      "   - Guessed position (x, y) = (11.00, 26.00)\n",
      "   - Aperture position (x, y) = (11, 26)\n",
      "   - Aperture radius (pixels) = 10\n",
      "   - Inner mask radius (pixels) = 5\n",
      "   - Outer mask radius (pixels) = 55\n",
      "Image center (y, x) = (28.0, 28.0)\n",
      "Simplex minimization... 1 PC - chi^2 = 3.64e+02 [DONE]\n",
      "Best-fit parameters:\n",
      "   - Position (x, y) = (12.91, 26.00)\n",
      "   - Separation (mas) = 54.81\n",
      "   - Position angle (deg) = 97.56\n",
      "   - Contrast (mag) = 5.69\n",
      "Simplex minimization... 2 PC - chi^2 = 1.87e+02 [DONE]\n",
      "Best-fit parameters:\n",
      "   - Position (x, y) = (13.49, 26.75)\n",
      "   - Separation (mas) = 52.42\n",
      "   - Position angle (deg) = 94.92\n",
      "   - Contrast (mag) = 5.45\n",
      "Simplex minimization... 3 PC - chi^2 = 2.88e+02 [DONE]\n",
      "Best-fit parameters:\n",
      "   - Position (x, y) = (13.31, 26.66)\n",
      "   - Separation (mas) = 53.12\n",
      "   - Position angle (deg) = 95.23\n",
      "   - Contrast (mag) = 5.49\n",
      "Simplex minimization... 4 PC - chi^2 = 4.44e+02 [DONE]\n",
      "Best-fit parameters:\n",
      "   - Position (x, y) = (13.13, 26.27)\n",
      "   - Separation (mas) = 53.89\n",
      "   - Position angle (deg) = 96.62\n",
      "   - Contrast (mag) = 5.55\n",
      "Simplex minimization... 5 PC - chi^2 = 3.00e+02 [DONE]\n",
      "Best-fit parameters:\n",
      "   - Position (x, y) = (12.76, 26.43)\n",
      "   - Separation (mas) = 55.16\n",
      "   - Position angle (deg) = 95.88\n",
      "   - Contrast (mag) = 5.63\n",
      "Simplex minimization... 6 PC - chi^2 = 2.78e+02 [DONE]\n",
      "Best-fit parameters:\n",
      "   - Position (x, y) = (12.60, 26.44)\n",
      "   - Separation (mas) = 55.71\n",
      "   - Position angle (deg) = 95.80\n",
      "   - Contrast (mag) = 5.62\n",
      "Simplex minimization... 7 PC - chi^2 = 3.61e+02 [DONE]\n",
      "Best-fit parameters:\n",
      "   - Position (x, y) = (12.02, 26.26)\n",
      "   - Separation (mas) = 57.87\n",
      "   - Position angle (deg) = 96.22\n",
      "   - Contrast (mag) = 5.82\n",
      "Simplex minimization... 8 PC - chi^2 = 4.30e+02 [DONE]\n",
      "Best-fit parameters:\n",
      "   - Position (x, y) = (12.21, 26.25)\n",
      "   - Separation (mas) = 57.17\n",
      "   - Position angle (deg) = 96.32\n",
      "   - Contrast (mag) = 5.73\n",
      "Simplex minimization... 9 PC - chi^2 = 2.96e+02 [DONE]\n",
      "Best-fit parameters:\n",
      "   - Position (x, y) = (11.33, 26.18)\n",
      "   - Separation (mas) = 60.37\n",
      "   - Position angle (deg) = 96.22\n",
      "   - Contrast (mag) = 5.98\n",
      "Simplex minimization... 10 PC - chi^2 = 2.97e+02 [DONE]\n",
      "Best-fit parameters:\n",
      "   - Position (x, y) = (11.59, 26.26)\n",
      "   - Separation (mas) = 59.42\n",
      "   - Position angle (deg) = 96.07\n",
      "   - Contrast (mag) = 5.82\n",
      "Output ports: simplex001 (89, 57, 57), fluxpos001 (89, 6), simplex002 (70, 57, 57), fluxpos002 (70, 6), simplex003 (75, 57, 57), fluxpos003 (75, 6), simplex004 (73, 57, 57), fluxpos004 (73, 6), simplex005 (63, 57, 57), fluxpos005 (63, 6), simplex006 (79, 57, 57), fluxpos006 (79, 6), simplex007 (71, 57, 57), fluxpos007 (71, 6), simplex008 (66, 57, 57), fluxpos008 (66, 6), simplex009 (60, 57, 57), fluxpos009 (60, 6), simplex010 (78, 57, 57), fluxpos010 (78, 6)\n"
     ]
    }
   ],
   "source": [
    "module = SimplexMinimizationModule(name_in='simplex',\n",
    "                                   image_in_tag='centered',\n",
    "                                   psf_in_tag='psf',\n",
    "                                   res_out_tag='simplex',\n",
    "                                   flux_position_tag='fluxpos',\n",
    "                                   position=(11, 26),\n",
    "                                   magnitude=6.,\n",
    "                                   psf_scaling=-1.,\n",
    "                                   merit='gaussian',\n",
    "                                   aperture=10.*0.0036,\n",
    "                                   sigma=0.,\n",
    "                                   tolerance=0.01,\n",
    "                                   pca_number=range(1, 11),\n",
    "                                   cent_size=0.02,\n",
    "                                   edge_size=0.2,\n",
    "                                   extra_rot=-133.,\n",
    "                                   residuals='median',\n",
    "                                   reference_in_tag=None,\n",
    "                                   offset=None)\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('simplex')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When running the `SimplexMinimizationModule`, we see the $\\chi^2$ value changing until the tolerance threshold has been reached. The best-fit position and contrast is then printed and also stored in the database at the `flux_position_tag`. If the argument of `pca_number` is a list or range (instead of a single value), then the names of the `flux_position_tag` and `res_out_tag` are appended with the number of principal components in 3 digits (e.g. 003 for 3 principal components).\n",
    "\n",
    "The `res_out_tag` contains the PSF subtraction residuals for each iteration so the last image in the dataset shows the best-fit result. Let's have a look at the residuals after subtracting 10 principal components with the best-fit negative PSF injected (i.e. which has fully cancelled the companion flux)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x14615dbd0>"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "data = pipeline.get_data('simplex010')\n",
    "plt.imshow(data[-1, ], origin='lower')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's also plot the measured separation, position angle, and contrast as function of principal components that have been subtracted."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Contrast (mag)')"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure(figsize=(8, 8))\n",
    "ax1 = fig.add_subplot(3, 1, 1)\n",
    "ax2 = fig.add_subplot(3, 1, 2)\n",
    "ax3 = fig.add_subplot(3, 1, 3)\n",
    "\n",
    "for i in range(1, 11):\n",
    "    data = pipeline.get_data(f'fluxpos{i:03d}')\n",
    "    ax1.scatter(i, data[-1, 2], color='black')\n",
    "    ax2.scatter(i, data[-1, 3], color='black')\n",
    "    ax3.scatter(i, data[-1, 4], color='black')\n",
    "\n",
    "ax3.set_xlabel('Principal components', fontsize=14)\n",
    "ax1.set_ylabel('Separation (arcsec)', fontsize=14)\n",
    "ax2.set_ylabel('Position angle (deg)', fontsize=14)\n",
    "ax3.set_ylabel('Contrast (mag)', fontsize=14)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Detection limits"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As a final analysis, we will estimate detection limits from the data. To do so, we will first use the [FakePlanetModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.fluxposition.FakePlanetModule) to remove the flux of the companion from the data since it would otherwise bias the result. We use the PSF template that was stored with the tag *psf* and we adopt the separation and position angle that was determined with the `SimplexMinimizationModule`. We need to apply a correction of -133 degrees which was used previously for `extra_rot`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "----------------\n",
      "FakePlanetModule\n",
      "----------------\n",
      "\n",
      "Module name: fake\n",
      "Input ports: centered (70, 57, 57), psf (70, 57, 57)\n",
      "Input parameters:\n",
      "   - Magnitude = 6.10\n",
      "   - PSF scaling = -1.0\n",
      "   - Separation (arcsec) = 0.06\n",
      "   - Position angle (deg) = 0.06\n",
      "Injecting artificial planets... [DONE]                      \n",
      "Output port: removed (70, 57, 57)\n"
     ]
    }
   ],
   "source": [
    "module = FakePlanetModule(name_in='fake',\n",
    "                          image_in_tag='centered',\n",
    "                          psf_in_tag='psf',\n",
    "                          image_out_tag='removed',\n",
    "                          position=(0.061, 97.3-133.),\n",
    "                          magnitude=6.1,\n",
    "                          psf_scaling=-1.,\n",
    "                          interpolation='spline')\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('fake')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that the data only contains the flux of the central star, we use the [ContrastCurveModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.processing.html#pynpoint.processing.limits.ContrastCurveModule) to calculate the detection limits. We will calculate the brightness limits by setting the false positive fraction (FPF) to $2.87 \\times 10^{-7}$, which corresponds to $5\\sigma$ in the limit of Gaussian noise. At small angular separations, the detection limits are affected by small sample statistics (see [Mawet et al. 2014](https://ui.adsabs.harvard.edu/abs/2014ApJ...792...97M/abstract)) so this FPF would only correspond to a $5\\sigma$ detection at large separation from the star. In this example, we will subtract 10 principal components and use the median-collapsed residuals."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-------------------\n",
      "ContrastCurveModule\n",
      "-------------------\n",
      "\n",
      "Module name: limits\n",
      "Input ports: removed (70, 57, 57), psf (70, 57, 57)\n",
      "                                                      \n",
      "Calculating detection limits... [DONE]\n",
      "Output port: limits (4, 4)\n"
     ]
    }
   ],
   "source": [
    "module = ContrastCurveModule(name_in='limits',\n",
    "                             image_in_tag='removed',\n",
    "                             psf_in_tag='psf',\n",
    "                             contrast_out_tag='limits',\n",
    "                             separation=(0.05, 5., 0.01),\n",
    "                             angle=(0., 360., 60.),\n",
    "                             threshold=('fpf', 2.87e-7),\n",
    "                             psf_scaling=1.,\n",
    "                             aperture=0.02,\n",
    "                             pca_number=10,\n",
    "                             cent_size=0.02,\n",
    "                             edge_size=2.,\n",
    "                             extra_rot=-133.,\n",
    "                             residuals='median',\n",
    "                             snr_inject=100.)\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('limits')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exporting datasets to FITS and plain text formats"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we have finished the data processing and analysis, we will export some of the results from the HDF5 database to other data formats. Since astronomical images are commonly viewed with tools such as [DS9](https://sites.google.com/cfa.harvard.edu/saoimageds9), we will use the [FitsWritingModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.readwrite.html?highlight=fitswr#pynpoint.readwrite.fitswriting.FitsWritingModule) to write the median-collapsed residuals of the PSF subtraction to a FITS file. The database tag is specified as argument of `data_tag` and we will store the FITS file in the default output place of the `Pypeline`. The FITS file contains a 3D dataset of which the first dimension corresponds to an increasing number of subtracted principal components."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-----------------\n",
      "FitsWritingModule\n",
      "-----------------\n",
      "\n",
      "Module name: write1\n",
      "Input port: pca_median (30, 57, 57)\n",
      "Writing FITS file... [DONE]\n"
     ]
    }
   ],
   "source": [
    "module = FitsWritingModule(name_in='write1',\n",
    "                           data_tag='pca_median',\n",
    "                           file_name='pca_median.fits',\n",
    "                           output_dir=None,\n",
    "                           data_range=None,\n",
    "                           overwrite=True,\n",
    "                           subset_size=None)\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('write1')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similarly, we can export 1D and 2D datasets to a plain text file with the [TextWritingModule](https://pynpoint.readthedocs.io/en/latest/pynpoint.readwrite.html#pynpoint.readwrite.textwriting.TextWritingModule). Let's export the detection limits that were estimated with the `ContrastCurveModule`. We specify again the database tag and also add a header as first line in the text file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "-----------------\n",
      "TextWritingModule\n",
      "-----------------\n",
      "\n",
      "Module name: write2\n",
      "Input port: limits (4, 4)\n",
      "Writing text file... [DONE]\n"
     ]
    }
   ],
   "source": [
    "module = TextWritingModule(name_in='write2',\n",
    "                           data_tag='limits',\n",
    "                           file_name='limits.dat',\n",
    "                           output_dir=None,\n",
    "                           header='Separation (arcsec) - Contrast (mag) - Variance (mag) - FPF')\n",
    "\n",
    "pipeline.add_module(module)\n",
    "pipeline.run_module('write2')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
