{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Asteroid Light Curve\n", "\n", "
Owner(s): **Bryce Kalmbach** ([@jbkalmbach](https://github.com/LSSTScienceCollaborations/StackClubCourse/issues/new?body=@jbkalmbach))\n", "
Last Verified to Run: **2021-04-04**\n", "
Verified Stack Release: **v21.0.0**\n", "\n", "This notebook shows \n", "\n", "### Learning Objectives:\n", "\n", "After working through this lesson you should be able to: \n", "1. Load difference images and source catalogs using the Butler.\n", "2. Use an Exposure Object to get a WCS for an image.\n", "3. Use the WCS to find objects in the image based upon their ra, dec.\n", "4. Use Astropy to match an object with known astrometry to the source catalog\n", "4. Use a photoCalib object to get calibrated photometry from detected sources in the catalog.\n", "5. Build a light curve using the DM stack on real data!\n", "\n", "### Logistics\n", "This notebook is intended to be runnable on `lsst-lsp-stable.ncsa.illinois.edu` from a local git clone of https://github.com/LSSTScienceCollaborations/StackClubCourse.\n", "\n", "\n", "#### Further Resources\n", "This notebook uses methods from these other Stack Club notebooks:\n", "\n", "[Low-Surface Brightness Source Detection](https://github.com/LSSTScienceCollaborations/StackClub/blob/master/SourceDetection/LowSurfaceBrightness.ipynb)\n", "\n", "as well as previous notebooks in the Stack Club Course.\n", "\n", "#### Data Credit\n", "The image data in this notebook is DECam data from the HiTS survey processed by Meredith Rawls ([@mrawls](https://github.com/mrawls)) (original dataset location: `/project/mrawls/hits2015/rerun/cw_2020_04`)." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Set-up\n", "\n", "You can find the Stack version that this notebook is running by using `eups list -s` on the terminal command line:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:49.140223Z", "iopub.status.busy": "2021-04-23T20:44:49.136872Z", "iopub.status.idle": "2021-04-23T20:44:51.215017Z", "shell.execute_reply": "2021-04-23T20:44:51.221306Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "nb-kadrlica-r21-0-0\r\n", " 21.0.0+973e4c9e85 \tcurrent v21_0_0 setup\r\n" ] } ], "source": [ "# What version of the Stack am I using?\n", "! echo $HOSTNAME\n", "! eups list lsst_distrib -s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will need the following packages" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:51.239825Z", "iopub.status.busy": "2021-04-23T20:44:51.238354Z", "iopub.status.idle": "2021-04-23T20:44:52.833346Z", "shell.execute_reply": "2021-04-23T20:44:52.831992Z" } }, "outputs": [], "source": [ "import lsst.daf.persistence as dafPersist\n", "import lsst.afw.image as afwImage\n", "\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import lsst.geom\n", "\n", "from astropy.coordinates import SkyCoord\n", "from astropy import units as u\n", "from astropy.time import Time" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:52.841729Z", "iopub.status.busy": "2021-04-23T20:44:52.840192Z", "iopub.status.idle": "2021-04-23T20:44:53.000430Z", "shell.execute_reply": "2021-04-23T20:44:53.001248Z" } }, "outputs": [], "source": [ "# Enable interactive, in-notebook plotting with matplotlib\n", "%matplotlib ipympl\n", "\n", "# Some other options if the above doesn't work\n", "#%matplotlib widget\n", "#%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:53.007665Z", "iopub.status.busy": "2021-04-23T20:44:53.006804Z", "iopub.status.idle": "2021-04-23T20:44:53.123258Z", "shell.execute_reply": "2021-04-23T20:44:53.121980Z" } }, "outputs": [], "source": [ "import lsst.afw.display as afw_display\n", "afw_display.setDefaultBackend('matplotlib')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Look at difference images\n", "\n", "Our first task is (not surprisingly) to point the butler at the location of the repository we want to use." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:53.129893Z", "iopub.status.busy": "2021-04-23T20:44:53.128455Z", "iopub.status.idle": "2021-04-23T20:44:57.188028Z", "shell.execute_reply": "2021-04-23T20:44:57.189109Z" } }, "outputs": [], "source": [ "data_dir = '/project/stack-club/decam_hits_2015_subset/'\n", "butler = dafPersist.Butler(data_dir)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We happen to know _a priori_ that there are difference images in this dataset, but what are the actual datasets called when we access them through the butler? We can remind ourselves with `getDatasetTypes`. " ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:57.224231Z", "iopub.status.busy": "2021-04-23T20:44:57.223055Z", "iopub.status.idle": "2021-04-23T20:44:57.225574Z", "shell.execute_reply": "2021-04-23T20:44:57.226510Z" } }, "outputs": [], "source": [ "data_types = butler.getDatasetTypes()\n", "diff_data_types = [x for x in data_types if x.startswith('deepDiff') ]" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:57.237549Z", "iopub.status.busy": "2021-04-23T20:44:57.236497Z", "iopub.status.idle": "2021-04-23T20:44:57.245474Z", "shell.execute_reply": "2021-04-23T20:44:57.246357Z" } }, "outputs": [ { "data": { "text/plain": [ "['deepDiff_config',\n", " 'deepDiff_config_filename',\n", " 'deepDiff_diaSrc',\n", " 'deepDiff_diaSrc_filename',\n", " 'deepDiff_diaSrc_len',\n", " 'deepDiff_diaSrc_md',\n", " 'deepDiff_diaSrc_schema',\n", " 'deepDiff_diaSrc_schema_filename',\n", " 'deepDiff_diaSrc_schema_len',\n", " 'deepDiff_diaSrc_schema_md',\n", " 'deepDiff_differenceExp',\n", " 'deepDiff_differenceExp_bbox',\n", " 'deepDiff_differenceExp_detector',\n", " 'deepDiff_differenceExp_filename',\n", " 'deepDiff_differenceExp_filter',\n", " 'deepDiff_differenceExp_header_wcs',\n", " 'deepDiff_differenceExp_md',\n", " 'deepDiff_differenceExp_photoCalib',\n", " 'deepDiff_differenceExp_sub',\n", " 'deepDiff_differenceExp_visitInfo',\n", " 'deepDiff_differenceExp_wcs',\n", " 'deepDiff_kernelSrc',\n", " 'deepDiff_kernelSrc_filename',\n", " 'deepDiff_kernelSrc_len',\n", " 'deepDiff_kernelSrc_md',\n", " 'deepDiff_kernelSrc_schema',\n", " 'deepDiff_matchedExp',\n", " 'deepDiff_matchedExp_bbox',\n", " 'deepDiff_matchedExp_detector',\n", " 'deepDiff_matchedExp_filename',\n", " 'deepDiff_matchedExp_filter',\n", " 'deepDiff_matchedExp_header_wcs',\n", " 'deepDiff_matchedExp_md',\n", " 'deepDiff_matchedExp_photoCalib',\n", " 'deepDiff_matchedExp_sub',\n", " 'deepDiff_matchedExp_visitInfo',\n", " 'deepDiff_matchedExp_wcs',\n", " 'deepDiff_metadata',\n", " 'deepDiff_metadata_filename',\n", " 'deepDiff_warpedExp',\n", " 'deepDiff_warpedExp_bbox',\n", " 'deepDiff_warpedExp_detector',\n", " 'deepDiff_warpedExp_filename',\n", " 'deepDiff_warpedExp_filter',\n", " 'deepDiff_warpedExp_header_wcs',\n", " 'deepDiff_warpedExp_md',\n", " 'deepDiff_warpedExp_photoCalib',\n", " 'deepDiff_warpedExp_sub',\n", " 'deepDiff_warpedExp_visitInfo',\n", " 'deepDiff_warpedExp_wcs']" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(np.sort(list(diff_data_types)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also use `queryMetadata` to see what visits are available." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:57.252697Z", "iopub.status.busy": "2021-04-23T20:44:57.251732Z", "iopub.status.idle": "2021-04-23T20:44:57.272659Z", "shell.execute_reply": "2021-04-23T20:44:57.271847Z" } }, "outputs": [ { "data": { "text/plain": [ "[410790,\n", " 410791,\n", " 410792,\n", " 410793,\n", " 410794,\n", " 410795,\n", " 410796,\n", " 410797,\n", " 410798,\n", " 410799]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "butler.queryMetadata('deepDiff_differenceExp', ('visit'), dataId={'filter': 'g'})[:10]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load Images and Source Catalogs\n", "\n", "Now we are ready to load some data." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:57.277859Z", "iopub.status.busy": "2021-04-23T20:44:57.276944Z", "iopub.status.idle": "2021-04-23T20:44:57.280102Z", "shell.execute_reply": "2021-04-23T20:44:57.279306Z" } }, "outputs": [], "source": [ "visit_num = 410929\n", "ccd_num = 9" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First let's load the calexp and get the `maskedImage`." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:57.869420Z", "iopub.status.busy": "2021-04-23T20:44:57.868038Z", "iopub.status.idle": "2021-04-23T20:44:58.033757Z", "shell.execute_reply": "2021-04-23T20:44:58.032391Z" } }, "outputs": [], "source": [ "calexp = butler.get('calexp', {'visit': visit_num, 'ccdnum': ccd_num, 'filter': 'g'})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Two ways to get the `maskedImage` out of the `Exposure` object." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:58.040531Z", "iopub.status.busy": "2021-04-23T20:44:58.038995Z", "iopub.status.idle": "2021-04-23T20:44:58.043112Z", "shell.execute_reply": "2021-04-23T20:44:58.041992Z" } }, "outputs": [], "source": [ "calexp_im = calexp.getMaskedImage()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:58.050778Z", "iopub.status.busy": "2021-04-23T20:44:58.049437Z", "iopub.status.idle": "2021-04-23T20:44:58.052415Z", "shell.execute_reply": "2021-04-23T20:44:58.053497Z" } }, "outputs": [], "source": [ "# Alternate Way\n", "calexp_im = calexp.maskedImage" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get the source catalog (`src`)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:58.155563Z", "iopub.status.busy": "2021-04-23T20:44:58.154061Z", "iopub.status.idle": "2021-04-23T20:44:58.157129Z", "shell.execute_reply": "2021-04-23T20:44:58.158360Z" } }, "outputs": [], "source": [ "calexp_src_cat = butler.get('src', {'visit': visit_num, 'ccdnum': ccd_num, 'filter': 'g'})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get the difference image itself" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:58.991862Z", "iopub.status.busy": "2021-04-23T20:44:58.990454Z", "iopub.status.idle": "2021-04-23T20:44:58.995246Z", "shell.execute_reply": "2021-04-23T20:44:58.996341Z" } }, "outputs": [], "source": [ "diffexp = butler.get('deepDiff_differenceExp', {'visit': visit_num, 'ccdnum': ccd_num, 'filter':'g'})" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:59.029797Z", "iopub.status.busy": "2021-04-23T20:44:59.028349Z", "iopub.status.idle": "2021-04-23T20:44:59.031444Z", "shell.execute_reply": "2021-04-23T20:44:59.032575Z" } }, "outputs": [], "source": [ "diffexp_src_cat = butler.get('deepDiff_diaSrc', {'visit': visit_num, 'ccdnum': ccd_num, 'filter': 'g'})" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:59.039744Z", "iopub.status.busy": "2021-04-23T20:44:59.038384Z", "iopub.status.idle": "2021-04-23T20:44:59.041126Z", "shell.execute_reply": "2021-04-23T20:44:59.042211Z" } }, "outputs": [], "source": [ "diffexp_im = diffexp.getMaskedImage()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Get Visit Info\n", "Since we want to get light curves in the end we'll need to learn how to get the time of the visits. Let's use `getInfo` found in the `Exposure` object." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:59.049064Z", "iopub.status.busy": "2021-04-23T20:44:59.047779Z", "iopub.status.idle": "2021-04-23T20:44:59.050406Z", "shell.execute_reply": "2021-04-23T20:44:59.051399Z" } }, "outputs": [], "source": [ "exp_visit_info = calexp.getInfo().getVisitInfo()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:59.057928Z", "iopub.status.busy": "2021-04-23T20:44:59.056740Z", "iopub.status.idle": "2021-04-23T20:44:59.060920Z", "shell.execute_reply": "2021-04-23T20:44:59.061888Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DateTime(\"2015-02-17T03:51:13.595192500\", TAI)\n" ] } ], "source": [ "visit_date = exp_visit_info.getDate()\n", "print(visit_date)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:59.067861Z", "iopub.status.busy": "2021-04-23T20:44:59.066740Z", "iopub.status.idle": "2021-04-23T20:44:59.070472Z", "shell.execute_reply": "2021-04-23T20:44:59.071400Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2015-02-17 03:51:13.595192\n" ] } ], "source": [ "visit_date_python = exp_visit_info.getDate().toPython()\n", "print(visit_date_python)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:59.078050Z", "iopub.status.busy": "2021-04-23T20:44:59.077014Z", "iopub.status.idle": "2021-04-23T20:44:59.080464Z", "shell.execute_reply": "2021-04-23T20:44:59.081332Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "57070.160574018424\n" ] } ], "source": [ "visit_date_astropy = Time(visit_date_python)\n", "print(visit_date_astropy.mjd)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plot `calexp` and `diffExp` side-by-side" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:44:59.102239Z", "iopub.status.busy": "2021-04-23T20:44:59.095179Z", "iopub.status.idle": "2021-04-23T20:45:01.163098Z", "shell.execute_reply": "2021-04-23T20:45:01.161805Z" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "071bde330e184f28a1dcaf8f44792872", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = plt.figure()#figsize=(16, 14))\n", "display = []\n", "\n", "fig.add_subplot(1,2,1)\n", "display.append(afw_display.Display(frame=fig))\n", "display[0].scale('linear', 'zscale')\n", "display[0].mtv(calexp_im)\n", "\n", "fig.add_subplot(1,2,2)\n", "display.append(afw_display.Display(frame=fig))\n", "display[1].scale('linear', 'zscale')\n", "#display[1].setMaskTransparency(10)\n", "display[1].mtv(diffexp_im)\n", "\n", "plt.tight_layout()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### What's in the mask?\n", "\n", "First, we get the mask plane from the difference image. Then we ask what items it contains, and what colors are used to display them." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:01.169862Z", "iopub.status.busy": "2021-04-23T20:45:01.168544Z", "iopub.status.idle": "2021-04-23T20:45:01.173620Z", "shell.execute_reply": "2021-04-23T20:45:01.172472Z" } }, "outputs": [], "source": [ "mask = diffexp_im.mask" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:01.179645Z", "iopub.status.busy": "2021-04-23T20:45:01.178446Z", "iopub.status.idle": "2021-04-23T20:45:01.184781Z", "shell.execute_reply": "2021-04-23T20:45:01.183730Z" } }, "outputs": [ { "data": { "text/plain": [ "dict_items([('BAD', 0), ('CLIPPED', 10), ('CR', 3), ('DETECTED', 5), ('DETECTED_NEGATIVE', 6), ('EDGE', 4), ('INEXACT_PSF', 11), ('INTRP', 2), ('NOT_DEBLENDED', 12), ('NO_DATA', 8), ('REJECTED', 13), ('SAT', 1), ('SENSOR_EDGE', 14), ('SUSPECT', 7), ('UNMASKEDNAN', 9)])" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mask.getMaskPlaneDict().items()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:01.191089Z", "iopub.status.busy": "2021-04-23T20:45:01.189994Z", "iopub.status.idle": "2021-04-23T20:45:01.194760Z", "shell.execute_reply": "2021-04-23T20:45:01.195674Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "BAD : red\n", "CLIPPED : None\n", "CR : magenta\n", "DETECTED : blue\n", "DETECTED_NEGATIVE : cyan\n", "EDGE : yellow\n", "INEXACT_PSF : None\n", "INTRP : green\n", "NOT_DEBLENDED : None\n", "NO_DATA : orange\n", "REJECTED : None\n", "SAT : green\n", "SENSOR_EDGE : None\n", "SUSPECT : yellow\n", "UNMASKEDNAN : None\n" ] } ], "source": [ "mask = diffexp.getMask()\n", "for mask_name, mask_bit in mask.getMaskPlaneDict().items():\n", " print('{:20}: {}'.format(mask_name, display[1].getMaskPlaneColor(mask_name)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also mouse over the difference image mask and matplotlib will display the mask plane bit." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading and using the Exposure WCS" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using an asteroid finding algorithm called [KBMOD](https://github.com/dirac-institute/kbmod) we found Kuiper Belt Objects in the 2015 HiTS data that we are using here. In this folder, we've provided astrometry for the two objects we found in this field. Let's use `2015 DQ249` as an example and build its light curve.\n", "\n", "The astrometry for these objects is provided in text files easily loaded in a `pandas.DataFrame`." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:01.204412Z", "iopub.status.busy": "2021-04-23T20:45:01.201001Z", "iopub.status.idle": "2021-04-23T20:45:01.206495Z", "shell.execute_reply": "2021-04-23T20:45:01.207353Z" } }, "outputs": [], "source": [ "hits_object_df = pd.read_csv('NotebookData/hits_kbmod_2015_DQ249_coords.dat', delimiter=' ')" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:01.216651Z", "iopub.status.busy": "2021-04-23T20:45:01.215615Z", "iopub.status.idle": "2021-04-23T20:45:01.223527Z", "shell.execute_reply": "2021-04-23T20:45:01.222681Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
visityearmonthdayra_hourra_minra_secdec_degdec_mindec_sec
04109292015217.15939101938.442-55640.41
14109852015217.24529101937.616-55633.08
24110352015217.31416101936.969-55627.42
34110692015217.36113101936.501-55623.76
44112692015218.08845101929.672-55523.12
\n", "
" ], "text/plain": [ " visit year month day ra_hour ra_min ra_sec dec_deg dec_min \\\n", "0 410929 2015 2 17.15939 10 19 38.442 -5 56 \n", "1 410985 2015 2 17.24529 10 19 37.616 -5 56 \n", "2 411035 2015 2 17.31416 10 19 36.969 -5 56 \n", "3 411069 2015 2 17.36113 10 19 36.501 -5 56 \n", "4 411269 2015 2 18.08845 10 19 29.672 -5 55 \n", "\n", " dec_sec \n", "0 40.41 \n", "1 33.08 \n", "2 27.42 \n", "3 23.76 \n", "4 23.12 " ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hits_object_df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's use the information for visit number 410985 and find the asteroid in our difference image." ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:01.228372Z", "iopub.status.busy": "2021-04-23T20:45:01.227425Z", "iopub.status.idle": "2021-04-23T20:45:01.231127Z", "shell.execute_reply": "2021-04-23T20:45:01.230292Z" } }, "outputs": [], "source": [ "hits_visit = hits_object_df.loc[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Load the visit data. From our KBMOD search, I already know it is in CCD #9 so we can start with the data id already complete." ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:01.235789Z", "iopub.status.busy": "2021-04-23T20:45:01.234894Z", "iopub.status.idle": "2021-04-23T20:45:01.238369Z", "shell.execute_reply": "2021-04-23T20:45:01.237581Z" } }, "outputs": [], "source": [ "data_id = {'visit': hits_visit['visit'], 'ccdnum': 9, 'filter':'g'}" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:01.801941Z", "iopub.status.busy": "2021-04-23T20:45:01.242433Z", "iopub.status.idle": "2021-04-23T20:45:01.806216Z", "shell.execute_reply": "2021-04-23T20:45:01.804945Z" } }, "outputs": [], "source": [ "calexp = butler.get('calexp', data_id)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:01.858259Z", "iopub.status.busy": "2021-04-23T20:45:01.855205Z", "iopub.status.idle": "2021-04-23T20:45:01.862443Z", "shell.execute_reply": "2021-04-23T20:45:01.861217Z" } }, "outputs": [], "source": [ "calexp_src_cat = butler.get('src', data_id)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.440836Z", "iopub.status.busy": "2021-04-23T20:45:02.439321Z", "iopub.status.idle": "2021-04-23T20:45:02.446958Z", "shell.execute_reply": "2021-04-23T20:45:02.448011Z" } }, "outputs": [], "source": [ "diffexp = butler.get('deepDiff_differenceExp', data_id)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.482046Z", "iopub.status.busy": "2021-04-23T20:45:02.456235Z", "iopub.status.idle": "2021-04-23T20:45:02.486325Z", "shell.execute_reply": "2021-04-23T20:45:02.485080Z" } }, "outputs": [], "source": [ "diffexp_src_cat = butler.get('deepDiff_diaSrc', data_id)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.537861Z", "iopub.status.busy": "2021-04-23T20:45:02.511428Z", "iopub.status.idle": "2021-04-23T20:45:02.565137Z", "shell.execute_reply": "2021-04-23T20:45:02.563910Z" } }, "outputs": [], "source": [ "diffexp_src_df = diffexp_src_cat.asAstropy().to_pandas()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Brief Aside: There are lots of columns in the source catalog including quality flags. Here we show some potentially useful quality flags." ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.572502Z", "iopub.status.busy": "2021-04-23T20:45:02.571329Z", "iopub.status.idle": "2021-04-23T20:45:02.577265Z", "shell.execute_reply": "2021-04-23T20:45:02.576288Z" } }, "outputs": [ { "data": { "text/plain": [ "['base_PixelFlags_flag',\n", " 'base_PixelFlags_flag_offimage',\n", " 'base_PixelFlags_flag_edge',\n", " 'base_PixelFlags_flag_interpolated',\n", " 'base_PixelFlags_flag_saturated',\n", " 'base_PixelFlags_flag_cr',\n", " 'base_PixelFlags_flag_bad',\n", " 'base_PixelFlags_flag_suspect',\n", " 'base_PixelFlags_flag_interpolatedCenter',\n", " 'base_PixelFlags_flag_saturatedCenter',\n", " 'base_PixelFlags_flag_crCenter',\n", " 'base_PixelFlags_flag_suspectCenter']" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[x for x in diffexp_src_df.columns if x.startswith('base_PixelFlags')]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Find object with WCS\n", "\n", "To find the object we will load the image's WCS and use it to convert the ra, dec to pixel location." ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.583269Z", "iopub.status.busy": "2021-04-23T20:45:02.582186Z", "iopub.status.idle": "2021-04-23T20:45:02.586237Z", "shell.execute_reply": "2021-04-23T20:45:02.585331Z" } }, "outputs": [], "source": [ "wcs = diffexp.getWcs()" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.594013Z", "iopub.status.busy": "2021-04-23T20:45:02.592969Z", "iopub.status.idle": "2021-04-23T20:45:02.598160Z", "shell.execute_reply": "2021-04-23T20:45:02.597305Z" } }, "outputs": [ { "data": { "text/plain": [ "FITS standard SkyWcs:\n", "Sky Origin: (154.787109, -5.951107)\n", "Pixel Origin: (1171.94, 1762.08)\n", "Pixel Scale: 0.262966 arcsec/pixel" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wcs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use astropy SkyCoords to translate ra, dec into radians." ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.622659Z", "iopub.status.busy": "2021-04-23T20:45:02.612527Z", "iopub.status.idle": "2021-04-23T20:45:02.625543Z", "shell.execute_reply": "2021-04-23T20:45:02.624626Z" } }, "outputs": [], "source": [ "obj_pos = SkyCoord('%i %i %f %i %i %f' % (hits_visit['ra_hour'],\n", " hits_visit['ra_min'],\n", " hits_visit['ra_sec'],\n", " hits_visit['dec_deg'],\n", " hits_visit['dec_min'],\n", " hits_visit['dec_sec']),\n", " unit=(u.hourangle, u.degree))" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.631873Z", "iopub.status.busy": "2021-04-23T20:45:02.630960Z", "iopub.status.idle": "2021-04-23T20:45:02.635661Z", "shell.execute_reply": "2021-04-23T20:45:02.634920Z" } }, "outputs": [ { "data": { "text/plain": [ "(154.9067333333333, -5.942522222222222)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "obj_pos.ra.deg, obj_pos.dec.deg" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use `lsst.geom` package to create `SpherePoint` that describes a position on the sky.\n", "\n", "`lsst.geom` also has units that we can provide." ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.640962Z", "iopub.status.busy": "2021-04-23T20:45:02.640101Z", "iopub.status.idle": "2021-04-23T20:45:02.642671Z", "shell.execute_reply": "2021-04-23T20:45:02.643391Z" } }, "outputs": [], "source": [ "obj_pos_lsst = lsst.geom.SpherePoint(obj_pos.ra.deg, obj_pos.dec.deg, lsst.geom.degrees)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we can use `skyToPixel` to convert our ra, dec coordinates to pixel coordinates in the image." ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.648349Z", "iopub.status.busy": "2021-04-23T20:45:02.647544Z", "iopub.status.idle": "2021-04-23T20:45:02.649965Z", "shell.execute_reply": "2021-04-23T20:45:02.650629Z" } }, "outputs": [], "source": [ "x_pix, y_pix = wcs.skyToPixel(obj_pos_lsst)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also double check that our object is on this CCD by using `getDimensions` and comparing to the pixel location the WCS gives us." ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.655377Z", "iopub.status.busy": "2021-04-23T20:45:02.654575Z", "iopub.status.idle": "2021-04-23T20:45:02.657956Z", "shell.execute_reply": "2021-04-23T20:45:02.658591Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1053.1148631559506 3388.9460528498885\n", "(2048, 4096)\n" ] } ], "source": [ "print(x_pix, y_pix)\n", "print(diffexp.getDimensions())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Draw Postage Stamps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Use `Factory` method to create cutouts\n", "\n", "One way to create a postage stamp is using the `Factory` method. To use this we need to create a bounding box with `lsst.geom`. \n", "\n", "The `origin` argument in the call to `Factory` specifies that image pixel origin for our bounding box will be local to the cutout. (For more info on `afwImage.LOCAL` vs `afwImage.PARENT` see [here](https://pipelines.lsst.io/v/d-2018-07-09/modules/lsst.afw.image/indexing-conventions.html).)\n", "\n", "If `deep` is set then the cutout will copy the data rather than using a reference." ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.662998Z", "iopub.status.busy": "2021-04-23T20:45:02.662227Z", "iopub.status.idle": "2021-04-23T20:45:02.664542Z", "shell.execute_reply": "2021-04-23T20:45:02.665183Z" } }, "outputs": [], "source": [ "x_half_width = 40\n", "y_half_width = 40" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.669798Z", "iopub.status.busy": "2021-04-23T20:45:02.669071Z", "iopub.status.idle": "2021-04-23T20:45:02.671264Z", "shell.execute_reply": "2021-04-23T20:45:02.671872Z" } }, "outputs": [], "source": [ "# Define bounding box for cutout\n", "bbox = lsst.geom.Box2I()\n", "bbox.include(lsst.geom.Point2I(x_pix - x_half_width, y_pix - y_half_width))\n", "bbox.include(lsst.geom.Point2I(x_pix + x_half_width, y_pix + y_half_width))" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.676268Z", "iopub.status.busy": "2021-04-23T20:45:02.675541Z", "iopub.status.idle": "2021-04-23T20:45:02.677699Z", "shell.execute_reply": "2021-04-23T20:45:02.678278Z" } }, "outputs": [], "source": [ "# Generate cutouts with Factory\n", "calexp_cutout = calexp.Factory(calexp, bbox, origin=afwImage.LOCAL, deep=False)\n", "diffexp_cutout = diffexp.Factory(diffexp, bbox, origin=afwImage.LOCAL, deep=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is a new and easier way to get a cutout!" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.682936Z", "iopub.status.busy": "2021-04-23T20:45:02.682248Z", "iopub.status.idle": "2021-04-23T20:45:02.684316Z", "shell.execute_reply": "2021-04-23T20:45:02.684896Z" } }, "outputs": [], "source": [ "calexp_cutout = calexp.getCutout(obj_pos_lsst, size=lsst.geom.Extent2I(80, 80))\n", "diffexp_cutout = diffexp.getCutout(obj_pos_lsst, size=lsst.geom.Extent2I(80, 80))" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:02.700178Z", "iopub.status.busy": "2021-04-23T20:45:02.699465Z", "iopub.status.idle": "2021-04-23T20:45:03.920912Z", "shell.execute_reply": "2021-04-23T20:45:03.919577Z" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "813718455d684c6aa61a32edcf2f85c0", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = plt.figure(figsize=(10, 5))\n", "stamp_display = []\n", "\n", "fig.add_subplot(1,2,1)\n", "stamp_display.append(afw_display.Display(frame=fig))\n", "stamp_display[0].scale('linear', 'zscale')\n", "stamp_display[0].mtv(calexp_cutout.maskedImage)\n", "\n", "#stamp_display[0].dot('o', x_pix, y_pix, size=4)\n", "for src in calexp_src_cat:\n", " stamp_display[0].dot('o', src.getX(), src.getY(), ctype='cyan', size=4)\n", "plt.title('Calexp Image and Source Catalog')\n", " \n", "fig.add_subplot(1,2,2)\n", "stamp_display.append(afw_display.Display(frame=fig))\n", "stamp_display[1].scale('linear', 'zscale')\n", "stamp_display[1].mtv(diffexp_cutout.maskedImage)\n", "\n", "#stamp_display[1].dot('o', x_pix, y_pix, size=4)\n", "for src in diffexp_src_cat:\n", " stamp_display[1].dot('o', src.getX(), src.getY(), ctype='cyan', size=4)\n", "plt.title('Diffexp Image and Source Catalog')\n", "\n", "plt.tight_layout()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Exercise 1\n", "\n", "In this folder there is astrometry for another asteroid that was found in the same field on the first night of HiTS observations. Load `hits_kbmod_2014_XW40_coords.dat` into a dataframe and try to recreate the plot above for one of the visits. \n", "\n", "Hint: If you run into an error trying to create a cutout it may be because while the asteroid is in the same field it may not fall on the same CCD. To find the correct CCD use the `wcs.skyToPixel` function and this [map of the DECam focal plane](http://www.ctio.noao.edu/noao/sites/default/files/DECam/DECamOrientation.png)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Get Photometry for the Source" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Source matching with Astropy\n", "\n", "We are going to use Astropy and the `match_to_catalog_sky` method to match our asteroid to the closest source in difference exposure source catalog. We already loaded our asteroid ra, dec into an Astropy `SkyCoord` object above and called it `obj_pos`. A `SkyCoord` object can hold more than one set of coordinates though. So, we will load the coordinates from the source catalog into a `SkyCoord` object called `visit_coords`." ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:03.928593Z", "iopub.status.busy": "2021-04-23T20:45:03.927164Z", "iopub.status.idle": "2021-04-23T20:45:03.933460Z", "shell.execute_reply": "2021-04-23T20:45:03.929846Z" } }, "outputs": [], "source": [ "visit_coords = SkyCoord(diffexp_src_cat['coord_ra']*u.rad, diffexp_src_cat['coord_dec']*u.rad)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:03.939487Z", "iopub.status.busy": "2021-04-23T20:45:03.938284Z", "iopub.status.idle": "2021-04-23T20:45:03.945782Z", "shell.execute_reply": "2021-04-23T20:45:03.942408Z" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# obj_pos is only one row: The location of our asteroid in this visit.\n", "obj_pos" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:03.951668Z", "iopub.status.busy": "2021-04-23T20:45:03.950556Z", "iopub.status.idle": "2021-04-23T20:45:03.957738Z", "shell.execute_reply": "2021-04-23T20:45:03.954413Z" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# visit_coords is many rows: The location of all detected sources in the source catalog\n", "visit_coords[:10]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we want to find the closest match to `obj_pos` in `visit_coords` so we use `matchToCatalogSky` with `visit_coords` as the argument. What we get back are the index in `visit_coords` of the closest match and the 2-dimensional separation on the sky to that match. (If we had distance information we could use this to also get a closest 3-dimensional match.)" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:03.963917Z", "iopub.status.busy": "2021-04-23T20:45:03.962822Z", "iopub.status.idle": "2021-04-23T20:45:03.969228Z", "shell.execute_reply": "2021-04-23T20:45:03.966956Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "84 [0.39408103]\n" ] } ], "source": [ "idx, sep2d, sep3d = obj_pos.match_to_catalog_sky(visit_coords)\n", "print(idx, sep2d.arcsec)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Get Photometry for our matched source out of the Source Catalog" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use the source catalog directly to get instrumental fluxes and errors." ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:03.974209Z", "iopub.status.busy": "2021-04-23T20:45:03.973247Z", "iopub.status.idle": "2021-04-23T20:45:03.981246Z", "shell.execute_reply": "2021-04-23T20:45:03.980379Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "355.4253564211041\n" ] } ], "source": [ "obj_instFlux = diffexp_src_cat.getPsfInstFlux()[idx]\n", "print(obj_instFlux)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:03.986086Z", "iopub.status.busy": "2021-04-23T20:45:03.985171Z", "iopub.status.idle": "2021-04-23T20:45:03.991128Z", "shell.execute_reply": "2021-04-23T20:45:03.988731Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "56.061742251235195\n" ] } ], "source": [ "obj_instFlux_err = diffexp_src_cat.getPsfInstFluxErr()[idx]\n", "print(obj_instFlux_err)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But what if we want calibrated fluxes and magnitudes along with the errors?\n", "\n", "Use `photoCalib` product." ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:03.995487Z", "iopub.status.busy": "2021-04-23T20:45:03.994596Z", "iopub.status.idle": "2021-04-23T20:45:03.998760Z", "shell.execute_reply": "2021-04-23T20:45:03.997212Z" } }, "outputs": [], "source": [ "deepDiff_photoCalib = diffexp.getPhotoCalib()" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:04.003575Z", "iopub.status.busy": "2021-04-23T20:45:04.002743Z", "iopub.status.idle": "2021-04-23T20:45:04.007904Z", "shell.execute_reply": "2021-04-23T20:45:04.006075Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "value=1280.067439057850379, error=201.9069922125679568\n", "1280.0674390578504 201.90699221256796\n" ] } ], "source": [ "obj_g_flux = deepDiff_photoCalib.instFluxToNanojansky(obj_instFlux, obj_instFlux_err)\n", "print(obj_g_flux)\n", "\n", "# Access flux and error separately\n", "print(obj_g_flux.value, obj_g_flux.error)" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:04.012079Z", "iopub.status.busy": "2021-04-23T20:45:04.011278Z", "iopub.status.idle": "2021-04-23T20:45:04.016211Z", "shell.execute_reply": "2021-04-23T20:45:04.014437Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "value=23.63191787346008965, error=0.1712548298239273958\n", "23.63191787346009 0.1712548298239274\n" ] } ], "source": [ "obj_g_mag = deepDiff_photoCalib.instFluxToMagnitude(obj_instFlux, obj_instFlux_err)\n", "print(obj_g_mag)\n", "\n", "# Access flux and error separately\n", "print(obj_g_mag.value, obj_g_mag.error)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a light curve for the asteroid" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create a function to load in coordinates" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:04.020888Z", "iopub.status.busy": "2021-04-23T20:45:04.020122Z", "iopub.status.idle": "2021-04-23T20:45:04.023786Z", "shell.execute_reply": "2021-04-23T20:45:04.023119Z" } }, "outputs": [], "source": [ "def return_obj_skycoord(visit_data):\n", " obj_pos = SkyCoord('%i %i %f %i %i %f' % (visit_data['ra_hour'],\n", " visit_data['ra_min'],\n", " visit_data['ra_sec'],\n", " visit_data['dec_deg'],\n", " visit_data['dec_min'],\n", " visit_data['dec_sec']),\n", " unit=(u.hourangle, u.degree))\n", " \n", " return obj_pos" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Loop through each visit and gather necessary data\n", "\n", "To do this we need to load in the `differenceExp` and get the time of the observation. Then we get the source catalog and find the closest match to the known position of our asteroid coordinates. \n", "\n", "To make sure we only keep good matches in our light curve we set a threshold of 1 arcsec on our matches. If the closest detected object is more than 1 arcsec we will move on to the next visit without a flux measurement.\n", "\n", "If we do have a good match then we will use the `photoCalib` to get a calibrated flux measurement for our light curve." ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:04.784912Z", "iopub.status.busy": "2021-04-23T20:45:04.032678Z", "iopub.status.idle": "2021-04-23T20:45:12.670717Z", "shell.execute_reply": "2021-04-23T20:45:12.669536Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "No close matches for visit 410929. Distance to closest match: 16.27 arcsec\n", "Match within 0.39 arcsec for visit 410985\n", "No close matches for visit 411035. Distance to closest match: 33.96 arcsec\n", "No close matches for visit 411069. Distance to closest match: 35.25 arcsec\n", "No close matches for visit 411269. Distance to closest match: 85.68 arcsec\n", "Match within 0.53 arcsec for visit 411319\n", "Match within 0.33 arcsec for visit 411369\n", "Match within 0.64 arcsec for visit 411420\n", "No close matches for visit 411470. Distance to closest match: 36.11 arcsec\n", "No close matches for visit 411671. Distance to closest match: 50.35 arcsec\n", "Match within 0.48 arcsec for visit 411772\n", "Match within 0.61 arcsec for visit 411822\n", "No close matches for visit 411872. Distance to closest match: 34.88 arcsec\n" ] } ], "source": [ "visit_time = []\n", "visit_flux = []\n", "visit_flux_err = []\n", "visit_mag = []\n", "\n", "for obs_idx in range(len(hits_object_df)):\n", " \n", " # Load data\n", " hits_visit = hits_object_df.iloc[obs_idx]\n", " data_id = {'visit': hits_visit['visit'], 'ccdnum': 9, 'filter':'g'}\n", " diffexp = butler.get('deepDiff_differenceExp', data_id)\n", " diffexp_src_cat = butler.get('deepDiff_diaSrc', data_id)\n", " exp_visit_info = diffexp.getInfo().getVisitInfo()\n", " \n", " # Get Times\n", " visit_date_python = exp_visit_info.getDate().toPython()\n", " visit_date_astropy = Time(visit_date_python)\n", " \n", " # Match to Difference Image Source Catalog\n", " obj_pos = return_obj_skycoord(hits_visit)\n", " visit_coords = SkyCoord(diffexp_src_cat['coord_ra']*u.rad,\n", " diffexp_src_cat['coord_dec']*u.rad)\n", " match_idx, match_sep2d, _ = obj_pos.match_to_catalog_sky(visit_coords)\n", " \n", " # Only keep matches with 1 arcsecond. Otherwise skip this visit.\n", " if match_sep2d.arcsec > 1.0:\n", " print('No close matches for visit %i. Distance to closest match: %.2f arcsec' % (hits_visit['visit'], match_sep2d.arcsec))\n", " continue\n", " else:\n", " print('Match within %.2f arcsec for visit %i' % (match_sep2d.arcsec, hits_visit['visit']))\n", " \n", " # Load Flux for matched object\n", " visit_time.append(visit_date_astropy.mjd)\n", " inst_flux = diffexp_src_cat.getPsfInstFlux()[match_idx]\n", " inst_flux_err = diffexp_src_cat.getPsfInstFluxErr()[match_idx]\n", " deepDiff_photoCalib = diffexp.getPhotoCalib()\n", " obj_flux = deepDiff_photoCalib.instFluxToNanojansky(inst_flux, inst_flux_err)\n", " visit_flux.append(obj_flux.value)\n", " visit_flux_err.append(obj_flux.error)\n", " \n", " # For Exercise 2\n", " # Load Magnitude for matched object or interesting columns from source catalog or visit information here.\n", "\n", "visit_time = np.array(visit_time)" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "execution": { "iopub.execute_input": "2021-04-23T20:45:12.686687Z", "iopub.status.busy": "2021-04-23T20:45:12.685535Z", "iopub.status.idle": "2021-04-23T20:45:12.713276Z", "shell.execute_reply": "2021-04-23T20:45:12.706641Z" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "84d21c28c7654cfe9769206b22a87c83", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "Text(0.5, 1.0, '2015 DQ249 Light Curve in HiTS')" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fig = plt.figure()\n", "plt.errorbar(visit_time - visit_time[0], visit_flux, yerr=visit_flux_err, marker='o', lw=1, elinewidth=2)\n", "plt.xlabel('Time from First Observation (Days)')\n", "plt.ylabel('Flux (nanojansky)')\n", "plt.title('2015 DQ249 Light Curve in HiTS')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And there is our light curve!\n", "\n", "It seems that a few of our measurements did not have matching sources in the source catalog. KBMOD is designed to find objects that are not likely to be above the standard 5-sigma detection threshold in a single measurement so this is not surprising. An advanced exercise would be to rerun source detection with a lower threshold to try and get measurements for those visits and fill in the light curve!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Exercise 2\n", "Now that we have the basic infrastructure in place go back and make some other plots over time. An easy first step would be to make this plot with the magnitude of the source instead of the flux. Other ideas are to plot values from other columns in the source catalog or plot properties of the exposures from the `exp_visit_info` object. Or remake this plot with the astrometry from `2014_XW40`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "LSST", "language": "python", "name": "lsst" }, "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.8" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "030cb92730a4488592a58f2102a6c3ff": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "071bde330e184f28a1dcaf8f44792872": { "model_module": "jupyter-matplotlib", "model_module_version": "^0.7.4", "model_name": "MPLCanvasModel", "state": { "_cursor": "pointer", "_dom_classes": [], "_figure_label": "Figure", "_height": 0, "_image_mode": "full", "_message": "", "_model_module": "jupyter-matplotlib", "_model_module_version": "^0.7.4", "_model_name": "MPLCanvasModel", "_rubberband_height": 0, "_rubberband_width": 0, "_rubberband_x": 0, "_rubberband_y": 0, "_view_count": null, "_view_module": "jupyter-matplotlib", "_view_module_version": "^0.7.4", "_view_name": "MPLCanvasView", "_width": 0, "capture_scroll": false, "footer_visible": true, "header_visible": true, "layout": "IPY_MODEL_106dea99d0144d54a9a51ceb15092327", "resizable": true, "toolbar": "IPY_MODEL_f71f983f755e465887ed3af97f1518b8", "toolbar_position": "left", "toolbar_visible": true } }, "106dea99d0144d54a9a51ceb15092327": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "12b5a0e13f534a168db46f3bd8e06699": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "62f8bc3b4cdb41fb870dc03cc30e8c3a": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "7136b2027b6a4dd4a2e5fb7a501b96f0": { "model_module": "jupyter-matplotlib", "model_module_version": "^0.7.4", "model_name": "ToolbarModel", "state": { "_current_action": "", "_dom_classes": [], "_model_module": "jupyter-matplotlib", "_model_module_version": "^0.7.4", "_model_name": "ToolbarModel", "_view_count": null, "_view_module": "jupyter-matplotlib", "_view_module_version": "^0.7.4", "_view_name": "ToolbarView", "button_style": "", "collapsed": true, "layout": "IPY_MODEL_62f8bc3b4cdb41fb870dc03cc30e8c3a", "orientation": "vertical", "toolitems": [ [ "Home", "Reset original view", "home", "home" ], [ "Back", "Back to previous view", "arrow-left", "back" ], [ "Forward", "Forward to next view", "arrow-right", "forward" ], [ "Pan", "Left button pans, Right button zooms\nx/y fixes axis, CTRL fixes aspect", "arrows", "pan" ], [ "Zoom", "Zoom to rectangle\nx/y fixes axis, CTRL fixes aspect", "square-o", "zoom" ], [ "Download", "Download plot", "floppy-o", "save_figure" ] ] } }, "813718455d684c6aa61a32edcf2f85c0": { "model_module": "jupyter-matplotlib", "model_module_version": "^0.7.4", "model_name": "MPLCanvasModel", "state": { "_cursor": "pointer", "_dom_classes": [], "_figure_label": "Figure", "_height": 0, "_image_mode": "full", "_message": "", "_model_module": "jupyter-matplotlib", "_model_module_version": "^0.7.4", "_model_name": "MPLCanvasModel", "_rubberband_height": 0, "_rubberband_width": 0, "_rubberband_x": 0, "_rubberband_y": 0, "_view_count": null, "_view_module": "jupyter-matplotlib", "_view_module_version": "^0.7.4", "_view_name": "MPLCanvasView", "_width": 0, "capture_scroll": false, "footer_visible": true, "header_visible": true, "layout": "IPY_MODEL_f141d045447b41e28db3ef09f958ca87", "resizable": true, "toolbar": "IPY_MODEL_7136b2027b6a4dd4a2e5fb7a501b96f0", "toolbar_position": "left", "toolbar_visible": true } }, "84d21c28c7654cfe9769206b22a87c83": { "model_module": "jupyter-matplotlib", "model_module_version": "^0.7.4", "model_name": "MPLCanvasModel", "state": { "_cursor": "pointer", "_dom_classes": [], "_figure_label": "Figure", "_height": 0, "_image_mode": "full", "_message": "", "_model_module": "jupyter-matplotlib", "_model_module_version": "^0.7.4", "_model_name": "MPLCanvasModel", "_rubberband_height": 0, "_rubberband_width": 0, "_rubberband_x": 0, "_rubberband_y": 0, "_view_count": null, "_view_module": "jupyter-matplotlib", "_view_module_version": "^0.7.4", "_view_name": "MPLCanvasView", "_width": 0, "capture_scroll": false, "footer_visible": true, "header_visible": true, "layout": "IPY_MODEL_c9aa69fa085645479d21ce446bf66340", "resizable": true, "toolbar": "IPY_MODEL_f17fcca9dc7a4cd48842e9a2e4ea1916", "toolbar_position": "left", "toolbar_visible": true } }, "c9aa69fa085645479d21ce446bf66340": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f141d045447b41e28db3ef09f958ca87": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f17fcca9dc7a4cd48842e9a2e4ea1916": { "model_module": "jupyter-matplotlib", "model_module_version": "^0.7.4", "model_name": "ToolbarModel", "state": { "_current_action": "", "_dom_classes": [], "_model_module": "jupyter-matplotlib", "_model_module_version": "^0.7.4", "_model_name": "ToolbarModel", "_view_count": null, "_view_module": "jupyter-matplotlib", "_view_module_version": "^0.7.4", "_view_name": "ToolbarView", "button_style": "", "collapsed": true, "layout": "IPY_MODEL_12b5a0e13f534a168db46f3bd8e06699", "orientation": "vertical", "toolitems": [ [ "Home", "Reset original view", "home", "home" ], [ "Back", "Back to previous view", "arrow-left", "back" ], [ "Forward", "Forward to next view", "arrow-right", "forward" ], [ "Pan", "Left button pans, Right button zooms\nx/y fixes axis, CTRL fixes aspect", "arrows", "pan" ], [ "Zoom", "Zoom to rectangle\nx/y fixes axis, CTRL fixes aspect", "square-o", "zoom" ], [ "Download", "Download plot", "floppy-o", "save_figure" ] ] } }, "f71f983f755e465887ed3af97f1518b8": { "model_module": "jupyter-matplotlib", "model_module_version": "^0.7.4", "model_name": "ToolbarModel", "state": { "_current_action": "", "_dom_classes": [], "_model_module": "jupyter-matplotlib", "_model_module_version": "^0.7.4", "_model_name": "ToolbarModel", "_view_count": null, "_view_module": "jupyter-matplotlib", "_view_module_version": "^0.7.4", "_view_name": "ToolbarView", "button_style": "", "collapsed": true, "layout": "IPY_MODEL_030cb92730a4488592a58f2102a6c3ff", "orientation": "vertical", "toolitems": [ [ "Home", "Reset original view", "home", "home" ], [ "Back", "Back to previous view", "arrow-left", "back" ], [ "Forward", "Forward to next view", "arrow-right", "forward" ], [ "Pan", "Left button pans, Right button zooms\nx/y fixes axis, CTRL fixes aspect", "arrows", "pan" ], [ "Zoom", "Zoom to rectangle\nx/y fixes axis, CTRL fixes aspect", "square-o", "zoom" ], [ "Download", "Download plot", "floppy-o", "save_figure" ] ] } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }