Skip to content

Commit

Permalink
add plotting example nb
Browse files Browse the repository at this point in the history
  • Loading branch information
jrob93 committed Oct 7, 2024
1 parent 39a4ab8 commit c1e99d8
Show file tree
Hide file tree
Showing 4 changed files with 941 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/notebooks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ Notebooks

Introducing Jupyter Notebooks <notebooks/intro_notebook>
Adler phasecurve models <notebooks/adler_phasecurve_example>
Adler plotting example <notebooks/plotting_utilities_example>
384 changes: 384 additions & 0 deletions docs/notebooks/colour_functions_example.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,384 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d3190549",
"metadata": {},
"source": [
"# Adler running colour measurement\n",
"\n",
"Adler includes a function `col_obs_ref` which calculates the difference between the most recent brightness data point in the observation (obs) filter and a number of previous measurements in the reference (ref) filter."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "82537a61",
"metadata": {},
"outputs": [],
"source": [
"from adler.dataclasses.AdlerPlanetoid import AdlerPlanetoid\n",
"from adler.dataclasses.AdlerData import AdlerData\n",
"from adler.science.PhaseCurve import PhaseCurve\n",
"from adler.science.Colour import col_obs_ref\n",
"from adler.utilities.plotting_utilities import plot_errorbar\n",
"from adler.utilities.science_utilities import apparition_gap_finder, get_df_obs_filt\n",
"\n",
"import numpy as np\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib.gridspec as gridspec\n",
"import astropy.units as u\n",
"from scipy.interpolate import splrep, BSpline, CubicSpline\n",
"from astropy.modeling.fitting import SLSQPLSQFitter\n",
"from astropy.time import Time\n",
"from astroquery.jplhorizons import Horizons"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b9f6dcda",
"metadata": {},
"outputs": [],
"source": [
"# ssObjectId of object to analyse\n",
"ssoid = \"6098332225018\" # good MBA test object"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c6f705c1",
"metadata": {},
"outputs": [],
"source": [
"# retrieve the object data\n",
"fname = \"../../notebooks/gen_test_data/adler_demo_testing_database.db\"\n",
"planetoid = AdlerPlanetoid.construct_from_SQL(ssoid, sql_filename=fname)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "21e0b93e",
"metadata": {},
"outputs": [],
"source": [
"# check orbit parameters\n",
"e = planetoid.MPCORB.e\n",
"incl = planetoid.MPCORB.incl\n",
"q = planetoid.MPCORB.q\n",
"a = q / (1.0 - e)\n",
"Q = a * (1.0 + e)\n",
"print(a, e, incl)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ee4064e7",
"metadata": {},
"outputs": [],
"source": [
"# plot and fit the phase curves in g and r filters\n",
"\n",
"fig = plt.figure()\n",
"gs = gridspec.GridSpec(1, 1)\n",
"ax1 = plt.subplot(gs[0, 0])\n",
"\n",
"adler_data = AdlerData(ssoid, planetoid.filter_list)\n",
"\n",
"for filt in [\"g\", \"r\"]:\n",
" # get observations and define a phase curve model to fit\n",
" sso = planetoid.SSObject_in_filter(filt)\n",
" obs = planetoid.observations_in_filter(filt)\n",
"\n",
" H = sso.H\n",
" G12 = sso.G12\n",
" pc = PhaseCurve(H=H * u.mag, phase_parameter_1=G12, model_name=\"HG12_Pen16\")\n",
"\n",
" alpha = np.linspace(0, np.amax(obs.phaseAngle)) * u.deg\n",
"\n",
" pc_fit = pc.FitModel(\n",
" np.array(getattr(obs, \"phaseAngle\")) * u.deg,\n",
" np.array(getattr(obs, \"reduced_mag\")) * u.mag,\n",
" )\n",
" pc = pc.InitModelSbpy(pc_fit)\n",
" red_mag = pc.ReducedMag(alpha)\n",
"\n",
" adler_data.populate_phase_parameters(filt, **pc.ReturnModelDict())\n",
"\n",
" # add this phase curve to the figure using the Adler plotting function\n",
" fig = plot_errorbar(planetoid, filt_list=[filt], fig=fig)\n",
" ax1 = fig.axes[0]\n",
" ax1.plot(\n",
" alpha.value,\n",
" pc.ReducedMag(alpha).value,\n",
" label=\"{}: H={:.2f}, G12={:.2f}\".format(filt, pc.H, pc.phase_parameter_1),\n",
" )\n",
" ax1.legend()\n",
"\n",
"ax1.invert_yaxis()\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d0df3c51",
"metadata": {},
"outputs": [],
"source": [
"# inspect the r filter phase curve model\n",
"adler_data.get_phase_parameters_in_filter(\"r\", \"HG12_Pen16\").__dict__"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c46fb9eb",
"metadata": {},
"outputs": [],
"source": [
"# inspect the g filter phase curve model\n",
"adler_data.get_phase_parameters_in_filter(\"g\", \"HG12_Pen16\").__dict__"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "73871e56",
"metadata": {},
"outputs": [],
"source": [
"# get the boundary times for each apparation of the object in the survey\n",
"# in this example we will just look at changes in colour for a single apparition\n",
"df_obs_all = pd.DataFrame()\n",
"for filt in [\"r\", \"g\"]:\n",
" obs = planetoid.observations_in_filter(filt)\n",
" _df_obs = pd.DataFrame(obs.__dict__)\n",
" df_obs_all = pd.concat([df_obs_all, _df_obs])\n",
"df_obs_all = df_obs_all.sort_values(\"midPointMjdTai\")\n",
"\n",
"t_app = apparition_gap_finder(np.array(df_obs_all[\"midPointMjdTai\"]))\n",
"print(t_app)"
]
},
{
"cell_type": "markdown",
"id": "63980010",
"metadata": {},
"source": [
"Now we can inpsect how the colour of the object varies (or not) as a function of time. The adler function `col_obs_ref` will compare the latest observation in a given filter with observations in another filter. By setting parameter `N_ref` one can set how many past obsevrations to use when calculating the latest colour."
]
},
{
"cell_type": "markdown",
"id": "5fd261a3",
"metadata": {},
"source": [
"Here we simulate observations coming night-by-night and the calculation of a g-r colour for the object\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bd0e0185",
"metadata": {},
"outputs": [],
"source": [
"# define colour function parameters\n",
"\n",
"# set number of reference observations to use for colour estimate, there are multiple options\n",
"# N_ref = 5\n",
"N_ref = 3\n",
"# N_ref = 1\n",
"# N_ref = None # selecting None uses all previous reference filter measurements\n",
"\n",
"# observation and filter field names\n",
"x_plot = \"midPointMjdTai\" # time column\n",
"y_plot = \"reduced_mag\" # magnitude column\n",
"yerr_plot = \"magErr\" # magnitude uncertainty column\n",
"filt_obs = \"g\" # observation filter\n",
"filt_ref = \"r\" # reference filter (we are calculating a filt_obs - filt_ref colour)\n",
"\n",
"# define colour field names\n",
"colour = \"{}-{}\".format(filt_obs, filt_ref)\n",
"colErr = \"{}-{}Err\".format(filt_obs, filt_ref)\n",
"delta_t_col = \"delta_t_{}\".format(colour)\n",
"y_ref_col = \"{}_{}\".format(y_plot, filt_ref)\n",
"x1_ref_col = \"{}1_{}\".format(x_plot, filt_ref)\n",
"x2_ref_col = \"{}2_{}\".format(x_plot, filt_ref)\n",
"\n",
"fig = plt.figure()\n",
"gs = gridspec.GridSpec(1, 1)\n",
"ax1 = plt.subplot(gs[0, 0])\n",
"\n",
"col_dict_list = []\n",
"for app_i in range(len(t_app) - 1):\n",
" # consider only one apparition\n",
" if app_i != 3:\n",
" continue\n",
"\n",
" time_min = t_app[app_i]\n",
" time_max = t_app[app_i + 1]\n",
"\n",
" _df_obs_all = df_obs_all[\n",
" (df_obs_all[\"midPointMjdTai\"] >= time_min) & (df_obs_all[\"midPointMjdTai\"] < time_max)\n",
" ]\n",
" _time_max = np.amax(_df_obs_all[\"midPointMjdTai\"])\n",
"\n",
" # get the phase curve model and observations for each filter\n",
"\n",
" # get the stored AdlerData parameters for the observation filter\n",
" ad_g = adler_data.get_phase_parameters_in_filter(filt_obs, \"HG12_Pen16\")\n",
" pc_g = PhaseCurve().InitModelDict(ad_g.__dict__) # make the PhaseCurve object from AdlerData\n",
" # get the phase curve model for the reference filter\n",
" ad_r = adler_data.get_phase_parameters_in_filter(filt_ref, \"HG12_Pen16\")\n",
" pc_r = PhaseCurve().InitModelDict(ad_r.__dict__)\n",
" # get the observations in both filters\n",
" df_obs = get_df_obs_filt(\n",
" planetoid, filt_obs, x1=time_min, x2=_time_max, col_list=[y_plot, yerr_plot], pc_model=pc_g\n",
" )\n",
" df_obs_ref = get_df_obs_filt(\n",
" planetoid, filt_ref, x1=time_min, x2=_time_max, col_list=[y_plot, yerr_plot], pc_model=pc_r\n",
" )\n",
"\n",
" ax1.errorbar(df_obs[x_plot], df_obs[y_plot], df_obs[yerr_plot], fmt=\"o\", label=filt_obs)\n",
" ax1.errorbar(df_obs_ref[x_plot], df_obs_ref[y_plot], df_obs_ref[yerr_plot], fmt=\"o\", label=filt_ref)\n",
"\n",
" # simulate stepping through each new filt_obs observation\n",
" x1 = time_min\n",
" for xi in range(len(df_obs)):\n",
" x2 = df_obs.iloc[xi][x_plot]\n",
"\n",
" # run the colour finding function here\n",
" col_dict = col_obs_ref(\n",
" planetoid,\n",
" adler_data,\n",
" filt_obs=filt_obs,\n",
" filt_ref=filt_ref,\n",
" N_ref=N_ref,\n",
" x_col=x_plot,\n",
" y_col=y_plot,\n",
" yerr_col=yerr_plot,\n",
" x1=x1,\n",
" x2=x2,\n",
" )\n",
" col_dict_list.append(col_dict)\n",
"\n",
" # plot some lines to show the colour and mean reference\n",
" ax1.vlines(df_obs.iloc[xi][x_plot], df_obs.iloc[xi][y_plot], col_dict[y_ref_col], color=\"k\", ls=\":\")\n",
" ax1.hlines(col_dict[y_ref_col], col_dict[x1_ref_col], col_dict[x2_ref_col], color=\"k\", ls=\"--\")\n",
"\n",
"# store running colour parameters as a dataframe\n",
"df_col = pd.DataFrame(col_dict_list)\n",
"df_col = pd.concat([df_obs, df_col], axis=1)\n",
"\n",
"ax1.set_xlabel(x_plot)\n",
"ax1.set_ylabel(y_plot)\n",
"ax1.legend()\n",
"ax1.invert_yaxis()\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a7734122",
"metadata": {},
"outputs": [],
"source": [
"# display the recorded colour parameters\n",
"df_col"
]
},
{
"cell_type": "markdown",
"id": "7f505a7e",
"metadata": {},
"source": [
"Now we can plot how the colour changes as a function of time"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0cd867d9",
"metadata": {},
"outputs": [],
"source": [
"# find filt_obs - filt_ref of newest filt_obs observation to the mean of the previous N_ref filt_ref observations\n",
"# colour code by time diff between obs and most recent obs_ref\n",
"\n",
"x_plot = \"midPointMjdTai\"\n",
"y_plot = colour\n",
"y_plot_err = colErr\n",
"c_plot = delta_t_col\n",
"df_plot = df_col\n",
"\n",
"fig = plt.figure()\n",
"gs = gridspec.GridSpec(1, 1)\n",
"ax1 = plt.subplot(gs[0, 0])\n",
"\n",
"s1 = ax1.scatter(df_plot[x_plot], df_plot[y_plot], c=df_plot[c_plot], zorder=3)\n",
"cbar1 = plt.colorbar(s1)\n",
"ax1.errorbar(df_plot[x_plot], df_plot[y_plot], df_plot[yerr_plot], fmt=\".\", zorder=1)\n",
"\n",
"obs_ref_mean = np.mean(df_plot[y_plot])\n",
"obs_ref_std = np.std(df_plot[y_plot])\n",
"print(\"{}-{} mean = {}, std = {}\".format(filt_obs, filt_ref, obs_ref_mean, obs_ref_std))\n",
"\n",
"ax1.axhline(obs_ref_mean, c=\"k\")\n",
"ax1.axhspan(obs_ref_mean - obs_ref_std, obs_ref_mean + obs_ref_std, zorder=0, color=\"k\", alpha=0.2)\n",
"\n",
"ax1.set_xlabel(x_plot)\n",
"ax1.set_ylabel(y_plot)\n",
"cbar1.set_label(c_plot)\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "620fe556",
"metadata": {},
"source": [
"These colours can then be run through the previously written outlier detection functions.\n",
"We have recorded metadata which can help exclude erroneous colour measurements, such as the time difference between the obs and ref measurements."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "605a043a",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "adler-dev",
"language": "python",
"name": "adler-dev"
},
"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.10.14"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading

0 comments on commit c1e99d8

Please sign in to comment.