{
"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", " | visit | \n", "year | \n", "month | \n", "day | \n", "ra_hour | \n", "ra_min | \n", "ra_sec | \n", "dec_deg | \n", "dec_min | \n", "dec_sec | \n", "
---|---|---|---|---|---|---|---|---|---|---|
0 | \n", "410929 | \n", "2015 | \n", "2 | \n", "17.15939 | \n", "10 | \n", "19 | \n", "38.442 | \n", "-5 | \n", "56 | \n", "40.41 | \n", "
1 | \n", "410985 | \n", "2015 | \n", "2 | \n", "17.24529 | \n", "10 | \n", "19 | \n", "37.616 | \n", "-5 | \n", "56 | \n", "33.08 | \n", "
2 | \n", "411035 | \n", "2015 | \n", "2 | \n", "17.31416 | \n", "10 | \n", "19 | \n", "36.969 | \n", "-5 | \n", "56 | \n", "27.42 | \n", "
3 | \n", "411069 | \n", "2015 | \n", "2 | \n", "17.36113 | \n", "10 | \n", "19 | \n", "36.501 | \n", "-5 | \n", "56 | \n", "23.76 | \n", "
4 | \n", "411269 | \n", "2015 | \n", "2 | \n", "18.08845 | \n", "10 | \n", "19 | \n", "29.672 | \n", "-5 | \n", "55 | \n", "23.12 | \n", "