diff --git a/docs/flystar/examples/motion_model_example.ipynb b/docs/flystar/examples/motion_model_example.ipynb
new file mode 100644
index 0000000..413b616
--- /dev/null
+++ b/docs/flystar/examples/motion_model_example.ipynb
@@ -0,0 +1,1363 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "333cd262",
+ "metadata": {},
+ "source": [
+ "# Motion Model Examples"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9251851e",
+ "metadata": {},
+ "source": [
+ "# Table of Contents"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1e4364ed",
+ "metadata": {},
+ "source": [
+ "# Table of Contents\n",
+ "- [1. Motion Model](#1-motion-model)\n",
+ " - [1.1. Example: Linear Model Fit](#11-example-linear-model-fit)\n",
+ " - [1.2. Example: Acceleration Model Fit](#12-example-acceleration-model-fit)\n",
+ " - [1.3. Example: Parallax Model Fit](#13-example-parallax-model-fit)\n",
+ "- [2. Fit Motion Model in StarTable](#2-fit-motion-model-in-startable)\n",
+ " - [2.1. Example: Default Fitting](#21-example-default-fitting)\n",
+ " - [2.2 Example: Specify Motion Models](#22-example-specify-motion-models)\n",
+ " - [2.3. Example: Specify the `motion_model_input` Column](#23-example-specify-the-motion_model_input-column)\n",
+ " - [2.4. Example: Infer Positions](#24-example-infer-positions)\n",
+ " - [2.5. Speed Test](#25-speed-test)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4bd92a9d",
+ "metadata": {},
+ "source": [
+ "# 1. Motion Model"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0d084c38",
+ "metadata": {},
+ "source": [
+ "Summary of currently implemented motion models"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "faddd6d8",
+ "metadata": {},
+ "source": [
+ "| Motion Model | n_params | params | fixed_params | model | Description |\n",
+ "|--------------|----------|--------------------------------------------|-------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n",
+ "| Empty | 0 | NA | NA | $x(t) = $ NaN / fill_value
$x_e(t) = $ Inf | |\n",
+ "| Fixed | 1 | $x_0$
$y_0$ | NA | $x(t) = $ np.average($x$, weights=$x_{wt}$) | $x_{wt} = 1/xe^2$ if weighting='var'
$x_{wt} = 1/\\|xe\\|$ if weighting = 'std' |\n",
+ "| Linear | 2 | $x_0, v_x$
$y_0, v_y$ | optional: $t_0 =$ np.average($t, 1/\\sqrt{x_e^2 + y_e^2}$) | $x(t) = x_0 + v_x * (t - t_0)$ | |\n",
+ "| Acceleration | 3 | $x_0, v_{x0}, a_x$
$y_0, v_{y0}, a_y$ | optional: $t_0 =$ np.average($t, 1/\\sqrt{x_e^2 + y_e^2}$) | $x(t) = x_0 + v_{x0} * (t - t_0) + 1/2 * a_x * (t - t_0)^2$ | |\n",
+ "| Parallax | 3 | $x_0, v_x, pi$
$y_0, v_y$ | required: ra, dec
optional: $t_0 =$ np.average($t, 1/\\sqrt{x_e^2 + y_e^2}$); $pa=0$; obsLocation='earth' | $x(t) = x_0 + v_x * (t - t_0) + pvec * (t - t_0)$ | pvec is the parallax vector calculated based on ra, dec, pa, and obsLocation.
Only supports the same obsLocation for all stars in StarTable.fit_motion_model right now. |"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6fdc98af",
+ "metadata": {},
+ "source": [
+ "Examples on using `flystar.MotionModel`:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "51c963a1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%load_ext autoreload\n",
+ "%autoreload 2"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "473b0674",
+ "metadata": {},
+ "source": [
+ "Imports"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "ce4edb88",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "from flystar import motion_model\n",
+ "from flystar.startables import StarTable\n",
+ "from flystar.motion_model import Empty, Fixed, Linear, Acceleration, Parallax"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8c0e8559",
+ "metadata": {},
+ "source": [
+ "Prepare data"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "86b6319d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "t = np.array([0, 1., 2.2, 3.5, 5.]) + 2025.0\n",
+ "x = np.array([0., 0.5, 2.1, 3.2, 8.0])\n",
+ "y = np.array([10.2, 8.5, 9.1, 10.5, 13.0])\n",
+ "xe = np.array([0.2, 0.5, 0.3, 0.4, 0.6])\n",
+ "ye = np.array([0.3, 0.2, 0.5, 0.2, 0.4])\n",
+ "t_test = np.linspace(2025.0, 2030.0, 100) # Test times for model evaluation"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b1a87102",
+ "metadata": {},
+ "source": [
+ "## 1.1. Example: Linear Model Fit"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "0926c0a8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mm = Linear()\n",
+ "params, param_errs = mm.fit(t, x, y, xe, ye)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1fad1962",
+ "metadata": {},
+ "source": [
+ "Evaluate model at time t:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "840693ae",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x_model, y_model = mm.model(t, params)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "42fbd575",
+ "metadata": {},
+ "source": [
+ "Or if uncertainties of parameters is provided at the same time, the model will return the model uncertainties as well:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "8fcbdc5d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x_model, y_model, xe_model, ye_model = mm.model(t, params, param_errs)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6f9954ef",
+ "metadata": {},
+ "source": [
+ "Note that we did not provide the `fixed_params_dict` parameter in the `model` function, so the MotionModel will use the saved self.fixed_params_dict. One can also specify the fixed_params_dict as:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "6752e477",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'t0': np.float64(2027.0454838983064)}"
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "mm.fixed_params_dict"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "eba675c8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x_model, y_model, xe_model, ye_model = mm.model(t_test, params, param_errs, mm.fixed_params_dict)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a2acbe90",
+ "metadata": {},
+ "source": [
+ "Define a helper function to visualize result"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "7dba325f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def visualize_fit(t, x, y, xe, ye, x_model, y_model, xe_model, ye_model, mm_name, t_test=None):\n",
+ " if t_test is None:\n",
+ " t_test = t\n",
+ " x = np.atleast_2d(x)\n",
+ " y = np.atleast_2d(y)\n",
+ " xe = np.atleast_2d(xe)\n",
+ " ye = np.atleast_2d(ye)\n",
+ " x_model = np.atleast_2d(x_model)\n",
+ " y_model = np.atleast_2d(y_model)\n",
+ " xe_model = np.atleast_2d(xe_model)\n",
+ " ye_model = np.atleast_2d(ye_model)\n",
+ " \n",
+ " N_cases = x.shape[0]\n",
+ " fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))\n",
+ " for i in range(N_cases):\n",
+ " l0 = ax1.errorbar(t, x[i], yerr=xe[i], fmt='o', color=f'C{i%10}', label='Data')\n",
+ " l1, = ax1.plot(t_test, x_model[i], label=f'{mm_name} Fit')\n",
+ " l2 = ax1.fill_between(t_test, x_model[i] - xe_model[i], x_model[i] + xe_model[i], color=f'C{i%10}', alpha=0.3, label='Model Uncertainty')\n",
+ "\n",
+ " r0 = ax2.errorbar(t, y[i], yerr=ye[i], fmt='o', color=f'C{i%10}', label='Data')\n",
+ " r1, = ax2.plot(t_test, y_model[i], label=f'{mm_name} Fit')\n",
+ " r2 = ax2.fill_between(t_test, y_model[i] - ye_model[i], y_model[i] + ye_model[i], color=f'C{i%10}', alpha=0.3, label='Model Uncertainty')\n",
+ " ax1.set_xlabel('Time')\n",
+ " ax1.set_ylabel('X Position')\n",
+ " ax1.set_title(f'{mm_name} Motion Model Fit')\n",
+ " ax1.legend(\n",
+ " [l0, (l1, l2)], \n",
+ " ['Data', 'Model Fit'],\n",
+ " )\n",
+ " \n",
+ " ax2.set_xlabel('Time')\n",
+ " ax2.set_ylabel('Y Position')\n",
+ " ax2.set_title(f'{mm_name} Motion Model Fit')\n",
+ " ax2.legend(\n",
+ " [r0, (r1, r2)], \n",
+ " ['Data', 'Model Fit'],\n",
+ " )\n",
+ " plt.tight_layout()\n",
+ " plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "ad03fc67",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAA9wAAAHqCAYAAAD27EaEAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAxv5JREFUeJzs3Xd4XOWZ9/HvqMyMymjUe3XvFYyNCcH03ksKfZMlkAQSNhtC9g2YTQJJdsOShEBClmCIQ4nphECAUBI2gHHvXVbvZYpGU895/xAWFpJsSdZYkvX7XJevizlzZs4zltE993nu534spmmaiIiIiIiIiMiwihnpAYiIiIiIiIgci5Rwi4iIiIiIiESBEm4RERERERGRKFDCLSIiIiIiIhIFSrhFREREREREokAJt4iIiIiIiEgUKOEWERERERERiQIl3CIiIiIiIiJRoIRbREREREREJAqUcMuot2LFCiwWC2vWrOn3nP3792OxWFixYsXRG9gwevfdd7FYLIf8DKeeeioWi4XS0tIhXeOhhx7q871H8u9u+fLlWCwWYmJi2LdvX6/nOzo6SElJwWKxcP311w/bdY/kMx/4Wb377rsDOq+vP5dffjkAFouF5cuXd79m27ZtLF++nP379w96XCIio5FieBfF8OuH7bqK4TLWxI30AESGQ15eHh988AETJ04c6aEcEYfDwaOPPtorMJWXl/Puu++SkpIy5Pd+6KGHyMzM7PXeo+HvLjk5mccee4wf/vCHPY6vWrWKUChEfHz8CI3syN17770sW7asx7GMjAwAPvjgAwoLC7uPb9u2jXvuuYdTTjllyF/KRETGmtEQh4aDYrhiuGK49EUz3HJMsNlsLF68mKysrJEeSr98Pt9hz7nqqqt4//332b17d4/jv//97ykoKGDp0qXDPq7R8Hd31VVX8fjjj2MYRo/jjz76KJdccglWq3WERnbkJk+ezOLFi3v8mTx5MgCLFy/uEaxFRMaj0RCHDkcxvH+K4SKHpoRbjgl9lRcdKHXaunUrX/ziF3E6neTk5HDjjTficrl6vN40TR566CHmzZtHQkICaWlpXH755b1KpN58800uuugiCgsLsdvtTJo0iZtuuonm5uYe5x249rp167j88stJS0sb0N3nM844g6KiIn7/+993HzMMg8cff5zrrruOmJje/8v6/X7uvPNOysrKsFqtFBQU8PWvf5329vbuc0pLS9m6dSvvvfded0nUgbuv/ZVmvf/++5x22mk4HA4SExM58cQTefXVV3ucc6BU8J133uHmm28mMzOTjIwMLr30Umpraw/7eQ+48cYbqaqq4s033+w+tmvXLt5//31uvPHGPl9TWVnJ1VdfTXZ2NjabjenTp/Pzn/+8V8Cvra3lyiuvxOFw4HQ6ueqqq6ivr+/zPdesWcOFF15Ieno6drud+fPn86c//WnAn2OwDi5HW7FiBVdccQUAy5YtO2x5oojIsUIxXDFcMVyOZUq45Zh32WWXMWXKFJ577jm+973v8eSTT/Ltb3+7xzk33XQT3/rWtzj99NN58cUXeeihh9i6dSsnnngiDQ0N3eft3buXJUuW8PDDD/PGG29w11138dFHH3HSSScRCoV6XfvSSy9l0qRJrFq1it/85jeHHWtMTAzXX389TzzxBJFIBIA33niD6upqbrjhhl7nm6bJxRdfzH//939zzTXX8Oqrr3L77bfz+OOPc+qppxIIBAB44YUXmDBhAvPnz+eDDz7ggw8+4IUXXuh3HO+99x6nnnoqLpeLRx99lKeeegqHw8EFF1zAM8880+v8r3zlK8THx/Pkk0/ys5/9jHfffZerr776sJ/3gMmTJ/O5z32ux5eU3//+95SWlnLaaaf1Or+pqYkTTzyRN954gx/+8Ie8/PLLnH766XznO9/hG9/4Rvd5nZ2dnH766bzxxhvcd999rFq1itzcXK666qpe7/nOO++wdOlS2tvb+c1vfsNLL73EvHnzuOqqq44oYBqGQTgc7vGnL+eddx733nsvAL/+9a+7f07nnXfekK8tIjLWKYYrhiuGy5hnioxyjz32mAmYH3/8cb/nlJeXm4D52GOPdR+7++67TcD82c9+1uPcW265xbTb7aZhGKZpmuYHH3xgAubPf/7zHudVVVWZCQkJ5ne/+90+r2kYhhkKhcyKigoTMF966aVe177rrrsG9BnfeecdEzBXrVpl7tu3z7RYLOaf//xn0zRN84orrjBPOeUU0zRN87zzzjNLSkq6X/f666/3+RmfeeYZEzAfeeSR7mMzZ840P//5z/e6dl9/d4sXLzazs7NNj8fTfSwcDpuzZs0yCwsLu//uDvxsbrnllh7v+bOf/cwEzLq6ukN+7gN/T01NTeZjjz1m2mw2s6WlxQyHw2ZeXp65fPly0zRNMykpybzuuuu6X/e9733PBMyPPvqox/vdfPPNpsViMXfu3Gmapmk+/PDDvX42pmmaX/3qV3t95mnTppnz5883Q6FQj3PPP/98My8vz4xEIqZpfvqzeueddw752Q6c19ef3bt3m6ZpmoB59913d79m1apVA3pvEZGxQjFcMVwxXMY7zXDLMe/CCy/s8XjOnDn4/X4aGxsB+POf/4zFYuHqq6/ucQczNzeXuXPn9uhk2djYyNe+9jWKioqIi4sjPj6ekpISALZv397r2pdddtmgx1tWVsYpp5zC73//e1paWnjppZf6Lcl6++23AXo1UbniiitISkrib3/726Cv39HRwUcffcTll19OcnJy9/HY2FiuueYaqqur2blzZ4/X9PV3DFBRUTHg615xxRVYrVb++Mc/8pe//IX6+vp+u5q+/fbbzJgxg0WLFvU4fv3112OaZvffyzvvvIPD4eg1vi996Us9Hu/Zs4cdO3bw5S9/GaDHv4Nzzz2Xurq6Xp95oH7605/y8ccf9/hTVFQ0pPcSERlvFMMHRzFcMVxGH3Upl2PegW6SB9hsNqCrVAmgoaEB0zTJycnp8/UTJkwAusqKzjzzTGpra/nBD37A7NmzSUpKwjAMFi9e3P1+B8vLyxvSmP/lX/6FG264gfvvv5+EhITuLSg+q6Wlhbi4uF7NUiwWC7m5ubS0tAz62m1tbZim2efY8/Pzu697sMP9HQ9EUlISV111Fb///e8pKSnh9NNP7/4i9FktLS19dgD97PhaWlr6/Lnm5ub2eHyg5PA73/kO3/nOd/q85mfX+A3UhAkTOO6444b0WhGR8U4xfHAUwxXDZfRRwi3jXmZmJhaLhX/84x/dQeZgB45t2bKFjRs3smLFCq677rru5/fs2dPve1ssliGN6dJLL+XrX/86P/nJT/jqV79KQkJCn+dlZGQQDodpamrqEbBN06S+vp7jjz9+0NdOS0sjJiaGurq6Xs8daKKSmZk56PcdiBtvvJH//d//ZdOmTfzxj3/s97yMjIwBjS8jI4PVq1f3Ou+zDVcOnH/nnXdy6aWX9nnNqVOnDuxDiIjIUaMY3pNiuGK4jD4qKZdx7/zzz8c0TWpqajjuuON6/Zk9ezbwaeD9bED/7W9/O+xjSkhI4K677uKCCy7g5ptv7ve8A81IVq5c2eP4c889R0dHR49mJTabbUB3q5OSkjjhhBN4/vnne5xvGAYrV66ksLCQKVOmDPYjDciSJUu48cYbueSSS7jkkkv6Pe+0005j27ZtrFu3rsfxJ554AovF0r1n5rJly/B4PLz88ss9znvyySd7PJ46dSqTJ09m48aNff4bOO6443A4HMP0Kfs3lFkFEZHxTDG8J8VwxXAZfTTDLWPG22+/zf79+3sdP/fcc4/ofZcuXcq//uu/csMNN7BmzRpOPvlkkpKSqKur4/3332f27NncfPPNTJs2jYkTJ/K9730P0zRJT0/nlVde6bENxnC6/fbbuf322w95zhlnnMFZZ53FHXfcgdvtZunSpWzatIm7776b+fPnc80113SfO3v2bJ5++mmeeeYZJkyYgN1u7/4i8ln33XcfZ5xxBsuWLeM73/kOVquVhx56iC1btvDUU08N+a7/QDz66KOHPefb3/42TzzxBOeddx7/+Z//SUlJCa+++ioPPfQQN998c/eXiWuvvZb/+Z//4dprr+XHP/4xkydP5i9/+Qt//etfe73nb3/7W8455xzOOussrr/+egoKCmhtbWX79u2sW7eOVatWDftn/axZs2YB8Mgjj+BwOLDb7ZSVlfUq9xMRGWsUw3tTDFcMl/FBCbeMGXfccUefx8vLy4/4vX/729+yePFifvvb3/LQQw9hGAb5+fksXbq0u6lHfHw8r7zyCrfddhs33XQTcXFxnH766bz11lsUFxcf8RiGwmKx8OKLL7J8+XIee+wxfvzjH5OZmck111zDvffe2+NO/j333ENdXR1f/epX8Xg8lJSU9PnlB+Dzn/88b7/9NnfffTfXX389hmEwd+5cXn75Zc4///yj9On6l5WVxT//+U/uvPNO7rzzTtxuNxMmTOBnP/tZjy84iYmJvP3229x2221873vfw2KxcOaZZ/L0009z4okn9njPZcuWsXr1an784x/zrW99i7a2NjIyMpgxYwZXXnnlUflcZWVlPPDAA/ziF7/glFNOIRKJ8Nhjj/XbeEZEZKxQDO9NMVwxXMYHi2ma5kgPQkRERERERORYozXcIiIiIiIiIlGghFtEREREREQkCpRwi4iIiIiIiESBEm4RERERERGRKFDCLSIiIiIiIhIFSrhFREREREREomBM78NtGAa1tbU4HA4sFstID0dERGTATNPE4/GQn59PTMz4u/+tGC4iImPV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KCIiIjIIiuEiIjLWqc5HREREREREJAqUcIuIiIiIiIhEgRJuERERERERkShQwi0iIiIiIiISBUq4RURERERERKJACbeIiIiIiIhIFCjhFhEREREREYkCJdwiIiIiIiIiUaCEW0RERERERCQKlHCLiIiIiIiIRIESbhEREREREZEoUMItIiIiIiIiEgVxIz0AERGRsSDRGsf+n5w30sMQERGRMUQz3CIiIiIiIiJRoIRbREREREREJAqUcIuIiIiIiIhEgRJuERERERERkShQwi0iIiIiIiISBUq4RURERERERKJACbeIiIiIiIhIFCjhFhEREREREYmCuJEegIiIiIiIiEi0JFrj2P+T80bk2prhFhEREREREYkCJdwiIiIiIiIiUaCEW0RERERERCQKlHCLiIiIiIiIRIESbhEREREREZEoUMItIiIiIiIiEgVKuEVERERERESiQAm3iIiIiIiISBQo4RYRERERERGJAiXcIiIiIiIiIlGghFtEREREREQkCpRwi4iIiIiIiESBEm4RERERERGRKFDCLSIiIiIiIhIFSrhFREREREREokAJt4iIiIiIiEgUKOEWERERERERiQIl3CIiIiIiIiJRoIRbREREREREJAqUcIuIiIiIiIhEgRJuERERERERkShQwi0iIiIiIiISBUq4RURERERERKJACbeIiIiIiIhIFCjhFhEREREREYkCJdwiIiIiIiIiUaCEW0RERERERCQKlHCLiIiIiIiIRIESbhEREREREZEoUMItIiIiIiIiEgVKuEVERERERESiQAm3iIiIiIiISBQo4RYRERERERGJAiXcIiIiIiIiIlGghFtEREREREQkCpRwi4iIiIiIiESBEm4RERERERGRKFDCLSIiIiIiIhIFSrhFREQGyDBMIoY50sOIur///e9ccMEF5OfnY7FYePHFF7ufC4VC3HHHHcyePZukpCTy8/O59tprqa2tHbkBi4iIjFJKuEVERAag3Rfk77ubWLu/daSHEnUdHR3MnTuXBx98sNdzPp+PdevW8YMf/IB169bx/PPPs2vXLi688MIRGKmIiMjoFjfSAxARERnNIobJviYv6yvbqXV1Mq8odaSHFHXnnHMO55xzTp/POZ1O3nzzzR7HfvWrX7Fo0SIqKyspLi4+GkMUEREZE5Rwi4iI9MPlC7G+qo09jV4SrbGk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nztjDNu3b+eLX/zimP+IvJhN17wFg0GA8/YwDXw9sFoz28zE33UlJSXk5ubyxBNPkJmZyTXXXDP5NzYNJmvuRrp2JBIBYMuWLXi9Xnbu3Dn4+++++y5er3fM68xXiuHJUwxPnmJ4chTDk6cYnrxZG8Mn3GbtInbvvfcap9NpXnvttfOOXQgGg4Pvefjhh43T6TTPPPOM2b9/v/nCF75wXqt4n89nNm3aZFauXGmOHTt23nUGWsW/9dZb5nvf+57Zs2ePOXHihHniiSdMeXm5+cxnPjMj9z0ZpmvujDHmW9/6lqmoqDAvvfSSOXz4sPnqV79qiouLTXd397Tf92SYzrkzxpjf/OY3BjANDQ3Tep+TbbrmraOjw7jdbnPLLbeYDz74wBw5csT89//+3016err54IMPZuTeL9R0/sz9n//zf8yuXbvMkSNHzD//8z+brKws80//9E/Tfs+TZTLm7vjx4+bv/u7vzPvvv29Onz5t3nrrLXPTTTeZgoIC09bWNnidrVu3mlWrVpm3337bvP3222blypU6FmwUiuHJUwxPnmJ4chTDk6cYnrzZGsPnVMINDPtr+/btg++xLMts27bNlJaWGrvdbq666iqzf//+wd9/9dVXR7zOyZMnjTHG7Nq1y2zatMk4nU6TmZlpli5darZt22b6+vqm+Y4nz3TNnTH9R2H8t//230xxcbFxOBzmk5/8pDlw4MA03u3kms65M8aYL3zhC+ayyy6bprubOtM5b++995659tprTUFBgXE4HGbz5s3ml7/85TTe7eSazrm75557TEFBgcnIyDCrVq0yjz322DTe6eSbjLlrbm421113nSkuLjbp6emmsrLS3HnnnUOOCunq6jJ33XWXcTgcxuFwmLvuusv09PRM053OPorhyVMMT55ieHIUw5OnGJ682RrDbWcHLyIiIiIiIiKTaE7t4RYRERERERG5WCjhFhEREREREZkCSrhFREREREREpoASbhEREREREZEpoIRbREREREREZAoo4RYRERERERGZAkq4RURERERERKaAEm4RERERERGRKaCEW2See+CBB1izZs1MD0NEREQmSDFc5OJnM8aYmR6EiEwNm8026u9/6Utf4p//+Z+JRCK43e5pGpWIiIiMRTFcZG5Qwi0yh7W2tg7+9xNPPMFf//Vfc+TIkcHXsrKycDqdMzE0ERERGYViuMjcoJJykTmstLR08JfT6cRmsw157aPlaF/+8pe5+eab+bu/+ztKSkpwuVw8+OCDxONx/uzP/oyCggIqKyv5f//v/533Wc3Nzdxxxx3k5+fjdru56aabOHXq1PTesIiIyByhGC4yNyjhFpEhXnnlFVpaWnjjjTf43ve+xwMPPMANN9xAfn4+7777Ll//+tf5+te/TmNjIwDBYJCPf/zj5Obm8sYbb/Dmm2+Sm5vL1q1biUajM3w3IiIi84diuMjFRQm3iAxRUFDA//7f/5ulS5fyla98haVLlxIMBvmLv/gLFi9ezLe//W0yMjL4z//8TwB++tOfkpKSwr/+67+ycuVKli1bxvbt2zlz5gyvvfbazN6MiIjIPKIYLnJxSZvpAYjIxWfFihWkpPz+eVxJSQn19fWDX6empuJ2u2lvbwdg165dHDt2DIfDcd51wuEwx48fn55Bi4iIiGK4yEVGCbeIDJGenn7e1zabbdjXLMsCwLIs1q9fz3/8x38MuVZRUdHUDVRERETOoxgucnFRwi0iF2zdunU88cQTFBcXk5eXN9PDERERkXFSDBeZWtrDLSIX7K677qKwsJCbbrqJ3/3ud5w8eZLXX3+db33rWzQ1Nc308ERERGQEiuEiU0sJt4hcsOzsbN544w2qq6u55ZZbWLZsGV/5ylcIhUJ6Wi4iInIRUwwXmVo2Y4yZ6UGIiIiIiIiIzDVa4RYRERERERGZAkq4RURERERERKaAEm4RERERERGRKaCEW0RERERERGQKKOEWERERERERmQJKuEVERERERESmgBJuERERERERkSmghFtERERERERkCijhFhEREREREZkCSrhFREREREREpoASbhEREREREZEpoIRbREREREREZAr8f8lDKnAFCkkRAAAAAElFTkSuQmCC",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "visualize_fit(t, x, y, xe, ye, x_model, y_model, xe_model, ye_model, mm.name, t_test)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "98d3e2c4",
+ "metadata": {},
+ "source": [
+ "## 1.2. Example: Acceleration Model Fit"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ede486e5",
+ "metadata": {},
+ "source": [
+ "Upon further inspection, acceleration model seems to be a better representation of the data"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "id": "0a0d9d1f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mm = Acceleration()\n",
+ "params, param_errs = mm.fit(t, x, y, xe, ye)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "b3d63417",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "x_model, y_model, xe_model, ye_model = mm.model(t_test, params, param_errs)\n",
+ "visualize_fit(t, x, y, xe, ye, x_model, y_model, xe_model, ye_model, mm.name, t_test)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9d1f63b4",
+ "metadata": {},
+ "source": [
+ "Moreover, `MotionModel.model` is fully vectorized, and can infer positions of multiple stars at multiple times, and the resulting inferred positions has shape (N_stars, N_times). See the example below:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "d1e406c5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "t = np.array([0, 1., 2.2, 3.5, 5.]) + 2025.0\n",
+ "\n",
+ "xs = np.array([\n",
+ " [0., 0.5, 2.1, 3.2, 8.0],\n",
+ " [10.0, 8.9, 9.2, 7.4, 7.0],\n",
+ " [2.5, 6.2, 5.2, 3.2, 5.0]\n",
+ "])\n",
+ "\n",
+ "ys = np.array([\n",
+ " [10.2, 8.5, 9.1, 10.5, 13.0],\n",
+ " [8.0, 9.9, 8.2, 7.4, 7.0],\n",
+ " [5.2, 6.2, 4.7, 3.2, 6.0]\n",
+ "])\n",
+ "\n",
+ "xes = np.array([\n",
+ " [0.2, 0.5, 0.3, 0.4, 0.6],\n",
+ " [0.5, 0.2, 0.7, 0.3, 0.2],\n",
+ " [0.5, 0.7, 0.6, 0.4, 0.3]\n",
+ "])\n",
+ "\n",
+ "yes = np.array([\n",
+ " [0.3, 0.2, 0.5, 0.2, 0.4],\n",
+ " [0.2, 0.5, 0.6, 0.4, 0.2],\n",
+ " [0.4, 0.2, 0.3, 0.4, 0.5]\n",
+ "])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "4adebbe8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "params = []\n",
+ "param_errs = []\n",
+ "for xi, yi, xei, yei in zip(xs, ys, xes, yes):\n",
+ " p, pe = mm.fit(t, xi, yi, xei, yei)\n",
+ " params.append(p)\n",
+ " param_errs.append(pe)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4e0424df",
+ "metadata": {},
+ "source": [
+ "Once we have the params and param errors, we can infer the model positions at any given time."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "95745baa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x_model, y_model, xe_model, ye_model = mm.model(t_test, params, param_errs)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "06fdca50",
+ "metadata": {},
+ "source": [
+ "The inferred positions should have shape (N_stars, N_times):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "id": "54206834",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(3, 100)"
+ ]
+ },
+ "execution_count": 32,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "x_model.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "id": "e6a4e42e",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAA9wAAAHqCAYAAAD27EaEAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3XecXHW9+P/Xmd52ZnvNtvRKQoAAAYRQpIMKNq7S1J+K9ypyVVC/V0G9NBU7cPUioBQbiCgXFKQJBJIQAul1s5tsb9P7zPn98ZnZkuwms8nW7Pv5eJzH7sycmflMZrJn3uf9+bzfmq7rOkIIIYQQQgghhBhVhokegBBCCCGEEEIIcSySgFsIIYQQQgghhBgDEnALIYQQQgghhBBjQAJuIYQQQgghhBBiDEjALYQQQgghhBBCjAEJuIUQQgghhBBCiDEgAbcQQgghhBBCCDEGJOAWQgghhBBCCCHGgATcQgghhBBCCCHEGJCAW4y5n/70p2iaxuLFiyd6KH3OOusszjrrrAl7/scee4wf//jHQ96maRq33nrruI4H4KGHHkLTNDRN4+WXXz7odl3XmT17NpqmHfG/3e23385TTz110PUvv/zysM871q699lo0TSMvL49gMHjQ7Y2NjRgMhlF/X47mNWffq7179+a031DbV77yFfbu3YumaTz00EN993njjTe49dZb8Xq9Ix6XEGJqk+P1weR4PZgcr0dGjtcCJOAW4+DXv/41AJs3b+att96a4NFMDoc6gK9evZpPf/rT4zugAfLy8njggQcOuv6VV15h9+7d5OXlHfFjD3cAX758OatXr2b58uVH/NhHw2w2k0wm+f3vf3/QbQ8++OBRvebJ4MEHH2T16tWDti9+8YtUVFSwevVqLr744r5933jjDW677TY5gAsxDcnx+mByvB5MjtdjS47XxyYJuMWYWrduHe+++27fH4ihDgzHgkgkMmqPdcoppzBjxoxRe7yR+uhHP8oTTzyB3+8fdP0DDzzAqaeeSk1Nzag/p9vt5pRTTsHtdo/6Y+fCYrHwgQ98oO/LZpau6zz00EN89KMfnZBxjZbFixdzyimnDNpqamqwWq2ccsoplJSUTPQQhRATTI7XIyfH6/Enx2s5Xk9FEnCLMZU9YN95552sXLmS3/3ud4TD4YP2a25u5v/7//4/qqursVgsVFZWcuWVV9Le3t63j9fr5T//8z+ZOXMmVquV0tJSLrroIrZt29a3Tzwe53vf+x7z58/HarVSUlLCddddR2dn52HHmut96+rquOSSS3jyySc5/vjjsdls3HbbbQD84he/4H3vex+lpaU4nU6WLFnC3XffTSKR6Lv/WWedxTPPPENjY+OgKUNZQ02F2rRpE5dffjkFBQXYbDaWLVvGww8/PGif7JSnxx9/nG9+85tUVlbidrs599xz2b59+2Fff9bHP/5xAB5//PG+63w+H0888QTXX3/9kPfp6enhhhtuoKqqCovFwsyZM/nmN79JLBYb9LpCoRAPP/xw32vOTnUbbrrW008/zamnnorD4SAvL4/zzjuP1atXD9rn1ltvRdM0Nm/ezMc//nE8Hg9lZWVcf/31+Hy+nF/39ddfzxtvvDHo3+qFF16gsbGR6667bsj75PK+AGzbto0LLrgAh8NBcXExn/vc5wgEAkM+5gsvvMA555yD2+3G4XBw2mmn8c9//jPn1zESB05Ru/XWW/nqV78KQH19/SGnLAohji1yvJbj9cDXJcdrOV6L0SMBtxgzkUiExx9/nJNOOonFixdz/fXXEwgE+OMf/zhov+bmZk466ST+/Oc/c9NNN/Hss8/y4x//GI/HQ29vLwCBQIDTTz+d//mf/+G6667jr3/9K/fffz9z586ltbUVgHQ6zeWXX86dd97JVVddxTPPPMOdd97J888/z1lnnXXIs9ojve/69ev56le/yhe/+EWee+45rrjiCgB2797NVVddxW9/+1v+9re/8alPfYrvf//7fPazn+2777333stpp51GeXn5oClDw9m+fTsrV65k8+bN/PSnP+XJJ59k4cKFXHvttdx9990H7f+Nb3yDxsZG/vd//5df/vKX7Ny5k0svvZRUKnWYd0xxu91ceeWVg84eP/744xgMhiHPHEejUVatWsVvfvMbbrrpJp555hk+8YlPcPfdd/OhD32ob7/Vq1djt9u56KKL+l7zvffeO+w4HnvsMS6//HLcbjePP/44DzzwAL29vZx11lm89tprB+1/xRVXMHfuXJ544gluueUWHnvsMb785S/n9JoBzj33XGprawe97gceeID3ve99zJkz56D9c31f2tvbOfPMM9m0aRP33nsvv/3tbwkGg/z7v//7QY/5yCOP8P73vx+3283DDz/MH/7wBwoLCzn//POP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p7xXb28vbrvtNiSTSaTTadx88804fPhwc0+YiIhogWKdTbSwMXAT0bQ9//zzOH78OF566SU88sgjePDBB3HTTTchmUziF7/4Be666y7cddddOHr0KACgUqng3e9+NyKRCF566SW8/PLLiEQiuOGGG6Dr+hyfDRER0fmLdTbR/MDATUTTlkql8A//8A9YvXo1Pv7xj2P16tWoVCr43Oc+h1WrVuH++++Hz+fDf//3fwMAnnjiCciyjG9961u46KKLsHbtWmzZsgVHjhzBiy++OLcnQ0REdB5jnU00P3jm+gCIaOFYt24dZHniOl02m8X69evdnxVFQTqdxuDgIABgx44d2L9/P6LR6JT9qKqKAwcONOegiYiIFiHW2UTzAwM3EU2b1+ud8rMkSafcZts2AMC2bWzcuBH/8i//ctK+WltbG3egREREixzrbKL5gYGbiBrm0ksvxZNPPolMJoNYLDbXh0NERESnwTqbqDE4hpuIGub2229HS0sLbr75ZvzsZz/DoUOHsHXrVtxzzz04duzYXB8eERERjWOdTdQYDNxE1DChUAgvvfQSlixZgltuuQVr167Fxz/+cVSrVV49JyIimkdYZxM1hiSEEHN9EERERERERETnG7ZwExERERERETUAAzcRERERERFRAzBwExERERERETUAAzcRERERERFRAzBwExERERERETUAAzcRERERERFRAzBwExERERERETUAAzcRERERERFRAzBwExERERERETUAAzcRERERERFRAzBwExERERERETUAAzcRERERERFRA/z/gqHPx4dTtRIAAAAASUVORK5CYII=",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "visualize_fit(t, xs, ys, xes, yes, x_model, y_model, xe_model, ye_model, mm.name, t_test)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f7ae3e7f",
+ "metadata": {},
+ "source": [
+ "## 1.3. Example: Parallax Model Fit"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "08eceab5",
+ "metadata": {},
+ "source": [
+ "Parallax model requires some fixed parameters: `ra`, `dec`, `pa`, `obsLocation`, and `t0`.\n",
+ "- `ra` and `dec` are required parameters. \n",
+ "- `pa = 0` by default\n",
+ "- `obsLocation = 'earth'` by default\n",
+ "- `t0 = np.average(t, 1./np.hypot(xe, ye))` by default\n",
+ "\n",
+ "We need to provide the fixed parameters in the `fixed_params_dict`:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "018fc13a",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"dtf2d\" yielded 1 of \"dubious year (Note 6)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"dtf2d\" yielded 2 of \"dubious year (Note 6)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"utctai\" yielded 2 of \"dubious year (Note 3)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"utctai\" yielded 1 of \"dubious year (Note 3)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"taiutc\" yielded 1 of \"dubious year (Note 4)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n"
+ ]
+ }
+ ],
+ "source": [
+ "mm = Parallax()\n",
+ "fixed_params_dict = {'ra': 0., 'dec': 10., 'pa': 0., 'obsLocation': 'earth'}\n",
+ "params, param_errs = mm.fit(t, x, y, xe, ye, fixed_params_dict)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "id": "73dafb1f",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"dtf2d\" yielded 20 of \"dubious year (Note 6)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"dtf2d\" yielded 40 of \"dubious year (Note 6)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"utctai\" yielded 40 of \"dubious year (Note 3)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"utctai\" yielded 20 of \"dubious year (Note 3)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"taiutc\" yielded 20 of \"dubious year (Note 4)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAA9wAAAHqCAYAAAD27EaEAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAA8XlJREFUeJzs3Xd8W+W9+PHP0R625b0Sx3Z2QhgJAZKwEigbSqEUKC2zgwu9pS2dtOVCSi+U3tsyyuivLRAobQIUSmm5UEYgrIQsErLjeO8ha2/pnN8fJiYmdmInkiU73/cLvYiOjo6+smU953ue5/k+iqZpGkIIIYQQQgghhEgqXboDEEIIIYQQQgghxiNJuIUQQgghhBBCiBSQhFsIIYQQQgghhEgBSbiFEEIIIYQQQogUkIRbCCGEEEIIIYRIAUm4hRBCCCGEEEKIFJCEWwghhBBCCCGESAFJuIUQQgghhBBCiBSQhFsIIYQQQgghhEgBSbhFxlq2bBmKovTfDAYDEydO5Prrr6e1tTUtMV133XVUVVUN2FZVVcV111036rEsXrwYRVGYPHkymqbt9/g777zT/7NbtmzZiI+/fft27rzzThoaGvZ7bLCfw2jZ+56G+pn/4he/6N9nsNgP1eG858WLF7N48eJh7bfvZ37f29atW7nzzjtRFGXAcx555JFD+v0KIUSqSTt+YNKOXzfo49KOi/FGEm6R8Z544glWr17N66+/zje+8Q2WL1/OqaeeSiAQSHdoaZednU19fT0rV67c77HHH3+cnJycQz729u3bWbp06aCN3e23387f//73Qz724crOzua5557D5/MN2K5pGsuWLTus951ukydPZvXq1fvdpkyZwte//nVWr149YH9pqIUQmU7a8aFJOy7tuLTj458k3CLjzZkzhwULFrBkyRLuuOMOfvSjH1FfX8+LL7542McOhUKHH2AaTZo0iQULFvD4448P2O7z+Xjuuee44oorUvK6U6ZMYe7cuSk59nBcfPHFaJrGihUrBmxfuXIl9fX1KXvfo8FqtbJgwYL9blarlYkTJ7JgwYJ0hyiEECMi7fjQpB2XdlyMf5JwizFn7xdVY2MjAEuXLuWkk04iPz+fnJwc5s2bx2OPPbbf8KyqqiouvPBCXnjhBebOnYvFYmHp0qUAPPzww5x22mkUFxdjt9s5+uij+fWvf00sFhtxfOFwmO9///scd9xxOBwO8vPzWbhwIf/4xz8G7LdixQoUReGhhx4asP2OO+5Ar9fz+uuvD+v1brjhBl544QXcbveAYwNceeWVgz7nvffe48wzzyQ7OxubzcaiRYt4+eWX+x9ftmwZX/rSlwBYsmTJfkPaBhuWFQ6Hue2226iursZkMjFhwgS+9a1vDYgLPv09vPrqq8ybNw+r1crMmTP3O9k4EIfDwSWXXLLfcx5//HFOPvlkpk+fPujzHn/8cY499lgsFgv5+flccskl7NixY7/9li1bxowZMzCbzcyaNYunnnpq0ONFo1F++ctfMnPmTMxmM0VFRVx//fV0d3cP+72MxGeHolVVVbFt2zZWrVrV/ztK1xBBIYQYLmnHB5J2/FPSjks7Ph4Z0h2AECO1Z88eAIqKigBoaGjgxhtvZNKkSQCsWbOGb3/727S2tvJf//VfA567ceNGduzYwc9//nOqq6ux2+0A1NbWctVVV/U3Mps3b+a///u/2blz54gaEIBIJEJvby8/+MEPmDBhAtFolDfeeINLL72UJ554gmuuuQboa0RXrVrF97//fRYsWMD8+fNZuXIlv/zlL/npT3/KWWedNazXu/LKK/ne977H8uXLuemmmwB47LHHuOyyywYdkrVq1SrOOussjjnmGB577DHMZjOPPPIIF110EcuXL+eKK67gggsu4O677+anP/0pDz/8MPPmzQP6rogPRtM0vvCFL/Dmm29y2223ceqpp/Lxxx9zxx139A+lMpvN/ftv3ryZ73//+/zkJz+hpKSEP/3pT3zta19j6tSpnHbaacN631/72tc488wz2bFjB7NmzcLtdvPCCy/wyCOP4HQ699v/nnvu4ac//Slf/vKXueeee3A6ndx5550sXLiQdevWMW3aNKCvkb7++uu5+OKL+c1vfoPH4+HOO+8kEomg0316jVJVVS6++GLeffddfvSjH7Fo0SIaGxu54447WLx4MevXr8dqtQ7rvXxWPB4fcF+n0w147b3+/ve/c9lll+FwOHjkkUcABvychRAiE0k7PpC049KOSzs+zmlCZKgnnnhCA7Q1a9ZosVhM8/l82r/+9S+tqKhIy87O1jo6OvZ7TiKR0GKxmPaLX/xCKygo0FRV7X+ssrJS0+v12q5duw74unuP8dRTT2l6vV7r7e3tf+zaa6/VKisrB+xfWVmpXXvttUMeLx6Pa7FYTPva176mzZ07d8Bj4XBYmzt3rlZdXa1t375dKykp0U4//XQtHo8fMEZN07TTTz9dO+qoo/rjmj9/vqZpmrZt2zYN0N5++21t3bp1GqA98cQT/c9bsGCBVlxcrPl8vgExzpkzR5s4cWL/z+y5557TAO2tt97a77U/+3N49dVXNUD79a9/PWC/Z555RgO0P/zhD/3bKisrNYvFojU2NvZvC4VCWn5+vnbjjTce9H0D2re+9S1NVVWturpa+8EPfqBpmqY9/PDDWlZWlubz+bT/+Z//0QCtvr5e0zRNc7lcmtVq1c4///wBx2pqatLMZrN21VVXaZrW97svLy/X5s2bN+Cz09DQoBmNxgHvefny5RqgPf/88wOOufdn/sgjj/RvO/3007XTTz/9oO/t9NNP14D9bl/5ylc0TdO0O+64Q/vs1/ZRRx01rGMLIcRok3b8wKQdl3Zc06QdPxLIkHKR8RYsWIDRaCQ7O5sLL7yQ0tJSXnnlFUpKSoC++T6f+9zncDgc6PV6jEYj//Vf/4XT6aSrq2vAsY455phBhyl99NFHfP7zn6egoKD/GNdccw2JRILdu3ePOObnnnuOk08+maysLAwGA0ajkccee2y/YU9ms5lnn30Wp9PJvHnz0DSN5cuXo9frR/R6N9xwA+vXr2fLli089thjTJkyZdArzIFAgA8//JDLLruMrKys/u16vZ6rr76alpYWdu3aNeL3u7fYy2crjn7pS1/Cbrfz5ptvDth+3HHH9fdkAFgsFqZPn94/vHA49lY4/fOf/0w8Huexxx7j8ssvH/C+9lq9ejWhUGi/+CoqKjjjjDP649u1axdtbW1cddVVA4Z8VVZWsmjRogHP/de//kVubi4XXXQR8Xi8/3bcccdRWlrK22+/Pez3sq8pU6awbt26Abe77rrrkI4lhBCZQNrxg5N2XNpxMX5Jwi0y3lNPPcW6dev46KOPaGtr4+OPP+bkk08GYO3atZx99tkA/PGPf+T9999n3bp1/OxnPwP2L6ZSVla23/Gbmpo49dRTaW1t5YEHHuDdd99l3bp1PPzww4Me42BeeOEFLr/8ciZMmMDTTz/N6tWrWbduHTfccAPhcHi//adOncqpp55KOBzmK1/5yqAxHsxpp53GtGnT+H//7//x5z//mRtuuGG/ZScAXC4XmqYN+hrl5eUAgw7jOhin04nBYOgfHriXoiiUlpbud8yCgoL9jmE2m0f8s947z+ruu+9m48aNfO1rXxsyPhj8919eXt7/+N7/l5aW7rffZ7d1dnbidrsxmUwYjcYBt46ODnp6ekb0XvayWCzMnz9/wK26uvqQjiWEEJlA2vGDk3Zc2nExfskcbpHxZs2axfz58wd9bMWKFRiNRv71r39hsVj6tw9V+XSwxuvFF18kEAjwwgsvUFlZ2b9906ZNhxTv008/TXV1Nc8888yA14tEIoPu/6c//YmXX36ZE088kYceeogrrriCk046acSve/311/Pzn/8cRVG49tprB90nLy8PnU5He3v7fo+1tbUBUFhYOOLXLigoIB6P093dPaCx1jSNjo4OTjjhhBEfczgqKir43Oc+x9KlS5kxY8Z+V6/3jQ8Y8n3vfc979+vo6Nhvv89uKywspKCggFdffXXQ18zOzh7+GxFCiHFM2vHhkXZc2nExPkkPtxjTFEXBYDAMGLoVCoX485//PKJjwMAiFZqm8cc//vGQYzKZTAMa6Y6Ojv2qmwJs2bKFW265hWuuuYZ3332XY445hiuuuAKXyzXi17322mu56KKL+OEPf8iECRMG3cdut3PSSSfxwgsvDLgKraoqTz/9NBMnTuwfqrf35zGcq9Vnnnkm0HeSsq/nn3+eQCDQ/3gqfP/73+eiiy7i9ttvH3KfhQsXYrVa94uvpaWFlStX9sc3Y8YMysrKWL58+YDquI2NjXzwwQcDnnvhhRfidDpJJBL7XcmeP38+M2bMSOK7HNqh9CgIIUSmkHb8U9KOSzsuxifp4RZj2gUXXMBvf/tbrrrqKr75zW/idDr53//93xFVeDzrrLMwmUx8+ctf5kc/+hHhcJhHH330kBpLoH/JkptvvpnLLruM5uZm7rrrLsrKyqipqenfLxAIcPnll1NdXc0jjzyCyWTi2WefZd68eVx//fUjXp+0vLx8WM+55557OOuss1iyZAk/+MEPMJlMPPLII2zdupXly5f3n2DMmTMHgD/84Q9kZ2djsViorq4edBjZWWedxTnnnMOPf/xjvF4vJ598cn9107lz53L11VeP6L2MxNlnn90/HHEoubm53H777fz0pz/lmmuu4ctf/jJOp5OlS5disVi44447gL4qonfddRdf//rXueSSS/jGN76B2+3mzjvv3G8o2pVXXslf/vIX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2nAhhBi/JOFOgoSqsfSf2xls0NnebUv/uX1Uhpfv64wzzuDYY4/lhRdeAECn0/Hggw+ydetWnnzySVauXMmPfvQjABYtWsT9999PTk4O7e3ttLe384Mf/ADoO5G666672Lx5My+++CL19fVcd911o/pehBBCjI5vfetbPP300/z1r38lOzubjo4OOjo6CIVCQN+w8O9+97vcfffd/P3vf2fr1q1cd9112Gw2rrrqqv7jXHPNNdx2223997/zne/w2muvce+997Jz507uvfde3njjDb773e+O9lvcTya249KGCyHE+CBF05JgbX0v7Z7wkI9rQLsnzNr6XhZOKRi9wICZM2fy8ccfAww4qamuruauu+7ipptu4pFHHsFkMuFwOFAUpX+44F433HBD/78nT57Mgw8+yIknnojf7ycrK2tU3ocQQmQCdzCKxajHYtSnO5SUefTRRwFYvHjxgO1PPPFEf6L2ox/9iFAoxM0334zL5eKkk07itddeIzs7u3//pqYmdLpPr+svWrSIFStW8POf/5zbb7+dKVOm8Mwzz3DSSSel/D0dTKa249KGCyFE8miaRm8gSp7NhE534JojySQJdxJ0+YZupA9lv2TatyDNW2+9xd1338327dvxer3E43HC4TCBQAC73T7kMT766CPuvPNONm3aRG9vb38Rl6amJmbPnj0q70MIIdKpNxBld6ePhp4A8yrzmF6SffAnjVGadvBe3L1DlvcOWx7M22+/vd+2yy67jMsuu+wwokuNTG3HpQ0XQojkCETibG310OIKcur0IoqzLaP22jKkPAmG+wsbzV/sXjt27KC6uprGxkbOP/985syZw/PPP8+GDRt4+OGHAYjFYkM+PxAIcPbZZ5OVlcXTTz/NunXr+Pvf/w70DVMTQojxzBeOsbbOyStb29nc7KY3EEUdRkIqxpZMbcelDRdCiMOjaRoNPQFe29bJxiYX7lCM0W7GpYc7CU6szqfMYaHDEx50/pcClDosnFidP6pxrVy5ki1btvC9732P9evXE4/H+c1vftM/xO/ZZ58dsL/JZCKRSAzYtnPnTnp6evjVr37VvxzL+vXrR+cNCCFEGiVUjQ/re9nT5acoy0xJkYX6Hn+6wxIpkIntuLThQghxeHoDUXa0ednV6cOgU6gqsNPmCY16HNLDnQR6ncIdF/UNy/rsbIC99++4aDb6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HE6gpdyOpTVuaDSct01ERJPHgLuEzKtwoNpz4tTyjKIiLSuYW26HXst/YiIioolIy+posB20Y1WDFyY9520TEdHUMBorIUadFourXdBrNQglMsfcRlUFukYSqHRbUM3RbSIioglJyyo6huOYU8Zgm4iIcocBd4mpcJmxoMKJgWgKg9EUVCHGfpbMKGgbjCFgN2J5nZuj20RERCegCoH+SAqdw3HMCdixupHBNhER5Y6u2A2g7C2odEAjATsPRdA2EIPbYgAAjCQymFdux7JaD6xG/tMSEREdj6yIsX70lGY/mgI2FholIqKcYlRWgow6LRbXuNEYsGFvXxS7DkWgqAJrG72YW+6AlgVeiIiIjkuSALfVgHqfFfMqHHCY9MVuEhERzUAMuEuY3aTHkho3mgI2ZBQBj9VQ7CYRERGVhCq3BS6LAT6usU1ERHnEgHsGsPOuPBERUVZMei3nahMRUd5xohIRERERERFRHjDgJiIiIiIiIsoDBtxEREREREREecCAm4iIiIiIiCgPGHATERERERER5QEDbiIiIiIiIqI8YMBNRERERERElAcMuImIiIiIiIjygAE3ERERERERUR4w4CYiIiIiIiLKAwbcRERERERERHnAgJuIiIiIiIgoDxhwExEREREREeUBA24iIiIiIiKiPGDATURERERERJQHumI3oJCEEACAcDhc5JYQEdFsd7gvOtw30YmxHycioukgmz58VgXckUgEAFBdXV3klhAREY2KRCJwOp3FbkZJYD9ORETTyUT6cEnMolvrqqqiu7sbdrsdkiRNaV/hcBjV1dU4ePAgHA5Hjlo4c/F8ZY/nLDs8X9njOctOrs+XEAKRSAQVFRXQaDjDayLYjxcPz1f2eM6yw/OVPZ6z7OTyfGXTh8+qEW6NRoOqqqqc7tPhcPALngWer+zxnGWH5yt7PGfZyeX54sh2dtiPFx/PV/Z4zrLD85U9nrPs5Op8TbQP5y11IiIiIiIiojxgwE1ERERERESUBwy4J8loNOLb3/42jEZjsZtSEni+ssdzlh2er+zxnGWH52tm4b9ndni+ssdzlh2er+zxnGWnWOdrVhVNIyIiIiIiIioUjnATERERERER5QEDbiIiIiIiIqI8YMBNRERERERElAezNuC++eabsWLFCtjtdgQCAXz0ox/Frl27jthGCIEbb7wRFRUVMJvN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/x5PP/30UV+2+vp6BINBbNiwYey1dDqNjRs3Ys2aNWOvhcNhnH322TAYDHj00UdhMplO+Nnbtm0D8F6nVCoKdc6WLVsGo9F4RJn/TCaDAwcOoLa2Nk9Hl3uF/o4JIXDffffhsssuO+HF4nRVqHMWj8cB4Ii5TIefHx6dKQXF+DtWVlYGm82Ghx9+GCaTCWeddVbuDyyPcnXOxtt3KpUCAKxevRqhUAivvPLK2M9ffvllhEKhE+6HJob9eHbYh2eP/Xh22Idnj/14dkq2D8+6zNoM8eUvf1k4nU7x7LPPHrEMQzweH9vmlltuEU6nU/z+978X27dvF5/61KeOKCsfDofFypUrxcKFC8XevXuP2M/hsvIvvfSSuPXWW8W2bdvE/v37xcMPPywqKirERz7ykaIc91QU6pwJIcQ111wjKisrxRNPPCF27twpvvCFL4hAICCGhoYKftyTVcjzJYQQTz31lAAg3n777YIeZy4V6pz19/cLr9crLrroIvH666+LXbt2ia9//etCr9eL119/vSjHPhmF/I795Cc/EVu2bBG7du0St99+uzCbzeJHP/pRwY95qnJxzvbt2yduuukm8dprr4n29nbx0ksviQsvvFB4PB5x6NChsf2ce+65YtGiRWLTpk1i06ZNYuHChVwWLIfYj2eHfXj22I9nh3149tiPZ6dU+/BZG3ADOObjvvvuG9tGVVXx7W9/WwSDQWE0GsW6devE9u3bx37+zDPPjLuftrY2IYQQW7ZsEStXrhROp1OYTCbR0tIivv3tb4tYLFbgI566Qp0zIUaXxPja174mAoGAsNvt4swzzxQ7duwo4NFOXSHPlxBCfOpTnxJr1qwp0NHlRyHP2auvvirOPvts4fF4hN1uF6tWrRKPPfZYAY926gp5vi699FLh8XiEwWAQixYtEg8++GABjzR3cnHOurq6xHnnnScCgYDQ6/WiqqpKfPrTnz5qqZDBwUHxmc98RtjtdmG328VnPvMZMTw8XKAjnfnYj2eHfXj22I9nh3149tiPZ6dU+3Dp3cYTERERERERUQ7N2jncRERERERERPnEgJuIiIiIiIgoDxhwExEREREREeUBA24iIiIiIiKiPGDATURERERERJQHDLiJiIiIiIiI8oABNxEREREREVEeMOAmIiIiIiIiygMG3ER0lBtvvBGLFy8udjOIiIhoEtiPE00fkhBCFLsRRFQ4kiQd9+ef/exncfvttyOVSsHr9RaoVURERDQR7MeJSgsDbqJZpre3d+z/H374YXzrW9/Crl27xl4zm81wOp3FaBoRERGdAPtxotLClHKiWSYYDI49nE4nJEk66rUPpqJ97nOfw0c/+lHcdNNNKCsrg8vlwne+8x3Isox/+qd/gsfjQVVVFX7+858f8VldXV345Cc/CbfbDa/XiwsvvBAHDhwo7AETERHNIOzHiUoLA24impCnn34a3d3deO6553DrrbfixhtvxAUXXAC3242XX34ZV1xxBa644gocPHgQABCPx3H66afDZrPhueeewwsvvACbzYZzzz0X6XS6yEdDREQ0u7AfJyoOBtxENCEejwc//vGP0dLSgs9//vNoaWlBPB7HP//zP6O5uRk33HADDAYDXnzxRQDAQw89BI1Gg3vuuQcLFy7EvHnzcN9996GjowPPPvtscQ+GiIholmE/TlQcumI3gIhKw4IFC6DRvHePrqysDK2trWPPtVotvF4v+vr6AABbtmzB3r17Ybfbj9hPMpnEvn37CtNoIiIiAsB+nKhYGHAT0YTo9fojnkuSdMzXVFUFAKiqimXLluF//ud/jtqX3+/PX0OJiIjoKOzHiYqDATcR5cXSpUvx8MMPIxAIwOFwFLs5RERElAX240S5wTncRJQXn/nMZ+Dz+XDhhRfi+eefR1tbGzZu3IhrrrkGnZ2dxW4eERERHQf7caLcYMBNRHlhsVjw3HPPoaamBhdddBHmzZuHz3/+80gkErxTTkRENM2xHyfKDUkIIYrdCCIiIiIiIqKZhiPcRERERERERHnAgJuIiIiIiIgoDxhwExEREREREeUBA24iIiIiIiKiPGDATURERERERJQHDLiJiIiIiIiI8oABNxEREREREVEeMOAmIiIiIiIiygMG3ERERERERER5wICbiIiIiIiIKA8YcBMRERERERHlAQNuIiIiIiIiojz4/3lQGxRIhH3EAAAAAElFTkSuQmCC",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "x_model, y_model, xe_model, ye_model = mm.model(t_test, params, param_errs)\n",
+ "visualize_fit(t, x, y, xe, ye, x_model, y_model, xe_model, ye_model, mm.name, t_test)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5be8fb7e",
+ "metadata": {},
+ "source": [
+ "# 2. Fit Motion Model in StarTable"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3bd8dec7",
+ "metadata": {},
+ "source": [
+ "Examples on `flystar.StarTable.fit_motion_model`. Prepare the data with invalid values:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "id": "aa698e86",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "t = np.array([0, 1., 2.2, 3.5, 5.]) + 2025.0\n",
+ "\n",
+ "x = np.array([\n",
+ " [0., 0.5, 2.1, 3.2, 8.0], # Increasing 5 Epochs\n",
+ " [10.0, 8.9, 9.2, 7.4, 7.0], # Decreasing 5 Epochs\n",
+ " [2.5, np.nan, 5.2, np.nan, 5.0], # 3 Epochs\n",
+ " [np.nan, 6.2, np.nan, np.nan, 9.2], # 2 Epochs\n",
+ " [np.nan, 2.0, np.nan, np.nan, np.nan], # 1 Epoch\n",
+ " [np.nan, np.nan, np.nan, np.nan, np.nan] # All NaNs\n",
+ "])\n",
+ "\n",
+ "y = np.array([\n",
+ " [10.2, 8.5, 9.1, 10.5, 13.0], # Increasing 5 Epochs\n",
+ " [8.0, 9.9, 8.2, 7.4, 7.0], # Decreasing 5 Epochs\n",
+ " [5.2, np.nan, 4.7, np.nan, 6.0], # 3 Epochs\n",
+ " [np.nan, 1.2, np.nan, np.nan, 3.2], # 2 Epochs\n",
+ " [np.nan, 2.0, np.nan, np.nan, np.nan], # 1 Epoch\n",
+ " [np.nan, np.nan, np.nan, np.nan, np.nan] # All NaNs\n",
+ "])\n",
+ "\n",
+ "xe = np.array([\n",
+ " [0.2, 0.5, 0.3, 0.4, 0.6],\n",
+ " [0.5, 0.2, 0.7, 0.3, 0.2],\n",
+ " [0.5, np.nan, 0.6, np.nan, 0.3],\n",
+ " [np.nan, 0.6, np.nan, np.nan, 0.3],\n",
+ " [np.nan, 0.4, np.nan, np.nan, np.nan],\n",
+ " [np.nan, np.nan, np.nan, np.nan, np.nan]\n",
+ "])\n",
+ "\n",
+ "ye = np.array([\n",
+ " [0.3, 0.2, 0.5, 0.2, 0.4],\n",
+ " [0.2, 0.5, 0.6, 0.4, 0.2],\n",
+ " [0.7, np.nan, 0.5, np.nan, 0.2],\n",
+ " [np.nan, 0.4, np.nan, np.nan, 0.5],\n",
+ " [np.nan, 0.5, np.nan, np.nan, np.nan],\n",
+ " [np.nan, np.nan, np.nan, np.nan, np.nan]\n",
+ "])\n",
+ "\n",
+ "x = np.ma.masked_invalid(x)\n",
+ "y = np.ma.masked_invalid(y)\n",
+ "xe = np.ma.masked_invalid(xe)\n",
+ "ye = np.ma.masked_invalid(ye)\n",
+ "mask = np.ma.getmaskarray(x) | np.ma.getmaskarray(y) | np.ma.getmaskarray(xe) | np.ma.getmaskarray(ye)\n",
+ "\n",
+ "tab = StarTable({\n",
+ " 'x': x,\n",
+ " 'y': y,\n",
+ " 'xe': xe,\n",
+ " 'ye': ye\n",
+ "})\n",
+ "tab.meta['list_times'] = t"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9201897f",
+ "metadata": {},
+ "source": [
+ "There are a 2 ways to specify the desired motion models:\n",
+ "1. Let MotionModel automatically determine which motion model to use among the given `motion_models` list based on the number of valid observations. MotionModel will choose the motion model that has enough observations, i.e. $n_\\text{fit} \\geq n_\\text{params}$. \n",
+ "2. Specify a motion model for each star in the `motion_model_input` column. In case there is not enough observations, MotionModel will \"downgrade\" to a model with less parameters until $n_\\text{fit} \\geq n_\\text{params}$ among all the unique motion models specified in the column.\n",
+ "\n",
+ "Note that when `absolute_sigma=False` and `n_fit == n_params`, we don't have enough degree of freedom to rescale the uncertainties, so the uncertainties will be set to infinity -- the same behavior as `scipy.optimize.curve_fit`.
By default `motion_models = [Empty, Fixed, Linear]`. `Empty` and `Fixed` will always be added in the list to handle 0 and 1 point cases. See examples below for details. Let's start with the most basic usage."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e58f429d",
+ "metadata": {},
+ "source": [
+ "## 2.1. Example: Default Fitting"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 37,
+ "id": "02642d3b",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Fitting motion model Empty: 0%| | 0/1 [00:00, ?it/s]/Users/weilingfeng/Academic/Software/flystar/flystar/motion_model.py:119: OptimizeWarning: Empty data cannot be fit. Setting parameters to nan and uncertainties to np.inf.\n",
+ " fit_result = self.run_fit(\n",
+ "Fitting motion model Empty: 100%|██████████| 1/1 [00:00<00:00, 1157.37it/s]\n",
+ "Fitting motion model Fixed: 0%| | 0/1 [00:00, ?it/s]/Users/weilingfeng/Academic/Software/flystar/flystar/motion_model.py:404: UserWarning: Fixed model has no non-scipy fitter option. Running with scipy.\n",
+ " warnings.warn(\"Fixed model has no non-scipy fitter option. Running with scipy.\")\n",
+ "Fitting motion model Fixed: 100%|██████████| 1/1 [00:00<00:00, 3256.45it/s]\n",
+ "Fitting motion model Linear: 100%|██████████| 4/4 [00:00<00:00, 7040.38it/s]\n"
+ ]
+ }
+ ],
+ "source": [
+ "tab.fit_motion_model()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "81059189",
+ "metadata": {},
+ "source": [
+ "Since we do not specify the `motion_models` parameter in the `fit_motion_model` function, the default motion model of `Empty`, `Fixed` and `Linear` will be used. The function automatically determines which motion models among the three to use based on the number of valid observations, i.e., $n_\\text{fit} \\geq n_\\text{params}$:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "id": "a7573e51",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "StarTable length=6\n",
+ "
\n",
+ "| n_fit | n_required | motion_model_used |
\n",
+ "| int64 | int64 | str20 |
\n",
+ "| 5 | 2 | Linear |
\n",
+ "| 5 | 2 | Linear |
\n",
+ "| 3 | 2 | Linear |
\n",
+ "| 2 | 2 | Linear |
\n",
+ "| 1 | 2 | Fixed |
\n",
+ "| 0 | 2 | Empty |
\n",
+ "
"
+ ],
+ "text/plain": [
+ "\n",
+ "n_fit n_required motion_model_used\n",
+ "int64 int64 str20 \n",
+ "----- ---------- -----------------\n",
+ " 5 2 Linear\n",
+ " 5 2 Linear\n",
+ " 3 2 Linear\n",
+ " 2 2 Linear\n",
+ " 1 2 Fixed\n",
+ " 0 2 Empty"
+ ]
+ },
+ "execution_count": 38,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tab['n_required'] = 2\n",
+ "tab[['n_fit', 'n_required', 'motion_model_used']]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "20470c6e",
+ "metadata": {},
+ "source": [
+ "Next, let's try `absolute_sigma=False`. As mentioned above, we don't have enough degree of freedom to rescale the uncertainties for the forth star. In this case, the parameter uncertainties will be set to infinity, which is the same behavior as `scipy.optimize.curve_fit`. The same `OptmizieWarning` as in `scipy` will be raised."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "26b11593",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Fitting motion model Empty: 0%| | 0/1 [00:00, ?it/s]/Users/weilingfeng/Academic/Software/flystar/flystar/motion_model.py:119: OptimizeWarning: Empty data cannot be fit. Setting parameters to nan and uncertainties to np.inf.\n",
+ " fit_result = self.run_fit(\n",
+ "Fitting motion model Empty: 100%|██████████| 1/1 [00:00<00:00, 4524.60it/s]\n",
+ "Fitting motion model Fixed: 0%| | 0/1 [00:00, ?it/s]/Users/weilingfeng/Academic/Software/flystar/flystar/motion_model.py:404: UserWarning: Fixed model has no non-scipy fitter option. Running with scipy.\n",
+ " warnings.warn(\"Fixed model has no non-scipy fitter option. Running with scipy.\")\n",
+ "/Users/weilingfeng/Academic/Software/flystar/flystar/motion_model.py:119: OptimizeWarning: Degree of freedom < 0. Covariance of the parameters could not be estimated. Setting parameter uncertainties to fill value np.inf.\n",
+ " fit_result = self.run_fit(\n",
+ "Fitting motion model Fixed: 100%|██████████| 1/1 [00:00<00:00, 710.30it/s]\n",
+ "Fitting motion model Linear: 100%|██████████| 4/4 [00:00<00:00, 4723.32it/s]\n"
+ ]
+ }
+ ],
+ "source": [
+ "tab.fit_motion_model(absolute_sigma=False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "a411e006",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "<Column name='vx_err' dtype='float64' length=6>\n",
+ "\n",
+ "| 0.2398025689409276 |
\n",
+ "| 0.07197698078673948 |
\n",
+ "| 0.26723109004421475 |
\n",
+ "| inf |
\n",
+ "| inf |
\n",
+ "| inf |
\n",
+ "
"
+ ],
+ "text/plain": [
+ "\n",
+ " 0.2398025689409276\n",
+ "0.07197698078673948\n",
+ "0.26723109004421475\n",
+ " inf\n",
+ " inf\n",
+ " inf"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tab['vx_err']"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "241ab6d6",
+ "metadata": {},
+ "source": [
+ "## 2.2. Example: Specify Motion Models"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "220922c5",
+ "metadata": {},
+ "source": [
+ "Alternatively, one can specify a list of motion models to use, and the function will also automatically determine which model to use for each star depending on the valid observed epochs. In the following example, we specify `Acceleration` model, but **the function will always implicitly add `Empty` and `Fixed`** to handle the 0 or 1 epoch stars."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "a596c8e8",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Fitting motion model Acceleration: 0%| | 0/3 [00:00, ?it/s]/Users/weilingfeng/Academic/Software/flystar/flystar/motion_model.py:785: UserWarning: Acceleration model has no non-scipy fitter option. Running with scipy.\n",
+ " warnings.warn(\"Acceleration model has no non-scipy fitter option. Running with scipy.\")\n",
+ "Fitting motion model Acceleration: 100%|██████████| 3/3 [00:00<00:00, 2933.08it/s]\n",
+ "Fitting motion model Empty: 100%|██████████| 1/1 [00:00<00:00, 15141.89it/s]\n",
+ "Fitting motion model Fixed: 100%|██████████| 2/2 [00:00<00:00, 10754.63it/s]\n"
+ ]
+ }
+ ],
+ "source": [
+ "tab.fit_motion_model(motion_models=['Acceleration'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "7d66e979",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "StarTable length=6\n",
+ "
\n",
+ "| n_fit | motion_model_used |
\n",
+ "| int64 | str20 |
\n",
+ "| 5 | Acceleration |
\n",
+ "| 5 | Acceleration |
\n",
+ "| 3 | Acceleration |
\n",
+ "| 2 | Fixed |
\n",
+ "| 1 | Fixed |
\n",
+ "| 0 | Empty |
\n",
+ "
"
+ ],
+ "text/plain": [
+ "\n",
+ "n_fit motion_model_used\n",
+ "int64 str20 \n",
+ "----- -----------------\n",
+ " 5 Acceleration\n",
+ " 5 Acceleration\n",
+ " 3 Acceleration\n",
+ " 2 Fixed\n",
+ " 1 Fixed\n",
+ " 0 Empty"
+ ]
+ },
+ "execution_count": 24,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tab[['n_fit', 'motion_model_used']]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "188290a9",
+ "metadata": {},
+ "source": [
+ "## 2.3. Example: Specify the `motion_model_input` Column"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "99624463",
+ "metadata": {},
+ "source": [
+ "One can also specify a motion model for each star as a column in the star table. However, the function will \"downgrade\" the model to one with fewer parameters until $n_\\text{fit} \\geq n_\\text{params}$:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "id": "04db5f9e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ra = np.zeros(len(x))\n",
+ "dec = np.zeros(len(x))\n",
+ "pa = np.zeros(len(x))\n",
+ "\n",
+ "motion_model_input = [\n",
+ " 'Acceleration', # Will use Acceleration\n",
+ " 'Parallax', # Will use Parallax\n",
+ " 'Linear', # Will use Linear\n",
+ " 'Acceleration', # Will use Linear, as n_fit = 2 < 3\n",
+ " 'Linear', # Will use Fixed, as n_fit = 1 < 2\n",
+ " 'Fixed' # Will use Empty, as n_fit = 0 < 1\n",
+ "]\n",
+ "tab = StarTable({\n",
+ " 'x': x,\n",
+ " 'y': y,\n",
+ " 'xe': xe,\n",
+ " 'ye': ye,\n",
+ " 'ra': ra,\n",
+ " 'dec': dec,\n",
+ " 'pa': pa,\n",
+ " 'motion_model_input': motion_model_input\n",
+ "})\n",
+ "tab.meta['list_times'] = t"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "id": "2b61fbcf",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Fitting motion model Acceleration: 0%| | 0/1 [00:00, ?it/s]/Users/weilingfeng/Academic/Software/flystar/flystar/motion_model.py:785: UserWarning: Acceleration model has no non-scipy fitter option. Running with scipy.\n",
+ " warnings.warn(\"Acceleration model has no non-scipy fitter option. Running with scipy.\")\n",
+ "Fitting motion model Acceleration: 100%|██████████| 1/1 [00:00<00:00, 1086.04it/s]\n",
+ "Fitting motion model Empty: 0%| | 0/1 [00:00, ?it/s]/Users/weilingfeng/Academic/Software/flystar/flystar/motion_model.py:119: OptimizeWarning: Empty data cannot be fit. Setting parameters to nan and uncertainties to np.inf.\n",
+ " fit_result = self.run_fit(\n",
+ "Fitting motion model Empty: 100%|██████████| 1/1 [00:00<00:00, 9258.95it/s]"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Fitting motion model Fixed: 0%| | 0/1 [00:00, ?it/s]/Users/weilingfeng/Academic/Software/flystar/flystar/motion_model.py:404: UserWarning: Fixed model has no non-scipy fitter option. Running with scipy.\n",
+ " warnings.warn(\"Fixed model has no non-scipy fitter option. Running with scipy.\")\n",
+ "Fitting motion model Fixed: 100%|██████████| 1/1 [00:00<00:00, 4405.78it/s]\n",
+ "Fitting motion model Linear: 100%|██████████| 2/2 [00:00<00:00, 5302.53it/s]\n",
+ "Fitting motion model Parallax: 0%| | 0/1 [00:00, ?it/s]/Users/weilingfeng/Academic/Software/flystar/flystar/motion_model.py:1002: UserWarning: Parallax model has no non-scipy fitter option. Running with scipy.\n",
+ " warnings.warn(\"Parallax model has no non-scipy fitter option. Running with scipy.\", UserWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"dtf2d\" yielded 1 of \"dubious year (Note 6)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"dtf2d\" yielded 2 of \"dubious year (Note 6)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"utctai\" yielded 2 of \"dubious year (Note 3)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"utctai\" yielded 1 of \"dubious year (Note 3)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"taiutc\" yielded 1 of \"dubious year (Note 4)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "Fitting motion model Parallax: 100%|██████████| 1/1 [00:00<00:00, 292.33it/s]\n"
+ ]
+ }
+ ],
+ "source": [
+ "tab.fit_motion_model(fixed_params_dict={\n",
+ " 'ra': ra, \n",
+ " 'dec': dec, \n",
+ " 'pa': pa,\n",
+ " 'obsLocation': 'earth'\n",
+ "})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5a625ccb",
+ "metadata": {},
+ "source": [
+ "Let's check if the actually used motion model is corrected:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 41,
+ "id": "b30ffb16",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "StarTable length=6\n",
+ "
\n",
+ "| n_fit | n_required | motion_model_input | motion_model_used |
\n",
+ "| int64 | int64 | str12 | str12 |
\n",
+ "| 5 | 3 | Acceleration | Acceleration |
\n",
+ "| 5 | 3 | Parallax | Parallax |
\n",
+ "| 3 | 2 | Linear | Linear |
\n",
+ "| 2 | 3 | Acceleration | Linear |
\n",
+ "| 1 | 2 | Linear | Fixed |
\n",
+ "| 0 | 1 | Fixed | Empty |
\n",
+ "
"
+ ],
+ "text/plain": [
+ "\n",
+ "n_fit n_required motion_model_input motion_model_used\n",
+ "int64 int64 str12 str12 \n",
+ "----- ---------- ------------------ -----------------\n",
+ " 5 3 Acceleration Acceleration\n",
+ " 5 3 Parallax Parallax\n",
+ " 3 2 Linear Linear\n",
+ " 2 3 Acceleration Linear\n",
+ " 1 2 Linear Fixed\n",
+ " 0 1 Fixed Empty"
+ ]
+ },
+ "execution_count": 41,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "all_mm_map = motion_model.motion_model_map()\n",
+ "tab['n_required'] = np.array([all_mm_map[mm].n_params for mm in tab['motion_model_input']], dtype=int)\n",
+ "tab[['n_fit', 'n_required', 'motion_model_input', 'motion_model_used']]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d4f96fcb",
+ "metadata": {},
+ "source": [
+ "## 2.4. Example: Infer Positions"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c660ec98",
+ "metadata": {},
+ "source": [
+ "Continuing from the previous example: Once we fit the motion models and the parameters are added into the table, we can infer the positions at arbitrary times with `StarTable.infer_positions`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "id": "095be28f",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"dtf2d\" yielded 20 of \"dubious year (Note 6)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"dtf2d\" yielded 40 of \"dubious year (Note 6)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"utctai\" yielded 40 of \"dubious year (Note 3)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"utctai\" yielded 20 of \"dubious year (Note 3)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n",
+ "/Users/weilingfeng/Software/miniconda3/envs/main/lib/python3.13/site-packages/erfa/core.py:133: ErfaWarning: ERFA function \"taiutc\" yielded 20 of \"dubious year (Note 4)\"\n",
+ " warn(f'ERFA function \"{func_name}\" yielded {wmsg}', ErfaWarning)\n"
+ ]
+ }
+ ],
+ "source": [
+ "x_model, y_model, xe_model, ye_model = tab.infer_positions(t_test)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a4df5458",
+ "metadata": {},
+ "source": [
+ "As in `MotionModel.model`, `StarTable.infer_positions` is also vectorized and returns positions and uncertainties in shapes of $(N_\\text{stars}, N_\\text{times})$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "id": "2f7e8b7a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(6, 100)"
+ ]
+ },
+ "execution_count": 44,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "x_model.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "7aab0868",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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eTabRTabLX9/5MgRnHXWWfUPmoiIyEWVzNcrKuC2bRtHjx5FJBKBpml13VYikcDq1atx6NAhRKNRh0Z45uNxqx6PWfV4zGrD41Y9p4+ZUgrJZBK9vb3Q9aW162t4eBjDw8MLXmdwcBB+v3/W5UeOHEFfXx/27NmD8847b9H7cnK+BvjcrgWPWW143KrHY1Y9HrPaOHncqpmvV1RKua7rjq8YRKNRPtFrwONWPR6z6vGY1YbHrXpOHrNYLObI7Titvb0d7e3tNf3uvn37AAA9PT0VXd+N+Rrgc7sWPGa14XGrHo9Z9XjMauPUcat0vl5RATcRERG568knn8SePXvw9re/HbFYDE8//TRuueUWXHHFFejv72/28IiIiBqKATcRERE5xjRN7Nq1C3fddRey2SwGBgZwww034FOf+lSzh0ZERNRwDLhrZJom7rjjDpim2eyhLCs8btXjMasej1lteNyqx2M2244dO7Bnz55mD2Ma/p2qx2NWGx636vGYVY/HrDbNOm4rqmgaERERERERUaMsrRKoRERERERERGcIBtxERERERERELmDATUREREREROSCFRtw33PPPXjTm96ESCSCzs5OvP/978cLL7ww7TpKKdx5553o7e1FIBDA2972Nvz2t78t//z06dP4xCc+gU2bNiEYDKK/vx9/8Rd/gbGxsWm3Mzg4CE3Tpn3cdtttDXmcTmvkcQOA//zP/8R5552HQCCA9vZ2XHXVVa4/Rqc16pj99Kc/nfU8K308/fTTDXu8Tmnkc+3FF1/ElVdeifb2dkSjUVx00UV49NFHG/I4ndTIY/bMM8/g3e9+N1paWtDW1oY//dM/xfj4eEMep9OcOG4A8LGPfQzr1q1DIBBAR0cHrrzySuzfv3/adUZGRnDttdciFoshFovh2muvxejoqNsPcdnjnF09zte14ZxdPc7XteGcXb1lO1+rFeo973mPeuihh9RvfvMb9eyzz6r3vve9qr+/X42Pj5ev87nPfU5FIhH13e9+Vz333HPq6quvVj09PSqRSCillHruuefUVVddpR5++GF14MAB9V//9V9qw4YN6gMf+MC0+xoYGFB33323GhoaKn8kk8mGPl6nNPK4fec731HxeFx95StfUS+88ILav3+/+va3v93Qx+uERh2zbDY77Tk2NDSkrr/+ejU4OKhs2274465XI59r69ev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rHrhhRfUX/3VXymv16ueffbZpjz2WjXyufalL31J7d27V73wwgvqy1/+sgoEAuof//EfG/6YneDEcXv55ZfVZz/7WfXLX/5Svfbaa+qJJ55QV155pWptbVXHjx8v385ll12mtm3bpp588kn15JNPqrPPPpttwSrAObt6nK9rwzm7epyva8M5u3rLdb5esQE3gDk/HnroofJ1bNtWd9xxh+ru7lamaaqLL75YPffcc+WfP/roo/PezsGDB5VSSu3du1edd955KhaLKb/frzZt2qTuuOMONTEx0eBH7IxGHTelpEXGX/7lX6rOzk4ViUTUu971LvWb3/ymgY/WGY08Zkop9aEPfUhdeOGFDXp07mnkcXv66afVpZdeqlpbW1UkElHnn3+++uEPf9jAR+uMRh6za6+9VrW2tiqfz6e2bdumvvnNbzbwkTrLieN25MgRdfnll6vOzk7l9XpVX1+f+vCHPzyrfcipU6fUNddcoyKRiIpEIuqaa65RIyMjDXqkyxfn7Opxvq4N5+zqcb6uDefs6i3X+VorDp6IiIiIiIiIHLRi93ATERERERERuYkBNxEREREREZELGHATERERERERuYABNxEREREREZELGHATERERERERuYABNxEREREREZELGHATERERERERuYABNxEREREREZELGHAT0YLuvPNObN++vdnDICIiogVwviZamjSllGr2IIioOTRNW/Dnf/Inf4Ivf/nLyGazaGtra9CoiIiIaCrO10TLFwNuohXs2LFj5a937dqFv/u7v8MLL7xQviwQCCAWizVjaERERFTE+Zpo+WJKOdEK1t3dXf6IxWLQNG3WZTNT1D7ykY/g/e9/Pz772c+iq6sLLS0tuOuuu5DP5/HXf/3XaG1tRV9fH77+9a9Pu68jR47g6quvRjweR1tbG6688kq8+uqrjX3AREREyxDna6LliwE3EVXtJz/5CY4ePYrHH38c9957L+688068733vQzwexy9+8QvceOONuPHGG3Ho0CEAQCqVwtvf/naEw2E8/vjj+PnPf45wOIzLLrsMlmU1+dEQERGdmThfEzUfA24iqlprayv+6Z/+CZs2bcJHP/pRbNq0CalUCp/+9KexYcMG3H777fD5fPjv//5vAMC3vvUt6LqOBx98EGeffTY2b96Mhx56CK+//jp++tOfNvfBEBERnaE4XxM1n6fZAyCi5WfLli3Q9cnzdV1dXdi6dWv5e8Mw0NbWhhMnTgAA9u7diwMHDiASiUy7nUwmg5dffrkxgyYiIlphOF8TNR8DbiKqmtfrnfa9pmlzXmbbNgDAtm3s3LkT//qv/zrrtjo6OtwbKBER0QrG+Zqo+RhwE5HrduzYgV27dqGzsxPRaLTZwyEiIqI5cL4mch73cBOR66655hq0t7fjyiuvxM9+9jMcPHgQjz32GG6++WYcPny42cMjIiIicL4mcgMDbiJyXTAYxOOPP47+/n5cddVV2Lx5Mz760Y8inU7zDDoREdESwfmayHmaUko1exBEREREREREZxqucBMRERERERG5gAE3ERERERERkQsYcBMRERERERG5gAE3ERERERERkQsYcBMRERERERG5gAE3ERERERERkQsYcBMRERERERG5gAE3ERERERERkQsYcBMRERERERG5gAE3ERERERERkQsYcBMRERERERG5gAE3ERERERERkQv+f8ZqD6VV4nMSAAAAAElFTkSuQmCC",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "visualize_fit(t, x, y, xe, ye, x_model, y_model, xe_model, ye_model, mm.name, t_test)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "12bb0136",
+ "metadata": {},
+ "source": [
+ "## 2.5. Speed Test"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "43fd87c5",
+ "metadata": {},
+ "source": [
+ "Speed test for the most commonly used Linear model. As the `use_scipy=False` option for the Linear model uses the [matrix multiplication solution](https://en.wikipedia.org/wiki/Weighted_least_squares#Solution), it is extremely fast at fewer epochs: "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "de576a47",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Fitting 10 epochs...\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Fitting motion model Linear: 100%|██████████| 10000/10000 [00:01<00:00, 6350.75it/s]\n",
+ "Fitting motion model Linear: 100%|██████████| 10000/10000 [00:00<00:00, 25802.05it/s]\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Fitting 31 epochs...\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Fitting motion model Linear: 100%|██████████| 10000/10000 [00:01<00:00, 6184.77it/s]\n",
+ "Fitting motion model Linear: 100%|██████████| 10000/10000 [00:00<00:00, 23908.79it/s]\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Fitting 100 epochs...\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Fitting motion model Linear: 100%|██████████| 10000/10000 [00:01<00:00, 6347.19it/s]\n",
+ "Fitting motion model Linear: 100%|██████████| 10000/10000 [00:00<00:00, 14309.49it/s]\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Fitting 316 epochs...\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Fitting motion model Linear: 100%|██████████| 10000/10000 [00:01<00:00, 5023.37it/s]\n",
+ "Fitting motion model Linear: 100%|██████████| 10000/10000 [00:03<00:00, 3288.47it/s]\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Fitting 1000 epochs...\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Fitting motion model Linear: 100%|██████████| 10000/10000 [00:02<00:00, 4314.91it/s]\n",
+ "Fitting motion model Linear: 100%|██████████| 10000/10000 [01:19<00:00, 125.47it/s]\n"
+ ]
+ }
+ ],
+ "source": [
+ "import time\n",
+ "N = 10000\n",
+ "dims = np.logspace(1, 3, 5, dtype=int)\n",
+ "rng = np.random.default_rng(42)\n",
+ "\n",
+ "scipy_times = []\n",
+ "analytic_times = []\n",
+ "\n",
+ "for dim in dims:\n",
+ " print(f'Fitting {dim} epochs...')\n",
+ " t = np.linspace(2025.0, 2030.0, dim)\n",
+ " x = rng.random((N, dim))\n",
+ " y = rng.random((N, dim))\n",
+ " xe = rng.uniform(0, 0.2, size=(N, dim))\n",
+ " ye = rng.uniform(0, 0.2, size=(N, dim))\n",
+ " tab = StarTable({\n",
+ " 'x': x,\n",
+ " 'y': y,\n",
+ " 'xe': xe,\n",
+ " 'ye': ye\n",
+ " })\n",
+ " tab.meta['list_times'] = t\n",
+ " \n",
+ " start = time.time()\n",
+ " tab.fit_motion_model(use_scipy=True)\n",
+ " end = time.time()\n",
+ " scipy_times.append(end - start)\n",
+ " \n",
+ " start = time.time()\n",
+ " tab.fit_motion_model(use_scipy=False)\n",
+ " end = time.time()\n",
+ " analytic_times.append(end - start)\n",
+ "\n",
+ "scipy_times = np.array(scipy_times)\n",
+ "analytic_times = np.array(analytic_times)\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "3d2a8457",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "280"
+ ]
+ },
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Collect memory garbage data\n",
+ "import gc\n",
+ "gc.collect()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "06442faf",
+ "metadata": {},
+ "source": [
+ "Let's visualize the performance:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "id": "03d53769",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "fig, ax = plt.subplots()\n",
+ "ax.plot(dims, N / scipy_times, marker='o', label='Scipy Curve Fit')\n",
+ "ax.plot(dims, N / analytic_times, marker='o', color='C3', label='Motion Model Analytic')\n",
+ "ax.set_xscale('log')\n",
+ "ax.set_xlabel('Number of Epochs')\n",
+ "ax.set_ylabel('Stars Fit per Second')\n",
+ "ax.set_title(f'Motion Model Fitting Performance of {N} Stars')\n",
+ "ax.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ea672ab4",
+ "metadata": {},
+ "source": [
+ "It can be seen that for epochs < 200, the analytic solution is faster than scipy, and vice versa for > 300 epochs."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "main",
+ "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.13.11"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/flystar/align.py b/flystar/align.py
index 994a3b1..2820ae5 100755
--- a/flystar/align.py
+++ b/flystar/align.py
@@ -1,10 +1,7 @@
import numpy as np
-from flystar import match
-from flystar import transforms
-from flystar import plots
-from flystar.starlists import StarList
-from flystar.startables import StarTable
-from flystar import motion_model
+from . import match, transforms, plots, motion_model
+from .starlists import StarList
+from .startables import StarTable
from astropy.table import Table, Column, vstack
import datetime
import copy
@@ -21,12 +18,12 @@ def __init__(self, list_of_starlists, ref_index=0, iters=2,
outlier_tol=[None, None],
trans_args=[{'order': 2}, {'order': 2}],
init_order=1,
- mag_trans=True, mag_lim=None, trans_weights=None, vel_weights='var',
+ mag_trans=True, mag_lim=None, trans_weighting=None, vel_weighting='var',
trans_input=None, trans_class=transforms.PolyTransform,
calc_trans_inverse=False,
init_guess_mode='miracle', iter_callback=None,
- default_motion_model='Fixed',
- motion_model_dict = {},
+ motion_models=['Empty', 'Fixed'],
+ fixed_params_dict=None,
use_scipy=True,
absolute_sigma=False,
save_path=None,
@@ -89,13 +86,13 @@ def __init__(self, list_of_starlists, ref_index=0, iters=2,
separately for each list and each iteration, you need to pass in a 2D array that
has shape (N_lists, 2).
- trans_weights : str
+ trans_weighting : str
Either None (def), 'both,var', 'list,var', or 'ref,var' depending on whether you want
to weight by the positional uncertainties (variances) in the individual starlists, or also with
the uncertainties in the reference frame itself. Note weighting only works when there
are positional uncertainties availabe. Other options include 'both,std', 'list,std', 'list,var'.
- vel_weights : str
+ vel_weighting : str
Either 'var' (def) or 'std', depending on whether you want to weight the motion model
fits by the variance or standard deviation of the position data
@@ -130,11 +127,11 @@ def = None. If not None, then this should contain an array or list of transform
A function to call (that accepts a StarTable object and an iteration number)
at the end of every iteration. This can be used for plotting or printing state.
- default_motion_model : string
- Name of motion model to use for new or unassigned stars
+ motion_models : list of MotionModel or str, optional
+ Motion models or their names to use for new or unassigned stars
- motion_model_dict : None or dict
- Dict of motion model name keys (strings) and corresponding MotionModel object values
+ fixed_params_dict : None or dict
+ Dictionary of motion model fixed parameters
use_scipy : bool, optional
If True, use scipy.optimize.curve_fit for velocity fitting. If False, use linear
@@ -192,20 +189,34 @@ def = None. If not None, then this should contain an array or list of transform
self.init_order = init_order
self.mag_trans = mag_trans
self.mag_lim = mag_lim
- self.trans_weights = trans_weights
- self.vel_weights = vel_weights
+ self.trans_weighting = trans_weighting
+ self.vel_weighting = vel_weighting
self.trans_input = trans_input
self.trans_class = trans_class
self.calc_trans_inverse = calc_trans_inverse
- self.motion_model_dict = motion_model_dict
self.use_scipy = use_scipy
self.absolute_sigma = absolute_sigma
- self.default_motion_model = default_motion_model
+ self.fixed_params_dict = fixed_params_dict
self.init_guess_mode = init_guess_mode
self.iter_callback = iter_callback
self.save_path = save_path
self.verbose = verbose
+ all_mm_map = motion_model.motion_model_map()
+ if all(isinstance(mm, str) for mm in motion_models):
+ mm_names = motion_models
+ motion_models = [all_mm_map[mm] for mm in motion_models]
+ else:
+ mm_names = [mm.name for mm in motion_models]
+ if 'Empty' not in mm_names:
+ motion_models.append(all_mm_map['Empty'])
+ if 'Fixed' not in mm_names:
+ motion_models.append(all_mm_map['Fixed'])
+
+ # Sort by increasing n_params
+ motion_models = sorted(motion_models, key=lambda mm: mm.n_params)
+ self.motion_models = motion_models
+
# For backwards compatibility.
if self.verbose is True:
self.verbose = 9
@@ -235,23 +246,23 @@ def = None. If not None, then this should contain an array or list of transform
self.setup_trans_info()
# Make sure the motion models are ready
- self.motion_model_dict = motion_model.validate_motion_model_dict(self.motion_model_dict,
- StarTable(), self.default_motion_model)
+ # self.motion_model_dict = motion_model.validate_motion_model_dict(self.motion_model_dict,
+ # StarTable(), self.default_motion_model)
return
def fix_iterable_conditions(self):
if not np.iterable(self.dr_tol):
self.dr_tol = np.repeat(self.dr_tol, self.iters)
- assert len(self.dr_tol) == self.iters
+ assert len(self.dr_tol) == self.iters, f'len(dr_tol)={len(self.dr_tol)} != iters={self.iters}'
if not np.iterable(self.dm_tol):
self.dm_tol = np.repeat(self.dm_tol, self.iters)
- assert len(self.dm_tol) == self.iters
+ assert len(self.dm_tol) == self.iters, f'len(dm_tol)={len(self.dm_tol)} != iters={self.iters}'
if not np.iterable(self.outlier_tol):
self.outlier_tol = np.repeat(self.outlier_tol, self.iters)
- assert len(self.outlier_tol) == self.iters
+ assert len(self.outlier_tol) == self.iters, f'len(outlier_tol)={len(self.outlier_tol)} != iters={self.iters}'
if self.mag_lim is None:
self.mag_lim = np.repeat([[None, None]], len(self.star_lists), axis=0)
@@ -290,7 +301,7 @@ def fit(self):
# x_orig, y_orig, m_orig, (opt. errors) -- the transformed errors for the lists: 2D
# w, w_orig (optiona) -- the input and output weights of stars in transform: 2D
##########
- self.ref_table = self.setup_ref_table_from_starlist(self.star_lists[self.ref_index],motion_model_used='Fixed')
+ self.ref_table = self.setup_ref_table_from_starlist(self.star_lists[self.ref_index])
# Save the reference index to the meta data on the reference list.
self.ref_table.meta['ref_list'] = self.ref_index
@@ -369,6 +380,10 @@ def fit(self):
if self.iter_callback != None:
self.iter_callback(self.ref_table, nn)
+ # Add times into ref_table meta data
+ complete_times = np.array([np.unique(col[~np.isnan(col)])[0] for col in self.ref_table['t'].T])
+ self.ref_table.meta['LIST_TIMES'] = complete_times
+
if self.save_path:
with open(self.save_path, 'wb') as file:
pickle.dump(self, file)
@@ -408,12 +423,15 @@ def match_and_transform(self, ref_mag_lim, dr_tol, dm_tol, outlier_tol, trans_ar
if trans is None:
# Only use "use_in_trans" reference stars, even for initial guessing.
keepers = np.where(ref_list['use_in_trans'] == True)[0]
-
- trans = trans_initial_guess(ref_list[keepers], star_list_orig_trim, self.trans_args[0], self.motion_model_dict,
- mode=self.init_guess_mode,
- order=self.init_order,
- verbose=self.verbose,
- mag_trans=self.mag_trans)
+ trans = trans_initial_guess(
+ ref_list[keepers],
+ star_list_orig_trim,
+ self.trans_args[0],
+ mode=self.init_guess_mode,
+ order=self.init_order,
+ verbose=self.verbose,
+ mag_trans=self.mag_trans
+ )
if self.mag_trans:
star_list_T.transform_xym(trans) # trimmed, transformed
@@ -506,7 +524,7 @@ def match_and_transform(self, ref_mag_lim, dr_tol, dm_tol, outlier_tol, trans_ar
dy=(star_t['y'] - star_r['y']) * 1e3,
dm=(star_t['m'] - star_r['m']),
xo=star_s['x'], yo=star_s['y'], mo=star_s['m']))
-
+
idx_lis, idx_ref, dr, dm = match.match(star_list_T['x'], star_list_T['y'], star_list_T['m'],
ref_list['x'], ref_list['y'], ref_list['m'],
dr_tol=dr_tol, dm_tol=dm_tol, verbose=self.verbose)
@@ -517,7 +535,8 @@ def match_and_transform(self, ref_mag_lim, dr_tol, dm_tol, outlier_tol, trans_ar
## Make plot, if desired
plots.trans_positions(ref_list, ref_list[idx_ref], star_list_T, star_list_T[idx_lis],
- fileName='{0}'.format(star_list_T['t'][0]))
+ save_path=f"{self.save_path}/Transformed_Positions_{star_list_T['t'][0]}.png" if self.save_path else None,
+ show_plot=False)
### Update the observed (but transformed) values in the reference table.
self.update_ref_table_from_list(star_list, star_list_T, ii, idx_ref, idx_lis, idx2)
@@ -583,12 +602,12 @@ def setup_trans_info(self):
# Add inverse trans list, if desired
if self.calc_trans_inverse:
- trans_list_inverse = [None for ii in range(N_lists)]
+ trans_list_inverse = [None] * N_lists
self.trans_list_inverse = trans_list_inverse
return
- def setup_ref_table_from_starlist(self, star_list, motion_model_used=None):
+ def setup_ref_table_from_starlist(self, star_list):
"""
Start with the reference list.... this will change and grow
over time, so make a copy that we will keep updating.
@@ -596,7 +615,9 @@ def setup_ref_table_from_starlist(self, star_list, motion_model_used=None):
array in the original reference star list.
"""
col_arrays = {}
- motion_model_col_names = motion_model.get_all_motion_model_param_names(with_errors=True, with_fixed=True) + ['m0','m0_err','use_in_trans', 'motion_model_input', 'motion_model_used']
+ motion_model_col_names = motion_model.motion_model_param_names(self.motion_models, with_errors=True, with_fixed=True) + ['m0','m0_err','use_in_trans', 'motion_model_input', 'motion_model_used']
+ if 't0' not in motion_model_col_names:
+ motion_model_col_names.insert(0, 't0')
for col_name in star_list.colnames:
if col_name == 'name':
# The "name" column will be 1D; but we will also add a "name_in_list" column.
@@ -638,7 +659,7 @@ def setup_ref_table_from_starlist(self, star_list, motion_model_used=None):
if not new_cols_arr[ii] in ref_cols:
# Some munging to convert data shape from (N,1) to (N,),
# since these are all 1D cols
- vals = np.transpose(np.array(ref_table[orig_cols_arr[ii]]))[0]
+ vals = np.array(ref_table[orig_cols_arr[ii]]).flatten()
# Now add to ref_table
new_col = Column(vals, name=new_cols_arr[ii])
@@ -695,14 +716,17 @@ def setup_ref_table_from_starlist(self, star_list, motion_model_used=None):
for col_name in ref_table.colnames:
if len(ref_table[col_name].data.shape) == 2: # Find the 2D columns
ref_table._set_invalid_list_values(col_name, -1)
-
+
if 'motion_model_input' not in ref_table.colnames:
- ref_table.add_column(Column(np.repeat(self.default_motion_model, len(ref_table)), name='motion_model_input'))
+ ref_table.add_column(Column(np.repeat(self.motion_models[-1].name, len(ref_table)), name='motion_model_input'))
if 'motion_model_used' not in ref_table.colnames:
- if motion_model_used is None:
- ref_table.add_column(Column(np.repeat(self.default_motion_model, len(ref_table)), name='motion_model_used'))
- else:
- ref_table.add_column(Column(np.repeat(motion_model_used, len(ref_table)), name='motion_model_used'))
+ # Order self.motion_models by decreasing n_params
+ sorted_mms = sorted(self.motion_models, key=lambda mm: mm.n_params, reverse=True)
+ # Save the most complex motion model that can infer the positions with the existing columns.
+ for mm in sorted_mms:
+ if all([_ in ref_table.colnames for _ in mm.fit_param_names]) and all([_ in ref_table.colnames for _ in mm.fixed_param_names]):
+ ref_table.add_column(Column(np.repeat(mm.name, len(ref_table)), name='motion_model_used'))
+ break
return ref_table
@@ -802,35 +826,40 @@ def update_ref_table_from_list(self, star_list, star_list_T, ii, idx_ref, idx_li
if ((self.ref_table['x'].shape[1] != len(self.star_lists)) and
(ii != self.ref_index) and
(ii >= self.ref_table['x'].shape[1])):
-
+
self.ref_table.add_starlist()
-
+
copy_over_values(self.ref_table, star_list, star_list_T, ii, idx_ref, idx_lis)
self.ref_table['used_in_trans'][idx_ref_in_trans, ii] = True
### Add the unmatched stars and grow the size of the reference table.
- self.ref_table, idx_lis_new, idx_ref_new = add_rows_for_new_stars(self.ref_table, star_list, idx_lis,
- default_motion_model=self.default_motion_model)
+ self.ref_table, idx_lis_new, idx_ref_new = add_rows_for_new_stars(
+ self.ref_table,
+ star_list,
+ idx_lis,
+ motion_model=self.motion_models[-1].name
+ )
+
if len(idx_ref_new) > 0:
if self.verbose > 0:
print(' Adding {0:d} new stars to the reference table.'.format(len(idx_ref_new)))
-
+
copy_over_values(self.ref_table, star_list, star_list_T, ii, idx_ref_new, idx_lis_new)
# Copy the single-epoch values to the aggregate (only for new stars).
self.ref_table['x0'][idx_ref_new] = star_list_T['x'][idx_lis_new]
self.ref_table['y0'][idx_ref_new] = star_list_T['y'][idx_lis_new]
self.ref_table['m0'][idx_ref_new] = star_list_T['m'][idx_lis_new]
-
+
self.ref_table['name'] = update_old_and_new_names(self.ref_table, ii, idx_ref_new)
if self.use_ref_new == True:
self.ref_table['use_in_trans'][idx_ref_new] = True
else:
self.ref_table['use_in_trans'][idx_ref_new] = False
-
+
return
-
+
def update_ref_table_aggregates(self, keep_orig=None, n_boot=0):
"""
Average positions or fit velocities.
@@ -843,39 +872,41 @@ def update_ref_table_aggregates(self, keep_orig=None, n_boot=0):
"""
# Keep track of the original reference values.
# In certain cases, we will NOT update these.
- if keep_orig is not None:
+ if (keep_orig is not None) and (len(keep_orig) > 0):
vals_orig = {}
vals_orig['m0'] = self.ref_table['m0'][keep_orig]
vals_orig['m0_err'] = self.ref_table['m0_err'][keep_orig]
- motion_model_class_names = self.ref_table['motion_model_input'].tolist()
+ motion_model_class_names = []
+ if 'motion_model_input' in self.ref_table.keys():
+ motion_model_class_names += self.ref_table['motion_model_input'].tolist()
if 'motion_model_used' in self.ref_table.keys():
motion_model_class_names += self.ref_table['motion_model_used'][keep_orig].tolist()
vals_orig['motion_model_used'] = self.ref_table['motion_model_used'][keep_orig]
- motion_model_col_names = motion_model.get_list_motion_model_param_names(motion_model_class_names, with_errors=True, with_fixed=True)
+ motion_model_col_names = motion_model.motion_model_param_names(motion_model_class_names, with_errors=True, with_fixed=True)
for mm in motion_model_col_names:
if mm in self.ref_table.keys():
vals_orig[mm] = self.ref_table[mm][keep_orig]
- fit_star_idxs = [idx for idx in range(len(self.ref_table)) if idx not in keep_orig]
+ fit_star_idxs = np.array([idx for idx in range(len(self.ref_table)) if idx not in keep_orig], dtype=int)
else:
fit_star_idxs = None
- #pdb.set_trace()
+
# Figure out whether motion fits are necessary
- all_fixed = np.all(self.ref_table['motion_model_input']=='Fixed')
- if all_fixed:
+ if ('motion_model_input' in self.ref_table.keys()) and np.all(self.ref_table['motion_model_input']=='Fixed'):
weighted_xy = ('xe' in self.ref_table.colnames) and ('ye' in self.ref_table.colnames)
weighted_m = ('me' in self.ref_table.colnames)
self.ref_table.combine_lists_xym(weighted_xy=weighted_xy, weighted_m=weighted_m)
+
else:
- # Combine positions with a velocity fit.
- self.ref_table.fit_velocities(bootstrap=n_boot,
- verbose=self.verbose,
- show_progress=(self.verbose>0),
- default_motion_model=self.default_motion_model,
- select_stars=fit_star_idxs,
- motion_model_dict=self.motion_model_dict,
- weighting=self.vel_weights,
- use_scipy=self.use_scipy,
- absolute_sigma=self.absolute_sigma)
+ self.ref_table.fit_motion_model(
+ motion_models=self.motion_models,
+ fixed_params_dict=self.fixed_params_dict,
+ weighting=self.vel_weighting,
+ use_scipy=self.use_scipy,
+ absolute_sigma=self.absolute_sigma,
+ select_stars=fit_star_idxs,
+ bootstrap=n_boot,
+ verbose=self.verbose
+ )
# Combine (transformed) magnitudes
if 'me' in self.ref_table.colnames:
@@ -883,8 +914,9 @@ def update_ref_table_aggregates(self, keep_orig=None, n_boot=0):
else:
weights_col = 'me'
self.ref_table.combine_lists('m', weights_col=weights_col, ismag=True)
+
# Replace the originals if we are supposed to keep them fixed.
- if keep_orig is not None:
+ if (keep_orig is not None) and (len(keep_orig) > 0):
for val in vals_orig.keys():
self.ref_table[val][keep_orig] = vals_orig[val]
@@ -905,18 +937,18 @@ def get_weights_for_lists(self, ref_list, star_list):
var_xlis = 0.0
var_ylis = 0.0
- if self.trans_weights != None:
- if self.trans_weights == 'both,var':
+ if self.trans_weighting != None:
+ if self.trans_weighting == 'both,var':
weight = 1.0 / (var_xref + var_xlis + var_yref + var_ylis)
- if self.trans_weights == 'both,std':
+ if self.trans_weighting == 'both,std':
weight = 1.0 / np.sqrt(var_xref + var_xlis + var_yref + var_ylis)
- if self.trans_weights == 'ref,var':
+ if self.trans_weighting == 'ref,var':
weight = 1.0 / (var_xref + var_yref)
- if self.trans_weights == 'ref,std':
+ if self.trans_weighting == 'ref,std':
weight = 1.0 / np.sqrt(var_xref + var_yref)
- if self.trans_weights == 'list,var':
+ if self.trans_weighting == 'list,var':
weight = 1.0 / (var_xlis + var_ylis)
- if self.trans_weights == 'list,std':
+ if self.trans_weighting == 'list,std':
weight = 1.0 / np.sqrt(var_xlis, var_ylis)
else:
weight = None
@@ -957,14 +989,14 @@ def match_lists(self, dr_tol, dm_tol):
star_list_T.transform_xym(self.trans_list[ii])
else:
star_list_T.transform_xy(self.trans_list[ii])
-
- xref, yref = get_pos_at_time(star_list_T['t'][0], self.ref_table, self.motion_model_dict)
+
+ xref, yref = infer_positions(star_list_T['t'][0], self.ref_table)
mref = self.ref_table['m0']
idx_lis, idx_ref, dr, dm = match.match(star_list_T['x'], star_list_T['y'], star_list_T['m'],
xref, yref, mref,
dr_tol=dr_tol, dm_tol=dm_tol, verbose=self.verbose)
-
+
if self.verbose > 0:
fmt = 'Matched {0:5d} out of {1:5d} stars in list {2:2d} [dr = {3:7.4f} +/- {4:6.4f}, dm = {5:5.2f} +/- {6:4.2f}'
print(fmt.format(len(idx_lis), len(star_list_T), ii, dr.mean(), dr.std(), dm.mean(), dm.std()))
@@ -992,7 +1024,7 @@ def get_ref_list_from_table(self, epoch):
name = self.ref_table['name']
if ('motion_model_used' in self.ref_table.colnames):
- x,y,xe,ye = self.ref_table.get_star_positions_at_time(epoch, self.motion_model_dict, allow_alt_models=True)
+ x, y, xe, ye = self.ref_table.infer_positions(epoch)
else:
# No velocities... just used average positions.
x = self.ref_table['x0']
@@ -1137,22 +1169,29 @@ def calc_bootstrap_errors(self, n_boot=100, boot_epochs_min=-1, calc_vel_in_boot
y2_boot_sum = np.zeros((len(ref_table['x']), n_epochs))
m_boot_sum = np.zeros((len(ref_table['x']), n_epochs))
m2_boot_sum = np.zeros((len(ref_table['x']), n_epochs))
-
+
# Set up motion model parameters
- motion_model_list = ['Fixed', self.default_motion_model]
if 'motion_model_used' in ref_table.keys():
- motion_model_list += ref_table['motion_model_used'].tolist()
+ motion_model_list = np.unique(ref_table['motion_model_used']).tolist()
elif 'motion_model_input' in ref_table.keys():
- motion_model_list += ref_table['motion_model_input'].tolist()
- motion_col_list = motion_model.get_list_motion_model_param_names(np.unique(motion_model_list).tolist(), with_errors=False, with_fixed=False)
+ motion_model_list = np.unique(ref_table['motion_model_input']).tolist()
+
+ if 'Empty' not in motion_model_list:
+ motion_model_list.append('Empty')
+ if 'Fixed' not in motion_model_list:
+ motion_model_list.append('Fixed')
+
+ motion_col_list = motion_model.motion_model_param_names(motion_model_list, with_errors=False, with_fixed=False)
if calc_vel_in_bootstrap:
motion_boot_sum = {}
motion2_boot_sum = {}
for col in motion_col_list:
motion_boot_sum[col] = np.zeros((len(ref_table['x'])))
motion2_boot_sum[col] = np.zeros((len(ref_table['x'])))
- motion_boot_min_epochs = np.max([self.motion_model_dict[mod].n_pts_req
- for mod in np.unique(motion_model_list)])
+
+ all_mm_map = motion_model.motion_model_map()
+ motion_model_list = [all_mm_map[mm_name] for mm_name in motion_model_list]
+ motion_boot_min_epochs = np.max([mm.n_params for mm in motion_model_list])
### IF MEMORY PROBLEMS HERE:
### DEFINE MEAN, STD VARIABLES AND BUILD THEM RATHER THAN SAVING FULL ARRAY
@@ -1210,7 +1249,7 @@ def calc_bootstrap_errors(self, n_boot=100, boot_epochs_min=-1, calc_vel_in_boot
# Calculate weights based on weights keyword. If weights desired, will need to
# make starlist objects for this
- if self.trans_weights != None:
+ if self.trans_weighting != None:
# In order for weights calculation to work, we need to apply a transformation
# to the star_list_T so it is in the same units as ref_boot. So, we'll apply
# the final transformation for the epoch to get close enough for the
@@ -1232,7 +1271,6 @@ def calc_bootstrap_errors(self, n_boot=100, boot_epochs_min=-1, calc_vel_in_boot
m=starlist_boot['m'], mref=ref_boot['m'],
weights=weight, mag_trans=self.mag_trans)
#print(jj)
- #pdb.set_trace()
# Apply transformation to *all* orig positions in this epoch. Need to make a new
# FLYSTAR starlist object with the original positions for this. We don't
@@ -1291,10 +1329,16 @@ def calc_bootstrap_errors(self, n_boot=100, boot_epochs_min=-1, calc_vel_in_boot
# Now, do proper motion calculation, making sure to fix t0 to the
# orig value (so we can get a reasonable error on x0, y0)
- star_table.fit_velocities(
- fixed_t0=t0_arr,
- default_motion_model=self.default_motion_model,
- motion_model_dict=self.motion_model_dict,
+ if self.fixed_params_dict is None:
+ fixed_params_dict = {'t0': t0_arr}
+ elif 't0' not in self.fixed_params_dict.keys():
+ fixed_params_dict = self.fixed_params_dict.copy()
+ fixed_params_dict['t0'] = t0_arr
+
+ star_table.fit_motion_model(
+ motion_models=self.motion_models,
+ fixed_params_dict=fixed_params_dict,
+ weighting=self.vel_weighting,
use_scipy=self.use_scipy,
absolute_sigma=self.absolute_sigma
)
@@ -1306,7 +1350,7 @@ def calc_bootstrap_errors(self, n_boot=100, boot_epochs_min=-1, calc_vel_in_boot
# Quick check to make sure bootstrap calc was valid: output t0 should be
# same as input t0_arr, since we used fixed_t0 option
- assert np.sum(abs(star_table['t0'] - t0_arr) == 0)
+ np.testing.assert_array_equal(star_table['t0'], t0_arr)
#t3 = time.time()
#print('=================================================')
@@ -1345,8 +1389,20 @@ def calc_bootstrap_errors(self, n_boot=100, boot_epochs_min=-1, calc_vel_in_boot
col[idx_good] = data_dict[ff]
self.ref_table.add_column(col)
- # Calculate chi^2 with bootstrap positional errors
- x_pred, y_pred, _, _ = self.ref_table.get_star_positions_at_time(t_arr, self.motion_model_dict, allow_alt_models=True)
+ # # Calculate chi^2 with bootstrap positional errors
+ # # Determine which motion model to use:
+ # motion_model_list = sorted(motion_model_list, key=lambda mm: mm.n_params)
+ # mm_n_params = np.sort([mm.n_params for mm in motion_model_list])
+
+ # required_params = [all_mm_map[mm_name].n_params for mm_name in self.ref_table['motion_model_input']]
+ # mm_digitized = np.digitize(
+ # x=np.minimum(np.array(self.ref_table['n_detect']), required_params),
+ # bins=mm_n_params
+ # ) - 1
+ # self.ref_table['motion_model_used'] = np.array([motion_model_list[d].name for d in mm_digitized], dtype='U20')
+
+
+ x_pred, y_pred, _, _ = self.ref_table.infer_positions(t_arr)
xe_comb = np.hypot(self.ref_table['xe'], self.ref_table['xe_boot'])
ye_comb = np.hypot(self.ref_table['ye'], self.ref_table['ye_boot'])
data_dict['chi2_x_boot'] = np.nansum((self.ref_table['x']-x_pred)**2/(xe_comb)**2,axis=1)
@@ -1368,7 +1424,6 @@ def calc_bootstrap_errors(self, n_boot=100, boot_epochs_min=-1, calc_vel_in_boot
col[idx_good] = data_dict[ff]
self.ref_table.add_column(col)
- #pdb.set_trace()
print('===============================')
print('Done with bootstrap')
@@ -1384,7 +1439,7 @@ def __init__(self, ref_list, list_of_starlists, iters=2,
trans_args=[{'order': 2}, {'order': 2}],
init_order=1,
mag_trans=True, mag_lim=None, ref_mag_lim=None,
- trans_weights=None, vel_weights='var',
+ trans_weighting=None, vel_weighting='var',
trans_input=None,
trans_class=transforms.PolyTransform,
calc_trans_inverse=False,
@@ -1392,8 +1447,8 @@ def __init__(self, ref_list, list_of_starlists, iters=2,
update_ref_orig=False,
init_guess_mode='miracle',
iter_callback=None,
- default_motion_model='Fixed',
- motion_model_dict={},
+ motion_models=['Empty', 'Fixed'],
+ fixed_params_dict=None,
use_scipy=True,
absolute_sigma=False,
save_path=None,
@@ -1452,19 +1507,19 @@ def __init__(self, ref_list, list_of_starlists, iters=2,
If different from None, it indicates the minimum and maximum magnitude
on the catalogs for finding the transformations. Note, if you want specify the mag_lim
separately for each list and each iteration, you need to pass in a 2D array that
- has shape (N_lists, 2).
+ has shape (N_lists, N_iters).
ref_mag_lim : array
If different from None, it indicates the minimum and maximum magnitude
on the reference catalog for finding the transformations.
- trans_weights : str
+ trans_weighting : str
Either None (def), 'both,var', 'list,var', or 'ref,var' depending on whether you want
to weight by the positional uncertainties (variances) in the individual starlists, or also with
the uncertainties in the reference frame itself. Note weighting only works when there
are positional uncertainties availabe. Other options include 'both,std', 'list,std', 'list,var'.
- vel_weights : str
+ vel_weighting : str
Either 'var' (def) or 'std', depending on whether you want to weight the motion model
fits by the variance or standard deviation of the position data
@@ -1521,12 +1576,12 @@ def = None. If not None, then this should contain an array or list of transform
iter_callback : None or function
A function to call (that accepts a StarTable object and an iteration number)
at the end of every iteration. This can be used for plotting or printing state.
-
- default_motion_model : string
- Name of motion model to use for new or unassigned stars
-
- motion_model_dict : None or dict
- Dict of motion model name keys (strings) and corresponding MotionModel object values
+
+ motion_models : list of str or MotionModel objects
+ List of motion model names (strings) or MotionModel objects to use
+
+ fixed_params_dict : None or dict
+ Dictionary of fixed parameters for motion models
use_scipy : bool, optional
If True, use scipy.optimize.curve_fit for velocity fitting. If False, use linear algebra fitting, by default True.
@@ -1573,13 +1628,13 @@ def = None. If not None, then this should contain an array or list of transform
outlier_tol=outlier_tol, trans_args=trans_args,
init_order=init_order,
mag_trans=mag_trans, mag_lim=mag_lim,
- trans_weights=trans_weights, vel_weights=vel_weights,
+ trans_weighting=trans_weighting, vel_weighting=vel_weighting,
trans_input=trans_input, trans_class=trans_class,
calc_trans_inverse=calc_trans_inverse,
- default_motion_model = default_motion_model,
init_guess_mode=init_guess_mode,
iter_callback=iter_callback,
- motion_model_dict=motion_model_dict,
+ motion_models=motion_models,
+ fixed_params_dict=fixed_params_dict,
verbose=verbose, use_scipy=use_scipy,
absolute_sigma=absolute_sigma, save_path=save_path)
@@ -1601,10 +1656,10 @@ def = None. If not None, then this should contain an array or list of transform
self.ref_list['me'] = self.ref_list['m0_err']
if ('t' not in self.ref_list.colnames) and ('t0' in self.ref_list.colnames):
self.ref_list['t'] = self.ref_list['t0']
-
+
# Make sure the motion models are ready
- self.motion_model_dict = motion_model.validate_motion_model_dict(self.motion_model_dict,
- self.ref_list, self.default_motion_model)
+ # self.motion_model_dict = motion_model.validate_motion_model_dict(self.motion_model_dict,
+ # self.ref_list, self.default_motion_model)
return
@@ -1641,13 +1696,13 @@ def fit(self):
logger(_log, ' mag_trans = ' + str(self.mag_trans), self.verbose)
logger(_log, ' mag_lim = ' + str(self.mag_lim), self.verbose)
logger(_log, ' ref_mag_lim = ' + str(self.ref_mag_lim), self.verbose)
- logger(_log, ' trans_weights = ' + str(self.trans_weights), self.verbose)
- logger(_log, ' vel_weights = ' + str(self.vel_weights), self.verbose)
+ logger(_log, ' trans_weighting = ' + str(self.trans_weighting), self.verbose)
+ logger(_log, ' vel_weighting = ' + str(self.vel_weighting), self.verbose)
logger(_log, ' trans_input = ' + str(self.trans_input), self.verbose)
logger(_log, ' trans_class = ' + str(self.trans_class), self.verbose)
logger(_log, ' calc_trans_inverse = ' + str(self.calc_trans_inverse), self.verbose)
logger(_log, ' use_ref_new = ' + str(self.use_ref_new), self.verbose)
- logger(_log, ' default_motion_model = ' + str(self.default_motion_model), self.verbose)
+ logger(_log, ' motion_models = ' + str([mm.name for mm in self.motion_models]), self.verbose)
logger(_log, ' update_ref_orig = ' + str(self.update_ref_orig), self.verbose)
logger(_log, ' init_guess_mode = ' + str(self.init_guess_mode), self.verbose)
logger(_log, ' iter_callback = ' + str(self.iter_callback), self.verbose)
@@ -1669,7 +1724,6 @@ def fit(self):
#
##########
for nn in range(self.iters):
-
# If we are on subsequent iterations, remove matching results from the
# prior iteration. This leaves aggregated (1D) columns alone.
if nn > 0:
@@ -1682,13 +1736,13 @@ def fit(self):
print('Starting iter {0:d} with ref_table shape:'.format(nn), self.ref_table['x'].shape)
print("**********")
print("**********")
-
+
# ALL the action is in here. Match and transform the stack of starlists.
# This updates trans objects and the ref_table.
self.match_and_transform(self.ref_mag_lim,
self.dr_tol[nn], self.dm_tol[nn], self.outlier_tol[nn],
self.trans_args[nn])
-
+
# Clean up the reference table
# Find where stars are detected.
self.ref_table.detections()
@@ -1716,11 +1770,10 @@ def fit(self):
print("**********")
self.match_lists(self.dr_tol[-1], self.dm_tol[-1])
- keep_ref_orig = (self.update_ref_orig==False)
- if keep_ref_orig:
- keep_orig = np.where(self.ref_table['ref_orig'])[0]
- else:
+ if self.update_ref_orig:
keep_orig=None
+ else:
+ keep_orig = np.where(self.ref_table['ref_orig'])[0]
self.update_ref_table_aggregates(keep_orig=keep_orig)
##########
@@ -1771,7 +1824,7 @@ def get_all_epochs(t):
return all_epochs
-def setup_ref_table_from_starlist(star_list):
+def setup_ref_table_from_starlist(star_list, motion_models):
"""
Start with the reference list.... this will change and grow
over time, so make a copy that we will keep updating.
@@ -1779,7 +1832,7 @@ def setup_ref_table_from_starlist(star_list):
array in the original reference star list.
"""
col_arrays = {}
- motion_model_col_names = motion_model.get_all_motion_model_param_names(with_errors=True)
+ motion_model_col_names = motion_model.motion_model_param_names(motion_models, with_errors=True)
for col_name in star_list.colnames:
if col_name == 'name':
# The "name" column will be 1D; but we will also add a "name_in_list" column.
@@ -1787,7 +1840,7 @@ def setup_ref_table_from_starlist(star_list):
new_col_name = "name_in_list"
else:
new_col_name = col_name
-
+
# Make every column's 2D arrays except "name" and those
# columns used for the motion model.
if col_name in motion_model_col_names:
@@ -1823,7 +1876,7 @@ def setup_ref_table_from_starlist(star_list):
if not new_cols_arr[ii] in ref_cols:
# Some munging to convert data shape from (N,1) to (N,),
# since these are all 1D cols
- vals = np.transpose(np.array(ref_table[orig_cols_arr[ii]]))[0]
+ vals =np.array(ref_table[orig_cols_arr[ii]]).flatten()
# Now add to ref_table
new_col = Column(vals, name=new_cols_arr[ii])
@@ -1832,10 +1885,10 @@ def setup_ref_table_from_starlist(star_list):
if 'use_in_trans' not in ref_table.colnames:
new_col = Column(np.ones(len(ref_table), dtype=bool), name='use_in_trans')
ref_table.add_column(new_col)
-
+
# Now reset the original values to invalids... they will be filled in
# at later times. Preserve content only in the columns: name, x0, y0, m0 (and 0e).
- # Note that these are all the 1D columsn.
+ # Note that these are all the 1D columns.
for col_name in ref_table.colnames:
if len(ref_table[col_name].data.shape) == 2: # Find the 2D columns
ref_table._set_invalid_list_values(col_name, -1)
@@ -1893,7 +1946,7 @@ def reset_ref_values(ref_table):
return
-def add_rows_for_new_stars(ref_table, star_list, idx_lis, default_motion_model='Fixed'):
+def add_rows_for_new_stars(ref_table, star_list, idx_list, motion_model='Fixed'):
"""
For each star that is in star_list and NOT in idx_list, make a
new row in the reference table. The values will be empty (None, NAN, etc.).
@@ -1902,13 +1955,13 @@ def add_rows_for_new_stars(ref_table, star_list, idx_lis, default_motion_model='
----------
ref_table : StarTable
The reference table that the rows will be added to.
-
star_list : StarList
The starlist that will be used to estimate how many new stars there are.
-
- idx_lis : array or list
+ idx_list : array or list
The indices of the non-new stars (those that matched already). The complement
of this array will be used as the new stars.
+ motion_model : str
+ The motion model to assign to the new stars.
Returns
----------
@@ -1923,9 +1976,10 @@ def add_rows_for_new_stars(ref_table, star_list, idx_lis, default_motion_model='
last_star_idx = len(ref_table)
idx_lis_orig = np.arange(len(star_list))
- idx_lis_new = np.array(list(set(idx_lis_orig) - set(idx_lis)))
+ idx_lis_new = np.array(list(set(idx_lis_orig) - set(idx_list)))
+ N_newstars = len(idx_lis_new)
- if len(idx_lis_new) > 0:
+ if N_newstars > 0:
col_arrays = {}
for col_name in ref_table.colnames:
@@ -1938,16 +1992,16 @@ def add_rows_for_new_stars(ref_table, star_list, idx_lis, default_motion_model='
elif ref_table[col_name].dtype == np.dtype('bool'):
new_col_empty = False
elif col_name=='motion_model_input':
- new_col_empty = default_motion_model
+ new_col_empty = motion_model
elif col_name=='motion_model_used':
new_col_empty = 'Fixed'
else:
new_col_empty = np.nan
if len(ref_table[col_name].shape) == 1:
- new_col_shape = len(idx_lis_new)
+ new_col_shape = N_newstars
else:
- new_col_shape = [len(idx_lis_new), ref_table[col_name].shape[1]]
+ new_col_shape = [N_newstars, ref_table[col_name].shape[1]]
new_col_data = Column(data=np.tile(new_col_empty, new_col_shape),
name=col_name, dtype=ref_table[col_name].dtype)
@@ -1961,7 +2015,7 @@ def add_rows_for_new_stars(ref_table, star_list, idx_lis, default_motion_model='
ref_table = vstack([ref_table, ref_table_new])
idx_ref_new = np.arange(last_star_idx, len(ref_table))
-
+
return ref_table, idx_lis_new, idx_ref_new
"""
@@ -2294,10 +2348,10 @@ def find_transform_new(table1_mat, table2_mat,
if transInit != None:
table1T_mat = table1_mat.copy()
- table1T_mat = transform_by_object(table1T_mat, transInit)
+ table1T_mat = transform_from_object(table1T_mat, transInit)
- x1e = table1T_mag['xe']
- y1e = table1T_mag['ye']
+ x1e = table1T_mat['xe']
+ y1e = table1T_mat['ye']
# Calculate weights as to user specification
if weights == 'both':
@@ -2382,8 +2436,7 @@ def write_transform(transform, starlist, reference, N_trans, deltaMag=0, restric
Xcoeff = transform.px.parameters
Ycoeff = transform.py.parameters
else:
- print(( '{0} not yet supported!'.format(transType)))
- return
+ raise Exception(f'{trans_name} not yet supported!')
# Write output
_out = open(outFile, 'w')
@@ -2400,7 +2453,7 @@ def write_transform(transform, starlist, reference, N_trans, deltaMag=0, restric
_out.write('## N_trans: {0}\n'.format(N_trans))
_out.write('## Delta Mag: {0}\n'.format(deltaMag))
_out.write('{0:16s} {1:16s}\n'.format('# Xcoeff', 'Ycoeff'))
-
+
# Write the coefficients such that the orders are together as defined in
# documentation. This is a pain because PolyTransform output is weird.
# (see astropy Polynomial2D documentation)
@@ -2513,7 +2566,7 @@ def transform_from_object(starlist, transform):
keys = list(starlist.keys())
# Check to see if velocities or motion_model are present in starlist.
- vel = ('vx' in keys)and ~("motion_model_input" in keys)
+ vel = ('vx' in keys) and ("motion_model_input" not in keys)
mot = ("motion_model_input" in keys)
# If the only motion models used are Fixed and Linear, we can still transform velocities.
if mot:
@@ -2577,7 +2630,7 @@ def transform_from_object(starlist, transform):
# For more complicated motion_models,
# we can't easily transform them, set the values to nans and refit later.
if mot:
- motion_model_params = motion_model.get_all_motion_model_param_names()
+ motion_model_params = motion_model.motion_model_param_names()
for param in motion_model_params:
if param in keys:
starlist_f[param] = np.nan
@@ -2611,7 +2664,7 @@ def position_transform_from_object(x, y, xe, ye, transform):
order = transform.order
else:
txt = 'Transform not yet supported by position_transform_from_object'
- raise StandardError(txt)
+ raise Exception(txt)
# How the transformation is applied depends on the type of transform.
# This can be determined by the length of Xcoeff, Ycoeff
@@ -2710,7 +2763,7 @@ def velocity_transform_from_object(x0, y0, x0e, y0e, vx, vy, vxe, vye, transform
order = transform.order
else:
txt = 'Transform not yet supported by velocity_transform_from_object'
- raise StandardError(txt)
+ raise Exception(txt)
# How the transformation is applied depends on the type of transform.
# This can be determined by the length of Xcoeff, Ycoeff
@@ -2858,7 +2911,7 @@ def check_trans_input(list_of_starlists, trans_input, mag_trans):
return
-def trans_initial_guess(ref_list, star_list, trans_args, motion_model_dict, mode='miracle',
+def trans_initial_guess(ref_list, star_list, trans_args, mode='miracle',
ignore_contains='star', verbose=True, n_req_match=3,
mag_trans=True, order=1):
"""
@@ -2896,23 +2949,24 @@ def trans_initial_guess(ref_list, star_list, trans_args, motion_model_dict, mode
# If there are velocities in the reference list, use them.
# We assume velocities are in the same units as the positions.
- xref, yref = get_pos_at_time(star_list['t'][0], ref_list, motion_model_dict)
+ xref, yref = infer_positions(star_list['t'][0], ref_list)
if 'm' in ref_list.colnames:
mref = ref_list['m']
else:
mref = ref_list['m0']
-
- N, x1m, y1m, m1m, x2m, y2m, m2m = match.miracle_match_briteN(star_list['x'],
- star_list['y'],
- star_list['m'],
- xref,
- yref,
- mref,
- briteN)
-
- err_msg = 'Failed to find more than '+str(n_req_match)
- err_msg += ' (only ' + str(len(x1m)) + ') matches, giving up.'
- assert len(x1m) >= n_req_match, err_msg
+
+ N, x1m, y1m, m1m, x2m, y2m, m2m = match.miracle_match_briteN(
+ star_list['x'],
+ star_list['y'],
+ star_list['m'],
+ xref,
+ yref,
+ mref,
+ briteN
+ )
+
+ assert len(x1m) >= n_req_match, \
+ f'Failed to find more than {n_req_match} (only {len(x1m)}) matches, giving up.'
if verbose > 1:
print('initial_guess: {0:d} stars matched between starlist and reference list'.format(N))
@@ -2931,12 +2985,12 @@ def trans_initial_guess(ref_list, star_list, trans_args, motion_model_dict, mode
trans.mag_offset = np.mean(m2m - m1m)
else:
trans.mag_offset = 0
-
+
if verbose > 1:
print('init guess: ', trans.px.parameters, trans.py.parameters)
warnings.filterwarnings('default', category=AstropyUserWarning)
-
+
return trans
@@ -3028,8 +3082,8 @@ def outlier_rejection_indices(star_list, ref_list, outlier_tol, verbose=True):
The indicies of the stars to keep.
"""
# Optionally propogate the reference positions forward in time.
- xref, yref = get_pos_in_time(star_list['t'][0], ref_list)
-
+ xref, yref = infer_positions(star_list['t'][0], ref_list)
+
# Residuals
x_resid_on_old_trans = star_list['x'] - xref
y_resid_on_old_trans = star_list['y'] - yref
@@ -3135,40 +3189,49 @@ def get_weighting_scheme(weights, ref_list, star_list):
return weight
# TODO: This is sometimes run on a startable, not a starlist, at least as currently used
-def get_pos_at_time(t, starlist, motion_model_dict):
+def infer_positions(t, startable):
"""
- Take a starlist, check to see if it has motion/velocity columns.
+ Take a startable, check to see if it has motion/velocity columns.
If it does, then propogate the positions forward in time
to the desired epoch. If no motion/velocities exist, then just
use ['x0', 'y0'] or ['x', 'y']
- Inputs
+ Parameters
----------
t_array : float
The time to propogate to. Usually in decimal years;
but it should be in the same units
as the 't0' column in starlist.
+ startable : StarTable
+ Startable that needs to be inferred.
+
+ Returns
+ -------
+ x, y : tuple
+ Inferred position at time t
"""
# Check for motion model
- if 'motion_model_used' in starlist.colnames:
- x,y,xe,ye = starlist.get_star_positions_at_time(t, motion_model_dict, allow_alt_models=True)
+ if 'motion_model_used' in startable.colnames:
+ x, y, xe, ye = startable.infer_positions(t)
+
# If no motion model, check for velocities
- elif ('vx' in starlist.colnames) and ('vy' in starlist.colnames):
- x = starlist['x0'] + starlist['vx']*(t-starlist['t0'])
- y = starlist['y0'] + starlist['vy']*(t-starlist['t0'])
+ elif ('vx' in startable.colnames) and ('vy' in startable.colnames):
+ x = startable['x0'] + startable['vx'] * (t - startable['t0'])
+ y = startable['y0'] + startable['vy'] * (t - startable['t0'])
+
# If no velocities, try fitted positon
- elif ('x0' in starlist.colnames) and ('y0' in starlist.colnames):
- x = starlist['x0']
- y = starlist['y0']
+ elif ('x0' in startable.colnames) and ('y0' in startable.colnames):
+ x = startable['x0']
+ y = startable['y0']
# Otherwise, use measured position
else:
- x = starlist['x']
- y = starlist['y']
-
- return (x, y)
+ x = startable['x']
+ y = startable['y']
+
+ return x, y
def logger(logfile, message, verbose = 9):
if verbose > 4:
print(message)
logfile.write(message + '\n')
- return
+ return
\ No newline at end of file
diff --git a/flystar/analysis.py b/flystar/analysis.py
index 3121458..55094e5 100644
--- a/flystar/analysis.py
+++ b/flystar/analysis.py
@@ -1,17 +1,11 @@
import numpy as np
import pylab as plt
-from flystar import starlists
-from flystar import startables
-from flystar import align
-from flystar import match
-from flystar import transforms
+from . import starlists, match
from astropy import table
from astropy.table import Table, Column
from astropy.coordinates import SkyCoord
from astropy import units as u
from astropy.wcs import WCS
-from astroquery.gaia import Gaia
-from astroquery.mast import Observations, Catalogs
import pdb, copy
import math
from scipy.stats import f
@@ -42,6 +36,7 @@ def query_gaia(ra, dec, search_radius=30.0, table_name='gaiadr3'):
table_name : string
Options are 'gaiadr2' or 'gaiaedr3'
"""
+ from astroquery.gaia import Gaia
target_coords = SkyCoord(ra, dec, unit=(u.hourangle, u.deg), frame='icrs')
ra = target_coords.ra.degree
dec = target_coords.dec.degree
@@ -49,7 +44,7 @@ def query_gaia(ra, dec, search_radius=30.0, table_name='gaiadr3'):
search_radius *= u.arcsec
Gaia.ROW_LIMIT = 50000
- gaia_job = Gaia.cone_search_async(target_coords, search_radius, table_name = table_name + '.gaia_source')
+ gaia_job = Gaia.cone_search_async(target_coords, radius=search_radius, table_name=table_name + '.gaia_source')
gaia = gaia_job.get_results()
#Change new 'SOURCE_ID' column header back to lowercase 'source_id' so all subsequent functions still work:
diff --git a/flystar/examples.py b/flystar/examples.py
index 8059562..65723ec 100644
--- a/flystar/examples.py
+++ b/flystar/examples.py
@@ -1,11 +1,5 @@
-from flystar import transforms
-from flystar import match
-from flystar import align
-from flystar import starlists
-from flystar import plots
import numpy as np
-import copy
-import pdb
+from . import transforms, match, align, starlists, plots
def align_example(labelFile, reference, transModel=transforms.four_paramNW, order=1, N_loop=2,
@@ -83,7 +77,7 @@ def align_example(labelFile, reference, transModel=transforms.four_paramNW, orde
trans, N_trans = align.find_transform(label[idx_label],
label_trans[idx_label],
- starlist_mat[idx_starlist],
+ starlist[idx_starlist],
transModel=transModel,
order=order, weights=weights)
diff --git a/flystar/match.py b/flystar/match.py
index d7c391e..f564cd3 100644
--- a/flystar/match.py
+++ b/flystar/match.py
@@ -1,14 +1,10 @@
import numpy as np
-from flystar import starlists, transforms, startables, align
+from . import starlists, transforms, startables
from collections import Counter
from scipy.spatial import cKDTree as KDT
-from astropy.table import Column, Table
+from astropy.table import Column
import itertools
import copy
-import scipy.signal
-from scipy.spatial import distance
-import math
-import pdb
def miracle_match_briteN(xin1, yin1, min1, xin2, yin2, min2, Nbrite,
@@ -526,6 +522,7 @@ def generic_match(sl1, sl2, init_mode='triangle',
Startable of the two matched catalogs
"""
+ from . import align
# Check the input StarLists and transform them into astropy Tables
if not isinstance(sl1, starlists.StarList):
diff --git a/flystar/motion_model.py b/flystar/motion_model.py
index 0b86d07..b69f8f2 100644
--- a/flystar/motion_model.py
+++ b/flystar/motion_model.py
@@ -1,19 +1,16 @@
import numpy as np
from abc import ABC
-import pdb
from flystar import parallax
from astropy.time import Time
-from scipy.optimize import curve_fit
+from scipy.optimize import curve_fit, OptimizeWarning
import warnings
class MotionModel(ABC):
- # Number of data points required to fit model
- n_pts_req = 0
- # Degrees of freedom for model
- n_params = 0
-
# Fit paramters: Shared fit parameters
- fitter_param_names = []
+ fit_param_names = []
+
+ # Number of fit parameters/required observations in each direction
+ n_params = int(np.ceil(len(fit_param_names) / 2))
# Fixed parameters: These are parameters that are required for the model, but are not
# fit quantities. For example, RA and Dec in a parallax model.
@@ -24,49 +21,39 @@ class MotionModel(ABC):
# These parameters should be derived from the fit parameters and
# they must exist as a variable on the model object
optional_param_names = []
+ name = "MotionModel"
def __init__(self, *args, **kwargs):
"""
- Make a motion model object. This object defines the fitter and fixed parameters,
- and if needed stores metadata such as RA and Dec for Parallax,
- for the given motion model and contains functions to fit these values to data
- and apply the values to compute expected positions at given times. Each instance
- corresponds to a given motion model, not an individual star, and thus the fit
- values are only input/returned in functions and not stored in the object.
+ Make a motion model object. This object defines the fit and fixed parameters,
+ and contains functions to fit the model to data and infer positions at given times.
+ Each instance corresponds to a given motion model, not an individual star,
+ and thus the fit values are only input/returned in functions, not stored in the object.
"""
return
+
+ def model_fit(self, dt):
+ return np.full_like(dt, np.nan)
+
+ def model(self, t, fit_params, fit_param_errs=None, fixed_params=None):
+ if fit_param_errs is None:
+ return np.full_like(t, np.nan), np.full_like(t, np.nan)
+ return np.full_like(t, np.nan), np.full_like(t, np.nan), np.full_like(t, np.inf), np.full_like(t, np.inf)
- def get_pos_at_time(self, params, t):
- """
- Position calculator for a single star using a given motion model and input
- model parameters and times.
- """
- #return x, y
- pass
-
- def get_batch_pos_at_time(self, t):
- """
- Position calculator for a set of stars using a given motion model and input
- model parameters and times.
- """
- #return x, y, x_err, y_err
- pass
-
- def run_fit(self, t, x, y, xe, ye, t0, weighting='var',
- use_scipy=True, absolute_sigma=True):
- """
- Run a single fit of the data to the motion model and return the best parameters.
- This function is used by the overall fit_motion_model function once for a basic fit
- or several times for a bootstrap fit.
- """
+ def run_fit(
+ self, t, x, y, xe, ye,
+ fixed_params_dict=None,
+ weighting='var',
+ use_scipy=True,
+ absolute_sigma=True,
+ params_guess=None,
+ fill_value=np.nan,
+ verbose=True
+ ):
# Run a single fit (used both for overall fit + bootstrap iterations)
- pass
-
- def get_weights(self, xe, ye, weighting='var'):
- """
- Get the weights for each data point for fitting. Options are 'var' (default)
- and 'std'.
- """
+ return np.full(self.n_params, fill_value), np.full(self.n_params, np.inf), np.nan, np.nan
+
+ def calc_weights(self, xe, ye, weighting='var'):
if weighting=='std':
return 1./xe, 1./ye
elif weighting=='var':
@@ -74,488 +61,1079 @@ def get_weights(self, xe, ye, weighting='var'):
else:
warnings.warn("Invalid weighting, using default weighting scheme var.", UserWarning)
return 1./xe**2, 1./ye**2
-
- def scale_errors(self, errs, weighting='var'):
- """
- Rescale the fit result errors as needed, according to the weighting scheme used.
- """
- if weighting=='std':
- return np.array(errs)**2
- elif weighting=='var':
- return errs
- else:
- warnings.warn("Invalid weighting, using default weighting scheme var.", UserWarning)
- return errs
- def fit_motion_model(self, t, x, y, xe, ye, t0, bootstrap=0, weighting='var',
- use_scipy=True, absolute_sigma=True):
- """
- Fit the input positions on the sky and errors
- to determine new parameters for this motion model (MM).
- Best-fit parameters will be returned along with uncertainties.
- Optionally, bootstrap error estimation can be performed.
+ def fit(
+ self, t, x, y, xe, ye,
+ fixed_params_dict=None,
+ weighting='var',
+ use_scipy=True,
+ absolute_sigma=True,
+ fill_value=np.nan,
+ params_guess=None,
+ return_chi2=False,
+ bootstrap=0,
+ verbose=True,
+ seed=None
+ ):
+ """Fit stellar motion parameters
+
+ Parameters
+ ----------
+ t : array-like
+ Times of measurements
+ x : array-like
+ x-coordinates
+ y : array-like
+ y-coordinates
+ xe : array-like
+ Uncertainty of x
+ ye : array-like
+ Uncertainty of y
+ fixed_params_dict : dict, optional
+ Dictionary of fixed parameters, see each motion model's fixed_param_names for details, by default None
+ weighting : str, optional
+ Use standard error weighting ('std': w=1/xe, 1/ye) or variance weighting ('var': w=1/xe**2, 1/ye**2), by default 'var'
+ use_scipy : bool, optional
+ Use scipy for optmization. Otherwise, use linear algebraic solution (Linear model only), which is faster for < 300 epochs, by default True
+ absolute_sigma : bool, optional
+ Absolute sigma. See scipy.optimize.curve_fit for details, by default True
+ fill_value : float, optional
+ Fill value for parameters when not enough data points to fit model, by default np.nan
+ params_guess : array-like, optional
+ Initial guess for the fit parameters used in scipy curve_fit, by default None
+ return_chi2 : bool, optional
+ Return chi^2 values along with parameters and uncertainties in params, param_errs, chi2_x, chi2_y, by default False
+ bootstrap : int, optional
+ Bootstrapping uncertainties, by default 0
+ verbose : bool, optional
+ Print warning messages, by default True
+ seed : int, optional
+ Seed for the random number generator, by default None
+ Returns
+ -------
+ params, params_err, chi2_x, chi2_y
+ Parameters, uncertainties, and chi squares. The corresponding parameter names are in self.fit_param_names.
"""
- params, param_errs = self.run_fit(t, x, y, xe, ye, t0=t0, weighting=weighting,
- use_scipy=use_scipy, absolute_sigma=absolute_sigma)
+ assert np.ndim(t) == np.ndim(x) == np.ndim(y) == np.ndim(xe) == np.ndim(ye) == 1, "Input arrays must be 1D! Motion model can only fit individual stars"
+ assert len(t) == len(x) == len(y) == len(xe) == len(ye), "Input arrays must have the same length!"
+ fit_result = self.run_fit(
+ t, x, y, xe, ye,
+ fixed_params_dict=fixed_params_dict,
+ weighting=weighting,
+ use_scipy=use_scipy,
+ absolute_sigma=absolute_sigma,
+ fill_value=fill_value,
+ params_guess=params_guess,
+ return_chi2=return_chi2,
+ verbose=verbose
+ )
+
+ if return_chi2:
+ params, param_errs, chi2_x, chi2_y = fit_result
+ else:
+ params, param_errs = fit_result
- if bootstrap>0 and len(x)>(self.n_pts_req):
- edx = np.arange(len(x), dtype=int)
+
+ # Bootstrap errors
+ n_obs = len(t)
+
+ if bootstrap > 0 and n_obs > (self.n_params):
+ rng = np.random.default_rng(seed)
+ edx = np.arange(n_obs, dtype=int)
+ # Precompute All Bootstrap Draws at Once
+ # Ensure there are enough unique points in each bootstrap sample
+ bdx_unique = np.stack([
+ rng.choice(edx, size=self.n_params, replace=False)
+ for _ in range(bootstrap)
+ ])
+ # Draw with replacement for the rest
+ bdx_extra = np.stack([
+ rng.choice(edx, size=n_obs - self.n_params, replace=True)
+ for _ in range(bootstrap)
+ ])
+ bdx_all = np.hstack((bdx_unique, bdx_extra))
+
bb_params = []
bb_params_errs = []
- for bb in range(bootstrap):
- bdx = np.random.choice(edx, len(x))
- while len(np.unique(bdx)) 0 else np.full_like(dt, x0)
+
+ def model(self, t, fit_params, fit_param_errs=None, fixed_params_dict=None):
+ """Predicted positions (and uncertainties, if fit_param_errs is provided) at time t of Fixed model.
+
+ Parameters
+ ----------
+ t : float or array-like
+ Time array, shape (N_times,)
+ fit_params : array-like
+ x0, y0 in shape (N_params,) or (N_stars, N_params)
+ fit_param_errs : array-like, optional
+ Uncertainties for x0, y0 in shape (N_params,) or (N_stars, N_params), by default None
+ fixed_params_dict : dict, optional
+ Not applicable for Fixed, by default None
+
+
+ Returns
+ -------
+ x, y (, xe, ye)
+ Predicted position (and uncertainties) of Fixed model, shape (N_stars, N_times), or (N_times,) if N_stars=1, or (N_stars,) if N_times=1
+ """
+ self.fixed_params_dict = fixed_params_dict
+ t = np.atleast_1d(t)
+ fit_params = np.atleast_2d(fit_params) # (N_stars, N_params)
+
+ N_stars = fit_params.shape[0] if fit_params.ndim > 1 else 1
+ N_times = len(t)
+ x0, y0 = fit_params.T # Each shape (N_stars,)
+
+ # Return results in (N_stars, N_times) shape
+ x = self.model_fit(t, x0) # Shape (N_stars, N_times)
+ y = self.model_fit(t, y0) # Shape (N_stars, N_times)
+
+ if N_stars == 1 or N_times == 1:
+ # If only one star, return flattened arrays
+ x = x.flatten()
+ y = y.flatten()
+
+ if fit_param_errs is None:
+ return x, y
+
+ fit_param_errs = np.atleast_2d(fit_param_errs) # (N_stars, N_params)
+ x0_err, y0_err = fit_param_errs.T
+
+ # Return results in (N_stars, N_times) shape
+ x_err = np.broadcast_to(x0_err[:, np.newaxis], (N_stars, N_times))
+ y_err = np.broadcast_to(y0_err[:, np.newaxis], (N_stars, N_times))
+
+ if N_stars == 1 or N_times == 1:
+ # If only one star, return flattened arrays
+ x_err = x_err.flatten()
+ y_err = y_err.flatten()
+
+ return x, y, x_err, y_err
+
+ def run_fit(
+ self, t, x, y, xe, ye,
+ fixed_params_dict=None,
+ weighting='var',
+ use_scipy=True,
+ absolute_sigma=True,
+ fill_value=np.nan,
+ params_guess=None,
+ return_chi2=False,
+ verbose=True
+ ):
+ if verbose and (not use_scipy):
+ warnings.warn("Fixed model has no non-scipy fitter option. Running with scipy.")
+
+ n_obs = len(t)
+ degree_of_freedom = n_obs - self.n_params
+ # Not enough data points to fit model
+ if degree_of_freedom < 0:
+ if verbose:
+ warnings.warn(
+ f'Not enough data points to fit model. Setting parameters to {fill_value} and uncertainties to np.inf.',
+ OptimizeWarning, stacklevel=2
+ )
+ params = np.full(self.n_params, fill_value)
+ param_errors = np.full(self.n_params, np.inf)
+ return params, param_errors, np.nan, np.nan
+
+ # degree_of_freedom >= 0
+ # Calculate weighted average position
+ x_wt, y_wt = self.calc_weights(xe, ye, weighting=weighting)
+ x_wt_norm = x_wt / np.sum(x_wt)
+ y_wt_norm = y_wt / np.sum(y_wt)
+ x0 = np.average(x, weights=x_wt)
+ x0e = (np.sum(x_wt_norm**2 * xe**2))**0.5 # Error propagation
+ y0 = np.average(y, weights=y_wt)
+ y0e = (np.sum(y_wt_norm**2 * ye**2))**0.5 # Error propagation
+
+ params = np.array([x0, y0])
+ param_errors = np.array([x0e, y0e])
+
+ if (not absolute_sigma) or return_chi2:
+ chi2x, chi2y = self.calc_chi2(t, x, y, xe, ye, params)
+
+ if not absolute_sigma:
+ if degree_of_freedom > 0:
+ reduced_chi2x = chi2x / degree_of_freedom
+ reduced_chi2y = chi2y / degree_of_freedom
+
+ param_errors[0] *= reduced_chi2x**0.5
+ param_errors[1] *= reduced_chi2y**0.5
+ else:
+ # degree_of_freedom == 0, as < 0 case already handled above
+ warnings.warn(
+ f'Degree of freedom < 0. Covariance of the parameters could not be estimated. Setting parameter uncertainties to fill value np.inf.',
+ OptimizeWarning, stacklevel=2
+ )
+ # Set parameter uncertainties to np.inf, same behavior as scipy.optimize.curve_fit
+ param_errors = np.full_like(param_errors, np.inf)
+
+ if return_chi2:
+ return params, param_errors, chi2x, chi2y
else:
- x_wt, y_wt = self.get_weights(xe,ye, weighting=weighting)
- x0 = np.average(x, weights=x_wt)
- x0e = np.sqrt(np.average((x-x0)**2,weights=x_wt))
- y0 = np.average(y, weights=y_wt)
- y0e = np.sqrt(np.average((y-y0)**2,weights=y_wt))
-
- params = [x0, y0]
- param_errors = [x0e, y0e]
-
- return params, param_errors
-
+ return params, param_errors
+
class Linear(MotionModel):
"""
A 2D linear motion model for a star on the sky.
"""
- n_pts_req = 2
- n_params=2
- fitter_param_names = ['x0', 'vx', 'y0', 'vy']
+ fit_param_names = ['x0', 'vx', 'y0', 'vy']
fixed_param_names = ['t0']
-
+
+ # Number of fit parameters/required observations in each direction
+ n_params = int(np.ceil(len(fit_param_names) / 2))
+ name = "Linear"
+
def __init__(self, **kwargs):
-
# Must call after setting parameters.
# This checks for proper parameter formatting.
super().__init__()
return
+
+ def model_fit(self, dt, x0, v):
+ """Linear motion model fit function
+
+ Parameters
+ ----------
+ dt : array-like
+ Time offset, shape (N_times,)
+ x0 : float or array-like
+ Initial position, shape (N_stars,) or scalar
+ v : float or array-like
+ Velocity, shape (N_stars,) or scalar
+
+ Returns
+ -------
+ x : array-like
+ Predicted position(s)
+ """
+ return x0 + v * dt
+
+ def model(self, t, fit_params, fit_param_errs=None, fixed_params_dict=None):
+ """Model positions (and uncertainties, if fit_param_errs is provided) at time t of Linear model.
+
+ Parameters
+ ----------
+ t : float or array-like
+ Time(s) at which to evaluate the model
+ fit_params : array-like
+ x0, vx, y0, vy in shape (N_params,) or (N_stars, N_params)
+ fit_param_errs : array-like, optional
+ Uncertainties of fit parameters in shape (N_params,) or (N_stars, N_params), by default None
+ fixed_params_dict : dict
+ t0, shape (1,) or (N_stars,)
+
+ Returns
+ -------
+ x, y (, xe, ye)
+ Predicted positions (and uncertainties, if fit_param_errs is provided) with shape (N_stars, N_times), or (N_times,) if N_stars=1, or (N_stars,) if N_times=1
+ """
+ if fixed_params_dict is None:
+ fixed_params_dict = self.fixed_params_dict
+ assert 't0' in fixed_params_dict, "Fixed parameter t0 is required for Linear model."
+
+ t = np.atleast_1d(t)
+ fit_params = np.atleast_2d(fit_params) # (N_stars, N_params)
+
+ N_stars = fit_params.shape[0] if fit_params.ndim > 1 else 1
+ N_times = len(t)
+
+ x0, vx, y0, vy = fit_params.T # Each shape (N_stars,)
+ t0 = np.atleast_1d(fixed_params_dict['t0']) # Shape (N_stars,) or (1,)
+
+ dt = t[np.newaxis, :] - t0[:, np.newaxis] # Shape (N_stars, N_times)
- def get_pos_at_time(self, fit_params, fixed_params, t):
- fit_params_dict = dict(zip(self.fitter_param_names, fit_params))
- fixed_params_dict = dict(zip(self.fixed_param_names, fixed_params))
- dt = t-fixed_params_dict['t0']
- return fit_params_dict['x0'] + fit_params_dict['vx']*dt, fit_params_dict['y0'] + fit_params_dict['vy']*dt
-
- def get_batch_pos_at_time(self, t, x0=[],vx=[], y0=[],vy=[], t0=[],
- x0_err=[],vx_err=[], y0_err=[],vy_err=[], **kwargs):
- if hasattr(t, "__len__"):
- dt = t-t0[:,np.newaxis]
- x = x0[:,np.newaxis] + dt*vx[:,np.newaxis]
- y = y0[:,np.newaxis] + dt*vy[:,np.newaxis]
- x_err = np.hypot(x0_err[:,np.newaxis], vx_err[:,np.newaxis]*dt)
- y_err = np.hypot(y0_err[:,np.newaxis], vy_err[:,np.newaxis]*dt)
- else:
- dt = t-t0
- x = x0 + dt*vx
- y = y0 + dt*vy
- x_err = np.hypot(x0_err, vx_err*dt)
- y_err = np.hypot(y0_err, vy_err*dt)
- return x,y,x_err,y_err
-
- def run_fit(self, t, x, y, xe, ye, t0, weighting='var', params_guess=None,
- use_scipy=True, absolute_sigma=True):
- dt = t-t0
- x_wt, y_wt = self.get_weights(xe,ye, weighting=weighting)
- if params_guess is None:
- params_guess = [x.mean(),0.0,y.mean(),0.0]
-
- # Handle 2-data point case
- if len(np.unique(dt))==2:
- if len(x)>2: # Catch case where bootstrap sends only 2 unique epochs
- _,idx=np.unique(dt, return_index=True)
- dt = dt[idx]
- x = x[idx]
- y = y[idx]
- xe = xe[idx]
- ye = ye[idx]
- dx = np.diff(x)[0]
- dy = np.diff(y)[0]
- dt_diff = np.diff(dt)[0]
- vx = dx / dt_diff
- vy = dy / dt_diff
- # TODO: still not sure about the error handling here
- x0 = x[0] - dt[0]*vx # np.average(x, weights=x_wt) #
- y0 = y[0] - dt[0]*vy # np.average(y, weights=y_wt) #
- x0e = np.abs(dx) / 2**0.5 # np.sqrt(np.sum(xe**2)/2) #
- y0e = np.abs(dy) / 2**0.5 # np.sqrt(np.sum(ye**2)/2) #
- vxe = 0.0 #np.abs(vx) * np.sqrt(np.sum(xe**2/x**2))
- vye = 0.0 #np.abs(vy) * np.sqrt(np.sum(ye**2/y**2))
-
- else:
- if use_scipy:
- def linear(t, c0, c1):
- return c0 + c1*t
- x_opt, x_cov = curve_fit(linear, dt, x, p0=np.array(params_guess[:2]), sigma=1/np.sqrt(x_wt), absolute_sigma=absolute_sigma)
- y_opt, y_cov = curve_fit(linear, dt, y, p0=np.array(params_guess[2:]), sigma=1/np.sqrt(y_wt), absolute_sigma=absolute_sigma)
- x0, vx = x_opt
- y0, vy = y_opt
- x0e, vxe = np.sqrt(x_cov.diagonal())
- y0e, vye = np.sqrt(y_cov.diagonal())
- x0e, vxe, y0e, vye = self.scale_errors([x0e, vxe, y0e, vye], weighting=weighting)
- else:
- # Use https://en.wikipedia.org/wiki/Weighted_least_squares#Solution scheme
- x = np.array(x)
- y = np.array(y)
- dt = np.array(dt)
- X_mat_t = np.vander(dt, 2)
- # x calculation
- W_mat_x = np.diag(x_wt)
- XTWX_mat_x = X_mat_t.T @ W_mat_x @ X_mat_t
- pcov_x = np.linalg.inv(XTWX_mat_x) # Covariance Matrix
- popt_x = pcov_x @ X_mat_t.T @ W_mat_x @ x # Linear Solution
- perr_x = np.sqrt(np.diag(pcov_x)) # Uncertainty of Linear Solution
- # y calculation
- W_mat_y = np.diag(y_wt)
- XTWX_mat_y = X_mat_t.T @ W_mat_y @ X_mat_t
- pcov_y = np.linalg.inv(XTWX_mat_y) # Covariance Matrix
- popt_y = pcov_y @ X_mat_t.T @ W_mat_y @ y # Linear Solution
- perr_y = np.sqrt(np.diag(pcov_y)) # Uncertainty of Linear Solution
- # prepare values to return
- x0, vx = popt_x[1], popt_x[0]
- y0, vy = popt_y[1], popt_y[0]
- x0e, vxe = perr_x[1], perr_x[0]
- y0e, vye = perr_y[1], perr_y[0]
- x0e, vxe, y0e, vye = self.scale_errors([x0e, vxe, y0e, vye], weighting=weighting)
+ x = self.model_fit(dt, x0[:, np.newaxis], vx[:, np.newaxis]) # Shape (N_stars, N_times)
+ y = self.model_fit(dt, y0[:, np.newaxis], vy[:, np.newaxis]) # Shape (N_stars, N_times)
+
+ if N_stars == 1 or N_times == 1:
+ # If only one star, return flattened arrays
+ x = x.flatten()
+ y = y.flatten()
+
+ if fit_param_errs is None:
+ return x, y
- params = [x0, vx, y0, vy]
- param_errors = [x0e, vxe, y0e, vye]
- return params, param_errors
+ fit_param_errs = np.atleast_2d(fit_param_errs) # (N_stars, N_params)
+ x0_err, vx_err, y0_err, vy_err = fit_param_errs.T # Each shape (N_stars,)
+ x_err = np.hypot(x0_err[:, np.newaxis], vx_err[:, np.newaxis] * dt) # Shape (N_stars, N_times)
+ y_err = np.hypot(y0_err[:, np.newaxis], vy_err[:, np.newaxis] * dt) # Shape (N_stars, N_times)
+ if N_stars == 1 or N_times == 1:
+ # If only one star, return flattened arrays
+ x_err = x_err.flatten()
+ y_err = y_err.flatten()
+ return x, y, x_err, y_err
+
+ def run_fit(
+ self, t, x, y, xe, ye,
+ fixed_params_dict=None,
+ weighting='var',
+ use_scipy=True,
+ absolute_sigma=True,
+ fill_value=np.nan,
+ params_guess=None,
+ return_chi2=False,
+ verbose=True
+ ):
+ if fixed_params_dict is None:
+ fixed_params_dict = {}
+ if 't0' not in fixed_params_dict:
+ # Default t0 to weighted average time
+ fixed_params_dict['t0'] = np.average(t, weights=1./np.hypot(xe, ye))
+ self.fixed_params_dict = fixed_params_dict
+ t0 = np.atleast_1d(fixed_params_dict['t0'])
+ t = np.atleast_1d(t)
+ x = np.atleast_1d(x)
+ y = np.atleast_1d(y)
+ xe = np.atleast_1d(xe)
+ ye = np.atleast_1d(ye)
+ n_obs = len(t)
+ degree_of_freedom = n_obs - self.n_params
+ # Not enough data points to fit model
+ if degree_of_freedom < 0:
+ if verbose:
+ warnings.warn(
+ f'Not enough data points to fit model. Setting parameters to {fill_value} and uncertainties to np.inf.',
+ OptimizeWarning, stacklevel=2
+ )
+ params = np.full(self.n_params, fill_value)
+ param_errors = np.full(self.n_params, np.inf)
+ if return_chi2:
+ return params, param_errors, np.nan, np.nan
+ else:
+ return params, param_errors
+
+ # degree_of_freedom >= 0
+ dt = t - t0
+ x_wt, y_wt = self.calc_weights(xe, ye, weighting=weighting)
+ if params_guess is None:
+ params_guess = [x.mean(), 0., y.mean(), 0.]
+
+ if use_scipy:
+ x_opt, x_cov = curve_fit(self.model_fit, dt, x, p0=np.array(params_guess[:2]), sigma=1/x_wt**0.5, absolute_sigma=absolute_sigma)
+ y_opt, y_cov = curve_fit(self.model_fit, dt, y, p0=np.array(params_guess[2:]), sigma=1/y_wt**0.5, absolute_sigma=absolute_sigma)
+ x0, vx = x_opt
+ y0, vy = y_opt
+ x0e, vxe = np.sqrt(x_cov.diagonal())
+ y0e, vye = np.sqrt(y_cov.diagonal())
+ params = np.array([x0, vx, y0, vy])
+ param_errors = np.array([x0e, vxe, y0e, vye])
+ if return_chi2:
+ chi2_x, chi2_y = self.calc_chi2(t, x, y, xe, ye, params, fixed_params_dict)
+ return params, param_errors, chi2_x, chi2_y
+ else:
+ return params, param_errors
+
+ # Linear algebraic solution
+ # Use https://en.wikipedia.org/wiki/Weighted_least_squares#Solution_scheme
+ X_mat_t = np.vander(dt, 2)
+ # x calculation
+ W_mat_x = np.diag(x_wt)
+ XTWX_mat_x = X_mat_t.T @ W_mat_x @ X_mat_t
+ pcov_x = np.linalg.inv(XTWX_mat_x) # Covariance Matrix
+ popt_x = pcov_x @ X_mat_t.T @ W_mat_x @ x # Linear Solution
+ perr_x = np.sqrt(np.diag(pcov_x)) # Uncertainty of Linear Solution
+ # y calculation
+ W_mat_y = np.diag(y_wt)
+ XTWX_mat_y = X_mat_t.T @ W_mat_y @ X_mat_t
+ pcov_y = np.linalg.inv(XTWX_mat_y) # Covariance Matrix
+ popt_y = pcov_y @ X_mat_t.T @ W_mat_y @ y # Linear Solution
+ perr_y = np.sqrt(np.diag(pcov_y)) # Uncertainty of Linear Solution
+ # prepare values to return
+ vx, x0 = popt_x
+ vy, y0 = popt_y
+ vxe, x0e = perr_x
+ vye, y0e = perr_y
+
+ params = np.array([x0, vx, y0, vy])
+ param_errors = np.array([x0e, vxe, y0e, vye])
+
+ # Does not use get_chi2 to accelerate calculation
+ if return_chi2 or (not absolute_sigma):
+ residual_x = x - X_mat_t @ popt_x
+ residual_y = y - X_mat_t @ popt_y
+
+ chi2_x = residual_x.T @ W_mat_x @ residual_x
+ chi2_y = residual_y.T @ W_mat_y @ residual_y
+
+ if not absolute_sigma:
+ if degree_of_freedom > 0:
+ reduced_chi2_x = chi2_x / degree_of_freedom
+ reduced_chi2_y = chi2_y / degree_of_freedom
+
+ param_errors[0:2] *= reduced_chi2_x**0.5
+ param_errors[2:4] *= reduced_chi2_y**0.5
+
+ else:
+ # degree_of_freedom == 0, as < 0 case already handled above
+ warnings.warn(
+ f'Degree of freedom < 0. Covariance of the parameters could not be estimated. Setting parameter uncertainties to fill value np.inf.',
+ OptimizeWarning, stacklevel=2
+ )
+ # Set parameter uncertainties to np.inf, same behavior as scipy.optimize.curve_fit
+ param_errors = np.full_like(param_errors, np.inf)
+
+ if return_chi2:
+ return params, param_errors, chi2_x, chi2_y
+ else:
+ return params, param_errors
+
class Acceleration(MotionModel):
"""
A 2D accelerating motion model for a star on the sky.
"""
- n_pts_req = 4 # TODO: consider special case for 3 pts
- n_params=3
- fitter_param_names = ['x0', 'vx0', 'ax', 'y0', 'vy0', 'ay']
+ fit_param_names = ['x0', 'vx0', 'ax', 'y0', 'vy0', 'ay']
fixed_param_names = ['t0']
-
- def __init__(self, x0=0, vx0=0, ax=0, y0=0, vy0=0, ay=0, t0=None,
- x0_err=0, vx0_err=0, ax_err=0, y0_err=0, vy0_err=0, ay_err=0, **kwargs):
+ name = "Acceleration"
+
+ # Number of fit parameters/required observations in each direction
+ n_params = int(np.ceil(len(fit_param_names) / 2))
+
+ def __init__(self):
# Must call after setting parameters.
# This checks for proper parameter formatting.
super().__init__()
return
+
+ def model_fit(self, t, x0, v0, a):
+ """Model positions at time t of Acceleration model.
+
+ Parameters
+ ----------
+ t : float or array-like
+ Time(s) at which to evaluate the model
+ x0 : float or array-like
+ Initial position(s)
+ v0 : float or array-like
+ Initial velocity(ies)
+ a : float or array-like
+ Acceleration(s)
+
+ Returns
+ -------
+ float or array-like
+ Model positions at time t of Acceleration model
+ """
+ return x0 + v0*t + 0.5*a*t**2
+
+ def model(self, t, fit_params, fit_param_errs=None, fixed_params_dict=None):
+ """Model positions (and uncertainties, if fit_param_errs is provided) at time t of Acceleration model.
+
+ Parameters
+ ----------
+ t : float or array-like
+ Time(s) at which to evaluate the model
+ fit_params : array-like
+ x0, vx, ax, y0, vy, ay in shape (N_params,) or (N_stars, N_params)
+ fit_param_errs : array-like, optional
+ Fit parameter uncertainties with shape (N_stars, N_params) or (N_params,), by default None
+ fixed_params_dict : dict
+ t0, shape (1,) or (N_stars,)
+
+ Returns
+ -------
+ x, y (, xe, ye)
+ Predicted positions (and uncertainties, if fit_param_errs is provided) with shape (N_stars, N_times), or (N_times,) if N_stars=1, or (N_stars,) if N_times=1
+ """
+ if fixed_params_dict is None:
+ fixed_params_dict = self.fixed_params_dict
+ assert 't0' in fixed_params_dict, "Fixed parameter t0 is required for Acceleration model."
+
+ t = np.atleast_1d(t)
+ fit_params = np.atleast_2d(fit_params) # (N_stars, N_params)
+
+ N_stars = fit_params.shape[0] if fit_params.ndim > 1 else 1
+ N_times = len(t)
- def get_pos_at_time(self, fit_params, fixed_params, t):
- fit_params_dict = dict(zip(self.fitter_param_names, fit_params))
- fixed_params_dict = dict(zip(self.fixed_param_names, fixed_params))
- dt = t-fixed_params_dict['t0']
- x = fit_params_dict['x0'] + fit_params_dict['vx0']*dt + 0.5*fit_params_dict['ax']*dt**2
- y = fit_params_dict['y0'] + fit_params_dict['vy0']*dt + 0.5*fit_params_dict['ay']*dt**2
- return x, y
+ x0, vx0, ax, y0, vy0, ay = fit_params.T # Each shape (N_stars,)
+ t0 = np.atleast_1d(fixed_params_dict['t0']) # Shape (N_stars,) or (1,)
- def get_batch_pos_at_time(self,t,
- x0=[],vx0=[],ax=[], y0=[],vy0=[],ay=[], t0=[],
- x0_err=[],vx0_err=[],ax_err=[], y0_err=[],vy0_err=[],ay_err=[], **kwargs):
- if hasattr(t, "__len__"):
- dt = t-t0[:,np.newaxis]
- x = x0[:,np.newaxis] + dt*vx0[:,np.newaxis] + 0.5*dt**2*ax[:,np.newaxis]
- y = y0[:,np.newaxis] + dt*vy0[:,np.newaxis] + 0.5*dt**2*ay[:,np.newaxis]
- x_err = np.sqrt(x0_err[:,np.newaxis]**2 + (vx0_err[:,np.newaxis]*dt)**2 + (0.5*ax_err[:,np.newaxis]*dt**2)**2)
- y_err = np.sqrt(y0_err[:,np.newaxis]**2 + (vy0_err[:,np.newaxis]*dt)**2 + (0.5*ay_err[:,np.newaxis]*dt**2)**2)
- else:
- dt = t-t0
- x = x0 + dt*vx0 + 0.5*dt**2*ax
- y = y0 + dt*vy0 + 0.5*dt**2*ay
- x_err = np.sqrt(x0_err**2 + (vx0_err*dt)**2 + (0.5*ax_err*dt**2)**2)
- y_err = np.sqrt(y0_err**2 + (vy0_err*dt)**2 + (0.5*ay_err*dt**2)**2)
- return x,y,x_err,y_err
-
- def run_fit(self, t, x, y, xe, ye, t0, weighting='var', params_guess=None,
- use_scipy=True, absolute_sigma=True):
+ dt = t[np.newaxis, :] - t0[:, np.newaxis] # Shape (N_stars, N_times)
+
+ x = self.model_fit(dt, x0[:, np.newaxis], vx0[:, np.newaxis], ax[:, np.newaxis]) # Shape (N_stars, N_times)
+ y = self.model_fit(dt, y0[:, np.newaxis], vy0[:, np.newaxis], ay[:, np.newaxis]) # Shape (N_stars, N_times)
+
+ if N_stars == 1 or N_times == 1:
+ # If only one star, return flattened arrays
+ x = x.flatten()
+ y = y.flatten()
+
+ if fit_param_errs is None:
+ return x, y
+
+ fit_param_errs = np.atleast_2d(fit_param_errs) # (N_stars, N_params)
+ x0_err, vx0_err, ax_err, y0_err, vy0_err, ay_err = fit_param_errs.T
+ x_err = np.sqrt(x0_err[:, np.newaxis]**2 + (vx0_err[:, np.newaxis] * dt)**2 + (0.5 * ax_err[:, np.newaxis] * dt**2)**2) # Shape (N_stars, N_times)
+ y_err = np.sqrt(y0_err[:, np.newaxis]**2 + (vy0_err[:, np.newaxis] * dt)**2 + (0.5 * ay_err[:, np.newaxis] * dt**2)**2) # Shape (N_stars, N_times)
+
+ if N_stars == 1 or N_times == 1:
+ # If only one star, return flattened arrays
+ x_err = x_err.flatten()
+ y_err = y_err.flatten()
+
+ return x, y, x_err, y_err
+
+
+ def run_fit(
+ self, t, x, y, xe, ye,
+ fixed_params_dict=None,
+ weighting='var',
+ use_scipy=True,
+ absolute_sigma=True,
+ params_guess=None,
+ fill_value=np.nan,
+ return_chi2=False,
+ verbose=True
+ ):
+ if fixed_params_dict is None:
+ fixed_params_dict = {}
+ if 't0' not in fixed_params_dict:
+ # Default t0 to weighted average time
+ fixed_params_dict['t0'] = np.average(t, weights=1./np.hypot(xe, ye))
+ self.fixed_params_dict = fixed_params_dict
+ t0 = np.atleast_1d(fixed_params_dict['t0'])
+ t = np.atleast_1d(t)
+ x = np.atleast_1d(x)
+ y = np.atleast_1d(y)
+ xe = np.atleast_1d(xe)
+ ye = np.atleast_1d(ye)
+
if not use_scipy:
- Warning("Acceleration model has no non-scipy fitter option. Running with scipy.")
- dt = t-t0
- x_wt, y_wt = self.get_weights(xe,ye, weighting=weighting)
+ if verbose:
+ warnings.warn("Acceleration model has no non-scipy fitter option. Running with scipy.")
+
+ n_obs = len(t)
+ degree_of_freedom = n_obs - self.n_params
+ # Not enough data points to fit model
+ if degree_of_freedom < 0:
+ if verbose:
+ warnings.warn(
+ f'Not enough data points to fit model. Setting parameters to {fill_value} and uncertainties to np.inf.',
+ OptimizeWarning, stacklevel=2
+ )
+ params = np.full(self.n_params, fill_value)
+ param_errors = np.full(self.n_params, np.inf)
+ if return_chi2:
+ return params, param_errors, np.nan, np.nan
+ else:
+ return params, param_errors
+
+ # degree_of_freedom >= 0
+ dt = t - t0
+ x_wt, y_wt = self.calc_weights(xe,ye, weighting=weighting)
if params_guess is None:
- params_guess = [x.mean(),0.0,0.0,y.mean(),0.0,0.0]
-
- def accel(t, c0,c1,c2):
- return c0 + c1*t + 0.5*c2*t**2
-
- x_opt, x_cov = curve_fit(accel, dt, x, p0=np.array(params_guess[:3]), sigma=1/x_wt**0.5, absolute_sigma=True)
- y_opt, y_cov = curve_fit(accel, dt, y, p0=np.array(params_guess[3:]), sigma=1/y_wt**0.5, absolute_sigma=True)
- x0 = x_opt[0]
- y0 = y_opt[0]
- vx0 = x_opt[1]
- vy0 = y_opt[1]
- ax = x_opt[2]
- ay = y_opt[2]
-
+ # Initial guess for velocity:
+ idx_first, idx_last = np.argmin(t), np.argmax(t)
+ t_span = t[idx_last] - t[idx_first]
+ params_guess = [x.mean(), (x[idx_last] - x[idx_first]) / t_span, 0., y.mean(), (y[idx_last] - y[idx_first]) / t_span, 0.]
+
+ x_opt, x_cov = curve_fit(self.model_fit, dt, x, p0=np.array(params_guess[:3]), sigma=1/x_wt**0.5, absolute_sigma=absolute_sigma)
+ y_opt, y_cov = curve_fit(self.model_fit, dt, y, p0=np.array(params_guess[3:]), sigma=1/y_wt**0.5, absolute_sigma=absolute_sigma)
+ x0, vx0, ax = x_opt
+ y0, vy0, ay = y_opt
x0e, vx0e, axe = np.sqrt(x_cov.diagonal())
y0e, vy0e, aye = np.sqrt(y_cov.diagonal())
- x0e, vx0e, axe, y0e, vy0e, aye = self.scale_errors([x0e, vx0e, axe, y0e, vy0e, aye], weighting=weighting)
- params = [x0, vx0, ax, y0, vy0, ay]
- param_errors = [x0e, vx0e, axe, y0e, vy0e, aye]
-
- return params, param_errors
+ params = np.array([x0, vx0, ax, y0, vy0, ay])
+ param_errors = np.array([x0e, vx0e, axe, y0e, vy0e, aye])
+ if return_chi2:
+ chi2_x, chi2_y = self.calc_chi2(t, x, y, xe, ye, params, fixed_params_dict)
+ return params, param_errors, chi2_x, chi2_y
+ else:
+ return params, param_errors
class Parallax(MotionModel):
"""
Motion model for linear proper motion + parallax
- Requires RA & Dec (J2000) for parallax calculation.
+ Requires RA and Dec J2000 (degrees) for parallax calculation.
Optional PA is counterclockwise offset of the image y-axis from North.
Optional obs parameter describes observer location, default is 'earth'.
"""
- n_pts_req = 4
- n_params=3
- fitter_param_names = ['x0', 'vx', 'y0', 'vy', 'pi']
- fixed_param_names = ['t0']
- fixed_meta_data = ['RA','Dec','PA','obs']
-
- def __init__(self, RA, Dec, PA=0.0, obs='earth', **kwargs):
- self.RA = RA
- self.Dec = Dec
- self.PA = PA
- self.obs = obs
- self.plx_vector_cached = None
- return
+ fit_param_names = ['x0', 'vx', 'y0', 'vy', 'pi']
+ fixed_param_names = ['t0', 'ra', 'dec', 'pa', 'obsLocation']
+ name = "Parallax"
- def get_parallax_vector(self, t_mjd):
- recalc_plx = True
+ # Number of fit parameters/required observations in each direction
+ n_params = int(np.ceil(len(fit_param_names) / 2))
+
+ def __init__(self):
+ super().__init__()
+ self.plx_vector_cached = None # Cache for parallax vector
+ return
+
+ def calc_parallax_vector(self, t_mjd, ra, dec, pa=0., obsLocation='earth'):
+ """Calculate parallax vector of shape (2, N_times)
+
+ Parameters
+ ----------
+ t_mjd : array-like
+ Time array in mjd
+ ra : float or array-like
+ Right ascension(s) in degrees
+ dec : float or array-like
+ Declination(s) in degrees
+ pa : float or array-like, optional
+ Position angle(s) of image y-axis from North in degrees, by default 0.
+ obsLocation : str, optional
+ Observer location, by default 'earth'
+
+ Returns
+ -------
+ pvec
+ Parallax vector of shape (2, N_times)
+ """
if self.plx_vector_cached is not None:
- if hasattr(t_mjd, "__len__"):
- if list(t_mjd) == list(self.plx_vector_cached[0]):
- pvec = self.plx_vector_cached[1:]
- recalc_plx = False
- elif all([t_mjd_i in self.plx_vector_cached[0] for t_mjd_i in t_mjd]):
- pvec_idxs = [np.argwhere(self.plx_vector_cached[0]==t_mjd_i)[0][0] for t_mjd_i in t_mjd]
- pvec = [self.plx_vector_cached[1][pvec_idxs], self.plx_vector_cached[2][pvec_idxs]]
- recalc_plx = False
- elif t_mjd in self.plx_vector_cached[0]:
- idx = np.where(t_mjd==self.plx_vector_cached[0])[0][0]
- pvec = np.array([self.plx_vector_cached[1][idx], self.plx_vector_cached[2][idx]])
- recalc_plx = False
- if recalc_plx:
- pvec = parallax.parallax_in_direction(self.RA, self.Dec, t_mjd, obsLocation=self.obs, PA=self.PA).T
- if hasattr(t_mjd, "__len__"):
- self.plx_vector_cached = [t_mjd, pvec[0], pvec[1]]
+ t_mjd = np.atleast_1d(t_mjd)
+ t_mjd_cached = self.plx_vector_cached[0]
+ if np.array_equal(t_mjd, t_mjd_cached):
+ # If cached values match input times, return cached values
+ return self.plx_vector_cached[1]
+
+ elif all(np.isin(t_mjd, t_mjd_cached)):
+ # If all input times are in cached values, return those
+ # Calculate pvec_idxs such that t_mjd_cached[ pvec_idxs ] == t_mjd
+ pvec_idxs = np.array([np.where(t_mjd_cached == t_mjd_i)[0][0] for t_mjd_i in t_mjd])
+ pvec = self.plx_vector_cached[1][:, pvec_idxs]
+ return pvec
+
+ pvec = parallax.parallax_in_direction(ra, dec, t_mjd, obsLocation=obsLocation, pa=pa)
+ self.plx_vector_cached = [t_mjd, pvec]
return pvec
+
+ def model_fit(self, dt, x0, vx, y0, vy, pi):
+ """Model positions at time t of Parallax model.
+
+ Parameters
+ ----------
+ dt : float or array-like
+ Time(s) at which to evaluate the model
+ x0 : float or array-like
+ Initial position(s)
+ vx : float or array-like
+ Velocity(ies)
+ y0 : float or array-like
+ Initial position(s)
+ vy : float or array-like
+ Velocity(ies)
+ pi : float or array-like
+ Parallax factor(s)
+
+ Returns
+ -------
+ x_res, y_res : array-like
+ Model positions at time t of Parallax model
+ """
+ # x0, vx, y0, vy, pi are all shape (N_stars, N_times)
+ x_res = x0 + vx * dt + pi * self.pvec[0]
+ y_res = y0 + vy * dt + pi * self.pvec[1]
+ return x_res, y_res
+
+ def _model_fit(self, dt, x0, vx, y0, vy, pi):
+ """Wrapper for model_fit to return concatenated results for scipy fitting."""
+ x_res, y_res = self.model_fit(dt, x0, vx, y0, vy, pi)
+ return np.hstack([x_res, y_res]) # Shape (N_stars, 2*N_times)
+
+ def model(self, t, fit_params, fit_param_errs=None, fixed_params_dict=None):
+ """Model positions (and uncertainties, if fit_param_errs is provided) at time t of Parallax model.
+
+ Parameters
+ ----------
+ t : float or array-like
+ Times at which to evaluate the model
+ fit_params : array-like
+ x0, vx, y0, vy, pi in shape (N_params,) or (N_stars, N_params)
+ fit_param_errs : array-like, optional
+ Uncertainties in fit parameters, by default None
+ fixed_params : dict
+ - t0, shape (N_stars,) or (1,).
+ - ra, shape (N_stars,) or (1,).
+ - dec, shape (N_stars,) or (1,).
+ - pa, optional, shape (N_stars,) or (1,), by default 0.
+ - obsLocation, optional, string, by default 'earth'
+
+ Returns
+ -------
+ x, y (, xe, ye)
+ Predicted positions (and uncertainties, if fit_param_errs is provided) with shape (N_stars, N_times), or (N_times,) if N_stars=1, or (N_stars,) if N_times=1
+ """
+ if fixed_params_dict is None:
+ fixed_params_dict = self.fixed_params_dict
+ assert all([_ in fixed_params_dict for _ in ['t0', 'ra', 'dec']]), "Fixed parameters t0, ra, and dec are required for Parallax model."
+
+ t = np.atleast_1d(t)
+ fit_params = np.atleast_2d(fit_params) # (N_stars, N_params)
+ N_stars = fit_params.shape[0] if fit_params.ndim > 1 else 1
+ N_times = len(t)
+
+ x0, vx, y0, vy, pi = fit_params.T # Each shape (N_stars,)
+ t0 = np.atleast_1d(fixed_params_dict['t0']) # Shape (N_stars,) or (1,)
+ ra = np.atleast_1d(fixed_params_dict['ra'])
+ dec = np.atleast_1d(fixed_params_dict['dec'])
+ pa = np.atleast_1d(fixed_params_dict.get('pa', 0.0))
+ obsLocation = fixed_params_dict.get('obsLocation', 'earth')
+
+ # TODO: vectorize parallax.parallax_in_direction to handle multiple obsLocation?
- def get_pos_at_time(self, fit_params, fixed_params, t):
- fit_params_dict = dict(zip(self.fitter_param_names, fit_params))
- fixed_params_dict = dict(zip(self.fixed_param_names, fixed_params))
- dt = t-fixed_params_dict['t0']
-
- t_mjd = Time(t, format='decimalyear', scale='utc').mjd
- pvec = self.get_parallax_vector(t_mjd)
- pvec_x = np.reshape(pvec[0], t.shape)
- pvec_y = np.reshape(pvec[1], t.shape)
- x = fit_params_dict['x0'] + fit_params_dict['vx']*dt + fit_params_dict['pi']*pvec_x
- y = fit_params_dict['y0'] + fit_params_dict['vy']*dt + fit_params_dict['pi']*pvec_y
- return x, y
+ assert (type(obsLocation) == str) or (np.unique(obsLocation).size == 1), "obsLocation must be a single string for all stars at this time."
+ if type(obsLocation) != str:
+ obsLocation = np.unique(obsLocation)[0]
+
+ dt = t[np.newaxis, :] - t0[:, np.newaxis] # Shape (N_stars, N_times)
+ t_mjd = Time(t, format='decimalyear', scale='utc').mjd # Shape (N_times,)
+ self.pvec = self.calc_parallax_vector(t_mjd, ra, dec, pa=pa, obsLocation=obsLocation) # Shape (2, N_times)
+ x, y = self.model_fit(dt, x0[:, np.newaxis], vx[:, np.newaxis], y0[:, np.newaxis], vy[:, np.newaxis], pi[:, np.newaxis]) # Shape (N_stars, N_times)
+
+ if N_stars == 1 or N_times == 1:
+ # If only one star, return flattened arrays
+ x = x.flatten()
+ y = y.flatten()
+
+ if fit_param_errs is None:
+ return x, y
+
+ fit_param_errs = np.atleast_2d(fit_param_errs) # (N_stars, N_params)
+ x0_err, vx_err, y0_err, vy_err, pi_err = fit_param_errs.T
+ x_err = np.sqrt(x0_err[:, np.newaxis]**2 + (vx_err[:, np.newaxis] * dt)**2 + (pi_err[:, np.newaxis] * self.pvec[0][np.newaxis, :])**2) # Shape (N_stars, N_times)
+ y_err = np.sqrt(y0_err[:, np.newaxis]**2 + (vy_err[:, np.newaxis] * dt)**2 + (pi_err[:, np.newaxis] * self.pvec[1][np.newaxis, :])**2) # Shape (N_stars, N_times)
- def get_batch_pos_at_time(self, t,
- x0=[],vx=[], y0=[],vy=[], pi=[], t0=[],
- x0_err=[],vx_err=[], y0_err=[],vy_err=[], pi_err=[], **kwargs):
- t_mjd = Time(t, format='decimalyear', scale='utc').mjd
- pvec = self.get_parallax_vector(t_mjd)
- if hasattr(t, "__len__"):
- dt = t-t0[:,np.newaxis]
- x = x0[:,np.newaxis] + dt*vx[:,np.newaxis] + pi[:,np.newaxis]*pvec[0].T
- y = y0[:,np.newaxis] + dt*vy[:,np.newaxis] + pi[:,np.newaxis]*pvec[1].T
- try:
- x_err = np.sqrt(x0_err[:,np.newaxis]**2 + (vx_err[:,np.newaxis]*dt)**2 + (pi_err[:,np.newaxis]*pvec[0].T)**2)
- y_err = np.sqrt(y0_err[:,np.newaxis]**2 + (vy_err[:,np.newaxis]*dt)**2 + (pi_err[:,np.newaxis]*pvec[1].T)**2)
- except:
- x_err,y_err = [],[]
- else:
- dt = t-t0
- x = x0 + dt*vx + pi*pvec[0]
- y = y0 + dt*vy + pi*pvec[1]
- try:
- x_err = np.sqrt(x0_err**2 + (vx_err*dt)**2 + (pi_err*pvec[0])**2)
- y_err = np.sqrt(y0_err**2 + (vy_err*dt)**2 + (pi_err*pvec[1])**2)
- except:
- x_err,y_err = [],[]
- return x,y,x_err,y_err
-
- def run_fit(self, t, x, y, xe, ye, t0, weighting='var', params_guess=None,
- use_scipy=True, absolute_sigma=True):
+ if N_stars == 1 or N_times == 1:
+ # If only one star, return flattened arrays
+ x_err = x_err.flatten()
+ y_err = y_err.flatten()
+ return x, y, x_err, y_err
+
+
+ def run_fit(
+ self, t, x, y, xe, ye,
+ fixed_params_dict,
+ weighting='var',
+ use_scipy=True,
+ absolute_sigma=True,
+ params_guess=None,
+ fill_value=np.nan,
+ return_chi2=False,
+ verbose=True
+ ):
if not use_scipy:
- Warning("Parallax model has no non-scipy fitter option. Running with scipy.")
+ if verbose:
+ warnings.warn("Parallax model has no non-scipy fitter option. Running with scipy.", UserWarning)
+
+ assert all([k in fixed_params_dict for k in ['ra', 'dec']]), "Parallax model requires 'ra' and 'dec' in fixed_params."
+ t = np.atleast_1d(t)
+
+ if 't0' not in fixed_params_dict:
+ # Default t0 to weighted average time
+ fixed_params_dict['t0'] = np.average(t, weights=1./np.hypot(xe, ye))
+ if 'obsLocation' not in fixed_params_dict:
+ fixed_params_dict['obsLocation'] = 'earth'
+ self.fixed_params_dict = fixed_params_dict
+ t0 = np.atleast_1d(fixed_params_dict['t0'])
+ ra = np.atleast_1d(fixed_params_dict['ra'])
+ dec = np.atleast_1d(fixed_params_dict['dec'])
+ pa = np.atleast_1d(fixed_params_dict.get('pa', 0.0))
+ obsLocation = fixed_params_dict['obsLocation']
+
+ n_fit = len(t)
+ degree_of_freedom = n_fit - self.n_params
+ # Not enough data points to fit model
+ if degree_of_freedom < 0:
+ if verbose:
+ warnings.warn(
+ f'Not enough data points to fit model. Setting parameters to {fill_value} and uncertainties to np.inf.',
+ OptimizeWarning, stacklevel=2
+ )
+ params = np.full(self.n_params, fill_value)
+ param_errors = np.full(self.n_params, np.inf)
+ if return_chi2:
+ return params, param_errors, np.nan, np.nan
+ else:
+ return params, param_errors
+
+ # degree_of_freedom >= 0
t_mjd = Time(t, format='decimalyear', scale='utc').mjd
- pvec = self.get_parallax_vector(t_mjd)
- x_wt, y_wt = self.get_weights(xe,ye, weighting=weighting)
- def fit_func(use_t, x0,vx, y0,vy, pi):
- x_res = x0 + vx*(use_t-t0) + pi*pvec[0]
- y_res = y0 + vy*(use_t-t0) + pi*pvec[1]
- return np.hstack([x_res, y_res])
+ self.pvec = self.calc_parallax_vector(t_mjd, ra, dec, pa=pa, obsLocation=obsLocation) # Shape (2, N_times)
+ x_wt, y_wt = self.calc_weights(xe, ye, weighting=weighting)
+
# Initial guesses, x0,y0 as x,y averages;
# vx,vy as average velocity if first and last points are perfectly measured;
- # pi for 10 pc disance
+ # pi for 10 pc distance
if params_guess is None:
idx_first, idx_last = np.argmin(t), np.argmax(t)
- params_guess = [x.mean(),(x[idx_last]-x[idx_first])/(t[idx_last]-t[idx_first]),
- y.mean(),(y[idx_last]-y[idx_first])/(t[idx_last]-t[idx_first]), 0.1]
- res = curve_fit(fit_func, t, np.hstack([x,y]),
- p0=params_guess, sigma = 1.0/np.hstack([x_wt,y_wt]))
- x0,vx,y0,vy,pi = res[0]
- x0_err,vx_err,y0_err,vy_err,pi_err = self.scale_errors(np.sqrt(np.diag(res[1])), weighting=weighting)
-
- params = [x0, vx, y0, vy, pi]
- param_errors = [x0_err, vx_err, y0_err, vy_err, pi_err]
- return params, param_errors
+ t_span = t[idx_last] - t[idx_first]
+ params_guess = [
+ x.mean(), (x[idx_last] - x[idx_first]) / t_span,
+ y.mean(), (y[idx_last] - y[idx_first]) / t_span,
+ 0.1
+ ]
+ popt, pcov = curve_fit(
+ self._model_fit, t - t0, np.hstack([x, y]),
+ p0=params_guess, sigma=np.hstack([x_wt, y_wt]),
+ absolute_sigma=absolute_sigma
+ )
+ x0, vx, y0, vy, pi = popt
+ x0_err, vx_err, y0_err, vy_err, pi_err = np.sqrt(pcov.diagonal())
+
+ params = np.array([x0, vx, y0, vy, pi])
+ param_errors = np.array([x0_err, vx_err, y0_err, vy_err, pi_err])
+ if return_chi2:
+ chi2_x, chi2_y = self.calc_chi2(t, x, y, xe, ye, params, fixed_params_dict)
+ return params, param_errors, chi2_x, chi2_y
+ else:
+ return params, param_errors
-def validate_motion_model_dict(motion_model_dict, startable, default_motion_model):
- """
- Check that everything is set up properly for motion models to run and their
- required metadata.
- """
- # Collect names of all motion models that might get used.
- all_motion_model_names = ['Fixed']
- if default_motion_model is not None:
- all_motion_model_names.append(default_motion_model)
- if 'motion_model_input' in startable.columns:
- all_motion_model_names += np.unique(startable['motion_model_input']).tolist()
- if 'motion_model_used' in startable.columns:
- all_motion_model_names += np.unique(startable['motion_model_used']).tolist()
- all_motion_model_names = np.unique(all_motion_model_names)
-
- # Check whether all motion models are in the dict, and if not, try to add them
- # here or raise an error.
- for mm in all_motion_model_names:
- if mm not in motion_model_dict:
- mm_obj = eval(mm)
- if len(mm_obj.fixed_meta_data)>0:
- raise ValueError(f"Cannot use {mm} motion model without required metadata. Please initialize with required metadata and provide in motion_model_dict.")
- else:
- motion_model_dict[mm] = mm_obj()
- warnings.warn(f"Using default model/fitter for {mm}.", UserWarning)
+def motion_model_param_names(motion_models, with_errors=True, with_fixed=True):
+ """Get the motion model parameter names from a list of MotionModels.
- return motion_model_dict
+ Parameters
+ ----------
+ motion_models : MotionModel, str, or list of MotionModels/strings.
+ Motion model to query parameter names from. If str, should be the name of a MotionModel class.
+ with_errors : bool, optional
+ Add uncertainty names with '_err' suffix or not, by default True
+ with_fixed : bool, optional
+ Add fixed param names with '_fixed' suffix or not, by default True
-
-def get_one_motion_model_param_names(motion_model_name, with_errors=True, with_fixed=True):
+ Returns
+ -------
+ list
+ List of all unique parameter names across all motion models
"""
- Get all the motion model parameters for a given motion_model_name.
- Optionally, include fixed and error parameters (included by default).
- """
- mod = eval(motion_model_name)
list_of_parameters = []
- list_of_parameters += getattr(mod, 'fitter_param_names')
- if with_fixed:
- list_of_parameters += getattr(mod, 'fixed_param_names')
- if with_errors:
- list_of_parameters += [par+'_err' for par in getattr(mod, 'fitter_param_names')]
- return list_of_parameters
+ def list_add(name):
+ if name not in list_of_parameters:
+ list_of_parameters.append(name)
+
+ motion_models = np.atleast_1d(motion_models)
+ mm_map = motion_model_map()
+ for mm in motion_models:
+ if isinstance(mm, str):
+ mm = mm_map[mm]
+ for param in mm.fit_param_names:
+ # Fitter params
+ list_add(param)
+ # Error params
+ if with_errors:
+ list_add(param + '_err')
+ # Fixed params
+ if with_fixed:
+ for param in mm.fixed_param_names:
+ list_add(param)
+ return list_of_parameters
-def get_list_motion_model_param_names(motion_model_list, with_errors=True, with_fixed=True):
- """
- Get all the motion model parameters for all models given in motion_model_list.
- Optionally, include fixed and error parameters (included by default).
- """
- list_of_parameters = []
- all_motion_models = [eval(mm) for mm in np.unique(motion_model_list).tolist()]
- for aa in range(len(all_motion_models)):
- param_names = getattr(all_motion_models[aa], 'fitter_param_names')
- param_fixed_names = getattr(all_motion_models[aa], 'fixed_param_names')
- param_err_names = [par+'_err' for par in param_names]
- list_of_parameters += param_names
- if with_fixed:
- list_of_parameters += param_fixed_names
- if with_errors:
- list_of_parameters += param_err_names
-
- return np.unique(list_of_parameters).tolist()
+def all_motion_model_param_names(with_errors=True, with_fixed=True):
+ """Get all motion model parameter names from all available MotionModels.
+ Parameters
+ ----------
+ with_errors : bool, optional
+ Add uncertainty names with '_err' suffix or not, by default True
+ with_fixed : bool, optional
+ Add fixed param names with '_fixed' suffix or not, by default True
-def get_all_motion_model_param_names(with_errors=True, with_fixed=True):
+ Returns
+ -------
+ list
+ List of all unique parameter names across all motion models
"""
- Get all the motion model parameters for all models defined in this module.
- Optionally, include fixed and error parameters (included by default).
- """
- list_of_parameters = []
- all_motion_models = MotionModel.__subclasses__()
- for aa in range(len(all_motion_models)):
- param_names = getattr(all_motion_models[aa], 'fitter_param_names')
- param_fixed_names = getattr(all_motion_models[aa], 'fixed_param_names')
- param_err_names = [par+'_err' for par in param_names]
+ return motion_model_param_names(MotionModel.__subclasses__(), with_errors=with_errors, with_fixed=with_fixed)
- list_of_parameters += param_names
- if with_fixed:
- list_of_parameters += param_fixed_names
- if with_errors:
- list_of_parameters += param_err_names
-
- return np.unique(list_of_parameters).tolist()
-
+def motion_model_map():
+ """Get a dictionary mapping motion model names to MotionModel classes.
+
+ Returns
+ -------
+ mm_map : dict
+ Dictionary mapping motion model names to MotionModel classes.
+ """
+ mm_map = dict(
+ [(mm.__name__, mm) for mm in MotionModel.__subclasses__()]
+ )
+ # Sort by n_params
+ mm_map = dict(sorted(mm_map.items(), key=lambda item: item[1].n_params))
+ return mm_map
\ No newline at end of file
diff --git a/flystar/parallax.py b/flystar/parallax.py
index 4792ec6..a4f0f8c 100755
--- a/flystar/parallax.py
+++ b/flystar/parallax.py
@@ -23,44 +23,64 @@
# Default cache size is 1 GB
cache_memory.reduce_size()
-@cache_memory.cache()
-def parallax_in_direction(RA, Dec, mjd, obsLocation='earth', PA=0):
+# @cache_memory.cache()
+def parallax_in_direction(ra, dec, mjd, obsLocation='earth', pa=0.):
"""
- | R.A. in degrees. (J2000)
- | Dec. in degrees. (J2000)
- | MJD
- | PA in degrees. (counterclockwise offset of the image y-axis from North)
-
- Equations following MulensModel.
+ Calculate the parallax vector in a given direction following MulensModel.
+
+ Parameters
+ ----------
+ RA : float or array-like
+ Right Ascension in degrees. (J2000)
+ Dec : float or array-like
+ Declination in degrees. (J2000)
+ mjd : float or array-like
+ Modified Julian Date.
+ obsLocation : str, optional
+ Observer location, by default 'earth'.
+ PA : float, optional
+ Position angle in degrees (counterclockwise offset of the image y-axis from North), by default 0.
+
+ Returns
+ -------
+ pvec : ndarray
+ Parallax vector components, shape of (2, N_stars, N_times), or (2, N_stars) if N_times=1, or (2, N_times) if N_stars=1.
"""
- #print('parallax_in_direction: len(t) = ', len(mjd))
-
# Munge inputs into astropy format.
- times = Time(mjd + 2400000.5, format='jd', scale='tdb')
- coord = SkyCoord(RA, Dec, unit=(units.deg, units.deg))
-
- direction = coord.cartesian.xyz.value
+ # times = Time(mjd + 2400000.5, format='jd', scale='tdb')
+ ra = np.atleast_1d(ra)
+ dec = np.atleast_1d(dec)
+ mjd = np.atleast_1d(mjd)
+ times = Time(mjd, format='mjd', scale='tdb') # convert to TDB
+ coord = SkyCoord(ra, dec, unit=(units.deg, units.deg))
+
+ directions = coord.cartesian.xyz.value.T # Shape (N_stars, 3)
north = np.array([0., 0., 1.])
- _east_projected = np.cross(north, direction) / np.linalg.norm(np.cross(north, direction))
- _north_projected = np.cross(direction, _east_projected) / np.linalg.norm(np.cross(direction, _east_projected))
+ # Cross product of each star with north vector
+ _east_projected = np.cross(north, directions)
+ _east_projected /= np.linalg.norm(_east_projected, axis=1)[:, np.newaxis] # Shape (N_stars, 3)
+ _north_projected = np.cross(directions, _east_projected)
+ _north_projected /= np.linalg.norm(_north_projected, axis=1)[:, np.newaxis] # Shape (N_stars, 3)
- obs_pos = get_observer_barycentric(obsLocation, times)
- sun_pos = get_body_barycentric(body='sun', time=times)
+ obs_pos = get_observer_barycentric(obsLocation, times) # Shape (N_times,)
+ sun_pos = get_body_barycentric(body='sun', time=times) # Shape (N_times,)
sun_obs_pos = sun_pos - obs_pos
- pos = sun_obs_pos.xyz.T.to(units.au)
+ pos = sun_obs_pos.xyz.T.to(units.au).value # Shape (N_times, 3)
+
+ e = np.einsum('ti,si->st', pos, _east_projected) # Shape (N_stars, N_times)
+ n = np.einsum('ti,si->st', pos, _north_projected) # Shape (N_stars, N_times)
- e = np.dot(pos, _east_projected)
- n = np.dot(pos, _north_projected)
-
# Rotate frame e,n->x,y accounting for PA
- PA_rad = np.pi/180.0 * PA
- x = -e.value*np.cos(PA_rad) + n.value*np.sin(PA_rad)
- y = e.value*np.sin(PA_rad) + n.value*np.cos(PA_rad)
-
- pvec = np.array([x, y]).T
+ pa = np.deg2rad(pa) # shape (N_stars,)
+ x = -e * np.cos(pa[:, np.newaxis]) + n * np.sin(pa[:, np.newaxis]) # Shape (N_stars, N_times)
+ y = e * np.sin(pa[:, np.newaxis]) + n * np.cos(pa[:, np.newaxis]) # Shape (N_stars, N_times)
+ pvec = np.array([x, y]) # Shape (2, N_stars, N_times)
+ if pvec.shape[1] == 1 or pvec.shape[2] == 1:
+ pvec = pvec.reshape(2, -1) # Shape (2, N_stars) or (2, N_times)
+
return pvec
@@ -144,6 +164,4 @@ def get_observer_barycentric(body, times, min_ephem_step=1, velocity=False):
if velocity:
return (obs_pos, obs_vel)
else:
- return obs_pos
-
-
+ return obs_pos
\ No newline at end of file
diff --git a/flystar/plots.py b/flystar/plots.py
index 7553a8d..8a2127c 100755
--- a/flystar/plots.py
+++ b/flystar/plots.py
@@ -1,9 +1,8 @@
-from flystar import analysis, motion_model, startables
-import pylab as py
-import pylab as plt
+from . import motion_model, startables
import numpy as np
import matplotlib.mlab as mlab
import matplotlib
+import matplotlib.pyplot as plt
from matplotlib import colors
import matplotlib.cm as cm
from scipy.stats import chi2
@@ -23,8 +22,8 @@
####################################################
-def trans_positions(ref, ref_mat, starlist, starlist_mat, xlim=None, ylim=None, fileName=None,
- equal_axis=True, root='./'):
+def trans_positions(ref, ref_mat, starlist, starlist_mat, xlim=None, ylim=None,
+ equal_axis=True, save_path=None, show_plot=True):
"""
Plot positions of stars in reference list and the transformed starlist,
in reference list coordinates. Stars used in the transformation are
@@ -55,31 +54,37 @@ def trans_positions(ref, ref_mat, starlist, starlist_mat, xlim=None, ylim=None,
equal_axis: boolean
If true, make axes equal. True by default
+
+ save_path: string
+ Path to save the figure to. Default is None
+ show_plot: boolean
+ If true, show the plot. Default is True
+
"""
- py.figure(figsize=(10,10))
- py.clf()
- py.plot(ref['x'], ref['y'], 'g+', ms=5, label='Reference')
- py.plot(starlist['x'], starlist['y'], 'rx', ms=5, label='starlist')
- py.plot(ref_mat['x'], ref_mat['y'], color='skyblue', marker='s', ms=10, alpha=0.3,
+ plt.figure(figsize=(10,10))
+ plt.clf()
+ plt.plot(ref['x'], ref['y'], 'g+', ms=5, label='Reference')
+ plt.plot(starlist['x'], starlist['y'], 'rx', ms=5, label='starlist')
+ plt.plot(ref_mat['x'], ref_mat['y'], color='skyblue', marker='s', ms=10, alpha=0.3,
linestyle='None', label='Matched Reference')
- py.plot(starlist_mat['x'], starlist_mat['y'], color='darkblue', marker='s', ms=5, alpha=0.3,
+ plt.plot(starlist_mat['x'], starlist_mat['y'], color='darkblue', marker='s', ms=5, alpha=0.3,
linestyle='None', label='Matched starlist')
- py.xlabel('X position (Reference Coords)')
- py.ylabel('Y position (Reference Coords)')
- py.legend(numpoints=1)
- py.title('Label.dat Positions After Transformation')
+ plt.xlabel('X position (Reference Coords)')
+ plt.ylabel('Y position (Reference Coords)')
+ plt.legend(numpoints=1)
+ plt.title('Label.dat Positions After Transformation')
if xlim != None:
- py.axis([xlim[0], xlim[1], ylim[0], ylim[1]])
+ plt.axis([xlim[0], xlim[1], ylim[0], ylim[1]])
if equal_axis:
- py.axis('equal')
- if fileName!=None:
- #py.savefig(root + fileName[3:8] + 'Transformed_positions_' + '.png')
- py.savefig(root + 'Transformed_positions_{0}'.format(fileName) + '.png')
- else:
- py.savefig(root + 'Transformed_positions.png')
+ plt.axis('equal')
+
+ if save_path:
+ plt.savefig(save_path)
+ if show_plot:
+ plt.show()
- py.close()
+ plt.close()
return
@@ -121,22 +126,22 @@ def pos_diff_hist(ref_mat, starlist_mat, nbins=25, bin_width=None, xlim=None, fi
bins = np.arange(min_range, max_range+bin_width, bin_width)
- py.figure(figsize=(10,10))
- py.clf()
- py.hist(diff_x, histtype='step', bins=bins, color='blue', label='X')
- py.hist(diff_y, histtype='step', bins=bins, color='red', label='Y')
- py.xlabel('Reference Position - starlist Position')
- py.ylabel('N stars')
- py.title('Position Differences for matched stars')
+ plt.figure(figsize=(10,10))
+ plt.clf()
+ plt.hist(diff_x, histtype='step', bins=bins, color='blue', label='X')
+ plt.hist(diff_y, histtype='step', bins=bins, color='red', label='Y')
+ plt.xlabel('Reference Position - starlist Position')
+ plt.ylabel('N stars')
+ plt.title('Position Differences for matched stars')
if xlim != None:
- py.xlim([xlim[0], xlim[1]])
- py.legend()
+ plt.xlim([xlim[0], xlim[1]])
+ plt.legend()
if fileName != None:
- py.savefig(root + fileName[3:8] + 'Positions_hist_' + '.png')
+ plt.savefig(root + fileName[3:8] + 'Positions_hist_' + '.png')
else:
- py.savefig(root + 'Positions_hist.png')
+ plt.savefig(root + 'Positions_hist.png')
- py.close()
+ plt.close()
return
def pos_diff_err_hist(ref_mat, starlist_mat, transform, nbins=25, bin_width=None, errs='both', xlim=None,
@@ -188,6 +193,7 @@ def pos_diff_err_hist(ref_mat, starlist_mat, transform, nbins=25, bin_width=None
an outlier.
"""
+ from . import analysis
diff_x = ref_mat['x'] - starlist_mat['x']
diff_y = ref_mat['y'] - starlist_mat['y']
@@ -248,51 +254,51 @@ def pos_diff_err_hist(ref_mat, starlist_mat, transform, nbins=25, bin_width=None
bins = np.arange(min_range, max_range+bin_width, bin_width)
- py.figure(figsize=(10,10))
- py.clf()
- n_x, bins_x, p = py.hist(ratio_x, histtype='step', bins=bins, color='blue',
+ plt.figure(figsize=(10,10))
+ plt.clf()
+ n_x, bins_x, p = plt.hist(ratio_x, histtype='step', bins=bins, color='blue',
label='X', density=True, linewidth=2)
- n_y, bins_y, p = py.hist(ratio_y, histtype='step', bins=bins, color='red',
+ n_y, bins_y, p = plt.hist(ratio_y, histtype='step', bins=bins, color='red',
label='Y', density=True, linewidth=2)
# Overplot a Gaussian, as well
mean = 0
sigma = 1
x = np.arange(-6, 6, 0.1)
- py.plot(x, norm.pdf(x,mean,sigma), 'g-', linewidth=2)
+ plt.plot(x, norm.pdf(x,mean,sigma), 'g-', linewidth=2)
# Annotate reduced chi-sqared values in plot: with outliers
- xstr = '$\chi^2_r$ = {0}'.format(np.round(chi_sq_red, decimals=3))
- py.annotate(xstr, xy=(0.3, 0.77), xycoords='figure fraction', color='black')
+ xstr = r'$\chi^2_r$ = {0}'.format(np.round(chi_sq_red, decimals=3))
+ plt.annotate(xstr, xy=(0.3, 0.77), xycoords='figure fraction', color='black')
txt = r'$\nu$ = 2*{0} - {1} = {2}'.format(len(diff_x), num_mod_params,
deg_freedom)
- py.annotate(txt, xy=(0.25,0.74), xycoords='figure fraction', color='black')
+ plt.annotate(txt, xy=(0.25,0.74), xycoords='figure fraction', color='black')
xstr2 = 'With Outliers'
xstr3 = '{0} with +/- {1}+ sigma'.format(len(ratio_x) - len(good[0]), outlier)
- py.annotate(xstr2, xy=(0.29, 0.83), xycoords='figure fraction', color='black')
- py.annotate(xstr3, xy=(0.25, 0.80), xycoords='figure fraction', color='black')
+ plt.annotate(xstr2, xy=(0.29, 0.83), xycoords='figure fraction', color='black')
+ plt.annotate(xstr3, xy=(0.25, 0.80), xycoords='figure fraction', color='black')
# Annotate reduced chi-sqared values in plot: without outliers
- xstr = '$\chi^2_r$ = {0}'.format(np.round(chi_sq_red_good, decimals=3))
- py.annotate(xstr, xy=(0.7, 0.8), xycoords='figure fraction', color='black')
+ xstr = r'$\chi^2_r$ = {0}'.format(np.round(chi_sq_red_good, decimals=3))
+ plt.annotate(xstr, xy=(0.7, 0.8), xycoords='figure fraction', color='black')
txt = r'$\nu$ = 2*{0} - {1} = {2}'.format(len(good[0]), num_mod_params,
deg_freedom_good)
- py.annotate(txt, xy=(0.65,0.77), xycoords='figure fraction', color='black')
+ plt.annotate(txt, xy=(0.65,0.77), xycoords='figure fraction', color='black')
xstr2 = 'Without Outliers'
- py.annotate(xstr2, xy=(0.67, 0.83), xycoords='figure fraction', color='black')
+ plt.annotate(xstr2, xy=(0.67, 0.83), xycoords='figure fraction', color='black')
- py.xlabel('(Ref Pos - TransStarlist Pos) / Ast. Error')
- py.ylabel('N stars (normalized)')
- py.title('Position Residuals for Matched Stars')
+ plt.xlabel('(Ref Pos - TransStarlist Pos) / Ast. Error')
+ plt.ylabel('N stars (normalized)')
+ plt.title('Position Residuals for Matched Stars')
if xlim != None:
- py.xlim([xlim[0], xlim[1]])
- py.legend()
+ plt.xlim([xlim[0], xlim[1]])
+ plt.legend()
if fileName != None:
- py.savefig(root + fileName[3:8] + 'Positions_err_ratio_hist_' + '.png')
+ plt.savefig(root + fileName[3:8] + 'Positions_err_ratio_hist_' + '.png')
else:
- py.savefig(root + 'Positions_err_ratio_hist.png')
+ plt.savefig(root + 'Positions_err_ratio_hist.png')
- py.close()
+ plt.close()
return
@@ -319,18 +325,18 @@ def mag_diff_hist(ref_mat, starlist_mat, bins=25, fileName=None, root='./'):
bad2 = np.where(bad == True)
diff_m = np.delete(diff_m, bad2)
- py.figure(figsize=(10,10))
- py.clf()
- py.hist(diff_m, bins=bins)
- py.xlabel('Reference Mag - TransStarlist Mag')
- py.ylabel('N stars')
- py.title('Magnitude Difference for matched stars')
+ plt.figure(figsize=(10,10))
+ plt.clf()
+ plt.hist(diff_m, bins=bins)
+ plt.xlabel('Reference Mag - TransStarlist Mag')
+ plt.ylabel('N stars')
+ plt.title('Magnitude Difference for matched stars')
if fileName != None:
- py.savefig(root + fileName[3:8] + 'Magnitude_hist_' + '.png')
+ plt.savefig(root + fileName[3:8] + 'Magnitude_hist_' + '.png')
else:
- py.savefig(root + 'Magnitude_hist.png')
+ plt.savefig(root + 'Magnitude_hist.png')
- py.close()
+ plt.close()
return
def pos_diff_quiver(ref_mat, starlist_mat, qscale=10, keyLength=0.2, xlim=None, ylim=None,
@@ -411,35 +417,35 @@ def pos_diff_quiver(ref_mat, starlist_mat, qscale=10, keyLength=0.2, xlim=None,
s = len(xpos)
- py.figure(figsize=(10,10))
- py.clf()
- q = py.quiver(xpos, ypos, diff_x, diff_y, scale=qscale)
+ plt.figure(figsize=(10,10))
+ plt.clf()
+ q = plt.quiver(xpos, ypos, diff_x, diff_y, scale=qscale)
fmt = '{0} ref units'.format(keyLength)
- #py.quiverkey(q, 0.2, 0.92, keyLength, fmt, coordinates='figure', color='black')
+ #plt.quiverkey(q, 0.2, 0.92, keyLength, fmt, coordinates='figure', color='black')
# Make our reference arrow a different color
- q2 = py.quiver(xpos[s-2:s], ypos[s-2:s], diff_x[s-2:s], diff_y[s-2:s], scale=qscale, color='red')
+ q2 = plt.quiver(xpos[s-2:s], ypos[s-2:s], diff_x[s-2:s], diff_y[s-2:s], scale=qscale, color='red')
# Annotate our reference quiver arrow
- py.annotate(fmt, xy=(xpos[-1]-2, ypos[-1]+0.5), color='red')
- py.xlabel('X Position (Reference coords)')
- py.ylabel('Y Position (Reference coords)')
+ plt.annotate(fmt, xy=(xpos[-1]-2, ypos[-1]+0.5), color='red')
+ plt.xlabel('X Position (Reference coords)')
+ plt.ylabel('Y Position (Reference coords)')
if xlim != None:
- py.axis([xlim[0], ylim[1], ylim[0], ylim[1]])
+ plt.axis([xlim[0], ylim[1], ylim[0], ylim[1]])
if sigma:
if fileName != None:
- py.title('(Reference - Transformed Starlist positions) / sigma')
- py.savefig(root + fileName[3:8] + 'Positions_quiver_sigma_' + '.png')
+ plt.title('(Reference - Transformed Starlist positions) / sigma')
+ plt.savefig(root + fileName[3:8] + 'Positions_quiver_sigma_' + '.png')
else:
- py.title('(Reference - Transformed Starlist positions) / sigma')
- py.savefig(root + 'Positions_quiver_sigma.png')
+ plt.title('(Reference - Transformed Starlist positions) / sigma')
+ plt.savefig(root + 'Positions_quiver_sigma.png')
else:
if fileName != None:
- py.title('Reference - Transformed Starlist positions')
- py.savefig(root + fileName[3:8] + 'Positions_quiver_' + '.png')
+ plt.title('Reference - Transformed Starlist positions')
+ plt.savefig(root + fileName[3:8] + 'Positions_quiver_' + '.png')
else:
- py.title('Reference - Transformed Starlist positions')
- py.savefig(root + 'Positions_quiver.png')
+ plt.title('Reference - Transformed Starlist positions')
+ plt.savefig(root + 'Positions_quiver.png')
- py.close()
+ plt.close()
return
def vpd(ref, starlist_trans, vxlim, vylim):
@@ -472,17 +478,17 @@ def vpd(ref, starlist_trans, vxlim, vylim):
trans_vx = starlist_trans['vx']
trans_vy = starlist_trans['vy']
- py.figure(figsize=(10,10))
- py.clf()
- py.plot(trans_vx, trans_vy, 'k.', ms=8, label='Transformed', alpha=0.4)
- py.plot(ref_vx, ref_vy, 'r.', ms=8, label='Reference', alpha=0.4)
- py.xlabel('Vx (Reference units)')
- py.ylabel('Vy (Reference units)')
+ plt.figure(figsize=(10,10))
+ plt.clf()
+ plt.plot(trans_vx, trans_vy, 'k.', ms=8, label='Transformed', alpha=0.4)
+ plt.plot(ref_vx, ref_vy, 'r.', ms=8, label='Reference', alpha=0.4)
+ plt.xlabel('Vx (Reference units)')
+ plt.ylabel('Vy (Reference units)')
if vxlim != None:
- py.axis([vxlim[0], vylim[1], vylim[0], vylim[1]])
- py.title('Reference and Transformed Proper Motions')
- py.legend()
- py.savefig('Transformed_velocities.png')
+ plt.axis([vxlim[0], vylim[1], vylim[0], vylim[1]])
+ plt.title('Reference and Transformed Proper Motions')
+ plt.legend()
+ plt.savefig('Transformed_velocities.png')
return
@@ -538,27 +544,27 @@ def vel_diff_err_hist(ref_mat, starlist_mat, nbins=25, bin_width=None, vxlim=Non
sigma = 1
x = np.arange(-6, 6, 0.1)
- py.figure(figsize=(20,10))
- py.subplot(121)
- py.subplots_adjust(left=0.1)
- py.hist(ratio_vx, bins=xbins, histtype='step', color='black', density=True,
+ plt.figure(figsize=(20,10))
+ plt.subplot(121)
+ plt.subplots_adjust(left=0.1)
+ plt.hist(ratio_vx, bins=xbins, histtype='step', color='black', density=True,
linewidth=2)
- py.plot(x, norm.pdf(x,mean,sigma), 'r-', linewidth=2)
- py.xlabel('(Ref Vx - Trans Vx) / Vxe')
- py.ylabel('N_stars')
- py.title('Vx Residuals, Matched')
+ plt.plot(x, norm.pdf(x,mean,sigma), 'r-', linewidth=2)
+ plt.xlabel('(Ref Vx - Trans Vx) / Vxe')
+ plt.ylabel('N_stars')
+ plt.title('Vx Residuals, Matched')
if vxlim != None:
- py.xlim([vxlim[0], vxlim[1]])
- py.subplot(122)
- py.hist(ratio_vy, bins=ybins, histtype='step', color='black', density=True,
+ plt.xlim([vxlim[0], vxlim[1]])
+ plt.subplot(122)
+ plt.hist(ratio_vy, bins=ybins, histtype='step', color='black', density=True,
linewidth=2)
- py.plot(x, norm.pdf(x,mean,sigma), 'r-', linewidth=2)
- py.xlabel('(Ref Vy - Trans Vy) / Vye')
- py.ylabel('N_stars')
- py.title('Vy Residuals, Matched')
+ plt.plot(x, norm.pdf(x,mean,sigma), 'r-', linewidth=2)
+ plt.xlabel('(Ref Vy - Trans Vy) / Vye')
+ plt.ylabel('N_stars')
+ plt.title('Vy Residuals, Matched')
if vylim != None:
- py.xlim([vylim[0], vylim[1]])
- py.savefig('Vel_err_ratio_dist.png')
+ plt.xlim([vylim[0], vylim[1]])
+ plt.savefig('Vel_err_ratio_dist.png')
return
@@ -606,17 +612,17 @@ def residual_vpd(ref_mat, starlist_trans_mat, pscale=None):
yerr = np.hypot(ref_mat['vy_err'], starlist_trans_mat['vy_err'])
# Plotting
- py.figure(figsize=(10,10))
- py.clf()
- py.errorbar(diff_x, diff_y, xerr=xerr, yerr=yerr, fmt='k.', ms=8, alpha=0.5)
+ plt.figure(figsize=(10,10))
+ plt.clf()
+ plt.errorbar(diff_x, diff_y, xerr=xerr, yerr=yerr, fmt='k.', ms=8, alpha=0.5)
if pscale != None:
- py.xlabel('Reference_vx - Transformed_vx (mas/yr)')
- py.ylabel('Reference_vy - Transformed_vy (mas/yr)')
+ plt.xlabel('Reference_vx - Transformed_vx (mas/yr)')
+ plt.ylabel('Reference_vy - Transformed_vy (mas/yr)')
else:
- py.xlabel('Reference_vx - Transformed_vx (reference coords)')
- py.ylabel('Reference_vy - Transformed_vy (reference coords)')
- py.title('Proper Motion Residuals')
- py.savefig('resid_vpd.png')
+ plt.xlabel('Reference_vx - Transformed_vx (reference coords)')
+ plt.ylabel('Reference_vy - Transformed_vy (reference coords)')
+ plt.title('Proper Motion Residuals')
+ plt.savefig('resid_vpd.png')
return
@@ -636,8 +642,8 @@ def plotStar(starNames, rootDir='./', align='align/align_d_rms_1000_abs_t',
else:
Nrows = math.ceil(Nstars / (Ncols / 2)) * 3
- py.close('all')
- py.figure(2, figsize=figsize)
+ plt.close('all')
+ plt.figure(2, figsize=figsize)
names = s.getArray('name')
mag = s.getArray('mag')
x = s.getArray('x')
@@ -746,7 +752,7 @@ def plotStar(starNames, rootDir='./', align='align/align_d_rms_1000_abs_t',
t0 = int(np.floor(np.min(time)))
tO = int(np.ceil(np.max(time)))
- dateTicLoc = py.MultipleLocator(3)
+ dateTicLoc = plt.MultipleLocator(3)
dateTicRng = [t0-1, tO+1]
dateTics = np.arange(t0, tO+1)
DateTicsLabel = dateTics-2000
@@ -754,7 +760,7 @@ def plotStar(starNames, rootDir='./', align='align/align_d_rms_1000_abs_t',
# See if we are using MJD instead.
if time[0] > 50000:
print('MJD')
- dateTicLoc = py.MultipleLocator(1000)
+ dateTicLoc = plt.MultipleLocator(1000)
t0 = int(np.round(np.min(time), 50))
tO = int(np.round(np.max(time), 50))
dateTicRng = [t0-200, tO+200]
@@ -779,121 +785,121 @@ def plotStar(starNames, rootDir='./', align='align/align_d_rms_1000_abs_t',
ind = (row-1)*Ncols + col
- paxes = py.subplot(Nrows, Ncols, ind)
- py.plot(time, fitLineX, 'b-')
- py.plot(time, fitLineX + fitSigX, 'b--')
- py.plot(time, fitLineX - fitSigX, 'b--')
- py.errorbar(time, x, yerr=xerr, fmt='k.')
- rng = py.axis()
- py.ylim(np.min(x-xerr-0.1),np.max(x+xerr+0.1))
- py.xlabel('Date - 2000 (yrs)', fontsize=fontsize1)
+ paxes = plt.subplot(Nrows, Ncols, ind)
+ plt.plot(time, fitLineX, 'b-')
+ plt.plot(time, fitLineX + fitSigX, 'b--')
+ plt.plot(time, fitLineX - fitSigX, 'b--')
+ plt.errorbar(time, x, yerr=xerr, fmt='k.')
+ rng = plt.axis()
+ plt.ylim(np.min(x-xerr-0.1),np.max(x+xerr+0.1))
+ plt.xlabel('Date - 2000 (yrs)', fontsize=fontsize1)
if time[0] > 50000:
- py.xlabel('Date (MJD)', fontsize=fontsize1)
- py.ylabel('X (pix)', fontsize=fontsize1)
+ plt.xlabel('Date (MJD)', fontsize=fontsize1)
+ plt.ylabel('X (pix)', fontsize=fontsize1)
paxes.xaxis.set_major_formatter(fmtX)
paxes.get_xaxis().set_major_locator(dateTicLoc)
paxes.yaxis.set_major_formatter(fmtY)
paxes.tick_params(axis='both', which='major', labelsize=fontsize1)
- py.yticks(np.arange(np.min(x-xerr-0.1), np.max(x+xerr+0.1), 0.2))
- py.xticks(dateTics, DateTicsLabel)
- py.xlim(np.min(dateTics), np.max(dateTics))
- py.annotate(starName,xy=(1.0,1.1), xycoords='axes fraction', fontsize=12, color='red')
+ plt.yticks(np.arange(np.min(x-xerr-0.1), np.max(x+xerr+0.1), 0.2))
+ plt.xticks(dateTics, DateTicsLabel)
+ plt.xlim(np.min(dateTics), np.max(dateTics))
+ plt.annotate(starName,xy=(1.0,1.1), xycoords='axes fraction', fontsize=12, color='red')
col = col + 1
ind = (row-1)*Ncols + col
- paxes = py.subplot(Nrows, Ncols, ind)
- py.plot(time, fitLineY, 'b-')
- py.plot(time, fitLineY + fitSigY, 'b--')
- py.plot(time, fitLineY - fitSigY, 'b--')
- py.errorbar(time, y, yerr=yerr, fmt='k.')
- rng = py.axis()
- py.axis(dateTicRng + [rng[2], rng[3]], fontsize=fontsize1)
- py.xlabel('Date - 2000 (yrs)', fontsize=fontsize1)
+ paxes = plt.subplot(Nrows, Ncols, ind)
+ plt.plot(time, fitLineY, 'b-')
+ plt.plot(time, fitLineY + fitSigY, 'b--')
+ plt.plot(time, fitLineY - fitSigY, 'b--')
+ plt.errorbar(time, y, yerr=yerr, fmt='k.')
+ rng = plt.axis()
+ plt.axis(dateTicRng + [rng[2], rng[3]], fontsize=fontsize1)
+ plt.xlabel('Date - 2000 (yrs)', fontsize=fontsize1)
if time[0] > 50000:
- py.xlabel('Date (MJD)', fontsize=fontsize1)
- py.ylabel('Y (pix)', fontsize=fontsize1)
+ plt.xlabel('Date (MJD)', fontsize=fontsize1)
+ plt.ylabel('Y (pix)', fontsize=fontsize1)
#paxes.get_xaxis().set_major_locator(dateTicLoc)
paxes.xaxis.set_major_formatter(fmtX)
paxes.get_xaxis().set_major_locator(dateTicLoc)
paxes.yaxis.set_major_formatter(fmtY)
paxes.tick_params(axis='both', which='major', labelsize=12)
- py.ylim(np.min(y-yerr-0.1),np.max(y+yerr+0.1))
- py.yticks(np.arange(np.min(y-yerr-0.1), np.max(y+yerr+0.1), 0.2))
- py.xticks(dateTics, DateTicsLabel)
- py.xlim(np.min(dateTics), np.max(dateTics))
+ plt.ylim(np.min(y-yerr-0.1),np.max(y+yerr+0.1))
+ plt.yticks(np.arange(np.min(y-yerr-0.1), np.max(y+yerr+0.1), 0.2))
+ plt.xticks(dateTics, DateTicsLabel)
+ plt.xlim(np.min(dateTics), np.max(dateTics))
row = row + 1
col = col - 1
ind = (row-1)*Ncols + col
- paxes = py.subplot(Nrows, Ncols, ind)
- py.plot(time, np.zeros(len(time)), 'b-')
- py.plot(time, fitSigX, 'b--')
- py.plot(time, -fitSigX, 'b--')
- py.errorbar(time, x - fitLineX, yerr=xerr, fmt='k.')
- py.axis(dateTicRng + resTicRng, fontsize=fontsize1)
- py.xlabel('Date - 2000 (yrs)', fontsize=fontsize1)
+ paxes = plt.subplot(Nrows, Ncols, ind)
+ plt.plot(time, np.zeros(len(time)), 'b-')
+ plt.plot(time, fitSigX, 'b--')
+ plt.plot(time, -fitSigX, 'b--')
+ plt.errorbar(time, x - fitLineX, yerr=xerr, fmt='k.')
+ plt.axis(dateTicRng + resTicRng, fontsize=fontsize1)
+ plt.xlabel('Date - 2000 (yrs)', fontsize=fontsize1)
if time[0] > 50000:
- py.xlabel('Date (MJD)', fontsize=fontsize1)
- py.ylabel('X Residuals (pix)', fontsize=fontsize1)
+ plt.xlabel('Date (MJD)', fontsize=fontsize1)
+ plt.ylabel('X Residuals (pix)', fontsize=fontsize1)
paxes.get_xaxis().set_major_locator(dateTicLoc)
paxes.xaxis.set_major_formatter(fmtX)
paxes.tick_params(axis='both', which='major', labelsize=fontsize1)
- py.xticks(dateTics, DateTicsLabel)
- py.xlim(np.min(dateTics), np.max(dateTics))
+ plt.xticks(dateTics, DateTicsLabel)
+ plt.xlim(np.min(dateTics), np.max(dateTics))
col = col + 1
ind = (row-1)*Ncols + col
- paxes = py.subplot(Nrows, Ncols, ind)
- py.plot(time, np.zeros(len(time)), 'b-')
- py.plot(time, fitSigY, 'b--')
- py.plot(time, -fitSigY, 'b--')
- py.errorbar(time, y - fitLineY, yerr=yerr, fmt='k.')
- py.axis(dateTicRng + resTicRng, fontsize=fontsize1)
- py.xlabel('Date -2000 (yrs)', fontsize=fontsize1)
+ paxes = plt.subplot(Nrows, Ncols, ind)
+ plt.plot(time, np.zeros(len(time)), 'b-')
+ plt.plot(time, fitSigY, 'b--')
+ plt.plot(time, -fitSigY, 'b--')
+ plt.errorbar(time, y - fitLineY, yerr=yerr, fmt='k.')
+ plt.axis(dateTicRng + resTicRng, fontsize=fontsize1)
+ plt.xlabel('Date -2000 (yrs)', fontsize=fontsize1)
if time[0] > 50000:
- py.xlabel('Date (MJD)', fontsize=fontsize1)
- py.ylabel('Y Residuals (pix)', fontsize=fontsize1)
+ plt.xlabel('Date (MJD)', fontsize=fontsize1)
+ plt.ylabel('Y Residuals (pix)', fontsize=fontsize1)
paxes.get_xaxis().set_major_locator(dateTicLoc)
paxes.xaxis.set_major_formatter(fmtX)
paxes.tick_params(axis='both', which='major', labelsize=fontsize1)
- py.xticks(dateTics, DateTicsLabel)
- py.xlim(np.min(dateTics), np.max(dateTics))
+ plt.xticks(dateTics, DateTicsLabel)
+ plt.xlim(np.min(dateTics), np.max(dateTics))
row = row + 1
col = col - 1
ind = (row-1)*Ncols + col
- paxes = py.subplot(Nrows, Ncols, ind)
- py.errorbar(x,y, xerr=xerr, yerr=yerr, fmt='k.')
- py.yticks(np.arange(np.min(y-yerr-0.1), np.max(y+yerr+0.1), 0.2))
- py.xticks(np.arange(np.min(x-xerr-0.1), np.max(x+xerr+0.1), 0.2), rotation = 270)
- py.axis('equal')
+ paxes = plt.subplot(Nrows, Ncols, ind)
+ plt.errorbar(x,y, xerr=xerr, yerr=yerr, fmt='k.')
+ plt.yticks(np.arange(np.min(y-yerr-0.1), np.max(y+yerr+0.1), 0.2))
+ plt.xticks(np.arange(np.min(x-xerr-0.1), np.max(x+xerr+0.1), 0.2), rotation = 270)
+ plt.axis('equal')
paxes.tick_params(axis='both', which='major', labelsize=fontsize1)
paxes.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))
paxes.xaxis.set_major_formatter(FormatStrFormatter('%.2f'))
- py.xlabel('X (pix)', fontsize=fontsize1)
- py.ylabel('Y (pix)', fontsize=fontsize1)
- py.plot(fitLineX, fitLineY, 'b-')
+ plt.xlabel('X (pix)', fontsize=fontsize1)
+ plt.ylabel('Y (pix)', fontsize=fontsize1)
+ plt.plot(fitLineX, fitLineY, 'b-')
col = col + 1
ind = (row-1)*Ncols + col
bins = np.arange(-7.5, 7.5, 1)
- paxes = py.subplot(Nrows, Ncols, ind)
+ paxes = plt.subplot(Nrows, Ncols, ind)
id = np.where(diffY < 0)[0]
sig[id] = -1.*sig[id]
- (n, b, p) = py.hist(sigX, bins, histtype='stepfilled', color='b', label='X')
- py.setp(p, 'facecolor', 'b')
- (n, b, p) = py.hist(sigY, bins, histtype='step', color='r', label='Y')
- py.axis([-7, 7, 0, 8], fontsize=10)
- py.legend()
- py.xlabel('Residuals (sigma)', fontsize=fontsize1)
- py.ylabel('Number of Epochs', fontsize=fontsize1)
+ (n, b, p) = plt.hist(sigX, bins, histtype='stepfilled', color='b', label='X')
+ plt.setp(p, 'facecolor', 'b')
+ (n, b, p) = plt.hist(sigY, bins, histtype='step', color='r', label='Y')
+ plt.axis([-7, 7, 0, 8], fontsize=10)
+ plt.legend()
+ plt.xlabel('Residuals (sigma)', fontsize=fontsize1)
+ plt.ylabel('Number of Epochs', fontsize=fontsize1)
##########
#
@@ -901,9 +907,9 @@ def plotStar(starNames, rootDir='./', align='align/align_d_rms_1000_abs_t',
#
##########
if (radial == True):
- py.clf()
+ plt.clf()
- dateTicLoc = py.MultipleLocator(3)
+ dateTicLoc = plt.MultipleLocator(3)
maxErr = np.array([rerr, terr]).max()
resTicRng = [-3*maxErr, 3*maxErr]
@@ -912,83 +918,83 @@ def plotStar(starNames, rootDir='./', align='align/align_d_rms_1000_abs_t',
fmtX = FormatStrFormatter('%5i')
fmtY = FormatStrFormatter('%6.2f')
- paxes = py.subplot(3,2,1)
- py.plot(time, fitLineR, 'b-')
- py.plot(time, fitLineR + fitSigR, 'b--')
- py.plot(time, fitLineR - fitSigR, 'b--')
- py.errorbar(time, r, yerr=rerr, fmt='k.')
- rng = py.axis()
- py.axis(dateTicRng + [rng[2], rng[3]])
- py.xlabel('Date (yrs)')
- py.ylabel('R (pix)')
+ paxes = plt.subplot(3,2,1)
+ plt.plot(time, fitLineR, 'b-')
+ plt.plot(time, fitLineR + fitSigR, 'b--')
+ plt.plot(time, fitLineR - fitSigR, 'b--')
+ plt.errorbar(time, r, yerr=rerr, fmt='k.')
+ rng = plt.axis()
+ plt.axis(dateTicRng + [rng[2], rng[3]])
+ plt.xlabel('Date (yrs)')
+ plt.ylabel('R (pix)')
paxes.xaxis.set_major_formatter(fmtX)
paxes.get_xaxis().set_major_locator(dateTicLoc)
paxes.yaxis.set_major_formatter(fmtY)
- paxes = py.subplot(3, 2, 2)
- py.plot(time, fitLineT, 'b-')
- py.plot(time, fitLineT + fitSigT, 'b--')
- py.plot(time, fitLineT - fitSigT, 'b--')
- py.errorbar(time, t, yerr=terr, fmt='k.')
- rng = py.axis()
- py.axis(dateTicRng + [rng[2], rng[3]])
- py.xlabel('Date (yrs)')
- py.ylabel('T (pix)')
+ paxes = plt.subplot(3, 2, 2)
+ plt.plot(time, fitLineT, 'b-')
+ plt.plot(time, fitLineT + fitSigT, 'b--')
+ plt.plot(time, fitLineT - fitSigT, 'b--')
+ plt.errorbar(time, t, yerr=terr, fmt='k.')
+ rng = plt.axis()
+ plt.axis(dateTicRng + [rng[2], rng[3]])
+ plt.xlabel('Date (yrs)')
+ plt.ylabel('T (pix)')
paxes.xaxis.set_major_formatter(fmtX)
paxes.get_xaxis().set_major_locator(dateTicLoc)
paxes.yaxis.set_major_formatter(fmtY)
- paxes = py.subplot(3, 2, 3)
- py.plot(time, np.zeros(len(time)), 'b-')
- py.plot(time, fitSigR, 'b--')
- py.plot(time, -fitSigR, 'b--')
- py.errorbar(time, r - fitLineR, yerr=rerr, fmt='k.')
- py.axis(dateTicRng + resTicRng)
- py.xlabel('Date (yrs)')
- py.ylabel('R Residuals (pix)')
+ paxes = plt.subplot(3, 2, 3)
+ plt.plot(time, np.zeros(len(time)), 'b-')
+ plt.plot(time, fitSigR, 'b--')
+ plt.plot(time, -fitSigR, 'b--')
+ plt.errorbar(time, r - fitLineR, yerr=rerr, fmt='k.')
+ plt.axis(dateTicRng + resTicRng)
+ plt.xlabel('Date (yrs)')
+ plt.ylabel('R Residuals (pix)')
paxes.get_xaxis().set_major_locator(dateTicLoc)
- paxes = py.subplot(3, 2, 4)
- py.plot(time, np.zeros(len(time)), 'b-')
- py.plot(time, fitSigT, 'b--')
- py.plot(time, -fitSigT, 'b--')
- py.errorbar(time, t - fitLineT, yerr=terr, fmt='k.')
- py.axis(dateTicRng + resTicRng)
- py.xlabel('Date (yrs)')
- py.ylabel('T Residuals (pix)')
+ paxes = plt.subplot(3, 2, 4)
+ plt.plot(time, np.zeros(len(time)), 'b-')
+ plt.plot(time, fitSigT, 'b--')
+ plt.plot(time, -fitSigT, 'b--')
+ plt.errorbar(time, t - fitLineT, yerr=terr, fmt='k.')
+ plt.axis(dateTicRng + resTicRng)
+ plt.xlabel('Date (yrs)')
+ plt.ylabel('T Residuals (pix)')
paxes.get_xaxis().set_major_locator(dateTicLoc)
bins = np.arange(-7, 7, 1)
- py.subplot(3, 2, 5)
- (n, b, p) = py.hist(sigR, bins)
- py.setp(p, 'facecolor', 'k')
- py.axis([-5, 5, 0, 20])
- py.xlabel('T Residuals (sigma)')
- py.ylabel('Number of Epochs')
-
- py.subplot(3, 2, 6)
- (n, b, p) = py.hist(sigT, bins)
- py.axis([-5, 5, 0, 20])
- py.setp(p, 'facecolor', 'k')
- py.xlabel('Y Residuals (sigma)')
- py.ylabel('Number of Epochs')
-
- py.subplots_adjust(wspace=0.4, hspace=0.4, right=0.95, top=0.95)
- py.savefig(rootDir+'plots/plotStarRadial_' + starName + '.png')
- py.show()
+ plt.subplot(3, 2, 5)
+ (n, b, p) = plt.hist(sigR, bins)
+ plt.setp(p, 'facecolor', 'k')
+ plt.axis([-5, 5, 0, 20])
+ plt.xlabel('T Residuals (sigma)')
+ plt.ylabel('Number of Epochs')
+
+ plt.subplot(3, 2, 6)
+ (n, b, p) = plt.hist(sigT, bins)
+ plt.axis([-5, 5, 0, 20])
+ plt.setp(p, 'facecolor', 'k')
+ plt.xlabel('Y Residuals (sigma)')
+ plt.ylabel('Number of Epochs')
+
+ plt.subplots_adjust(wspace=0.4, hspace=0.4, right=0.95, top=0.95)
+ plt.savefig(rootDir+'plots/plotStarRadial_' + starName + '.png')
+ plt.show()
title = rootDir.split('/')[-2]
- py.suptitle(title, x=0.5, y=0.97)
+ plt.suptitle(title, x=0.5, y=0.97)
if Nstars == 1:
- py.subplots_adjust(wspace=0.4, hspace=0.4, left = 0.15, bottom = 0.1, right=0.9, top=0.9)
- py.savefig(rootDir+'plots/plotStar_' + starName + '.png')
+ plt.subplots_adjust(wspace=0.4, hspace=0.4, left = 0.15, bottom = 0.1, right=0.9, top=0.9)
+ plt.savefig(rootDir+'plots/plotStar_' + starName + '.png')
else:
- py.subplots_adjust(wspace=0.6, hspace=0.6, left = 0.08, bottom = 0.05, right=0.95, top=0.90)
- py.savefig(rootDir+'plots/plotStar_all.png')
- py.show()
+ plt.subplots_adjust(wspace=0.6, hspace=0.6, left = 0.08, bottom = 0.05, right=0.95, top=0.90)
+ plt.savefig(rootDir+'plots/plotStar_all.png')
+ plt.show()
- py.show()
+ plt.show()
print('Fubar')
@@ -1051,7 +1057,7 @@ def plot_pm_error(tab):
plt.legend()
plt.xlabel('Mag')
plt.ylabel('PM Error (mas/yr)')
-
+ plt.show()
return
def plot_mag_error(tab):
@@ -1064,16 +1070,15 @@ def plot_mag_error(tab):
return
-def plot_mean_residuals_by_epoch(tab, motion_model_dict={}):
+def plot_mean_residuals_by_epoch(tab):
"""
Plot mean position and magnitude residuals vs. epoch.
Note we are plotting the mean( |dx} ) to see
the size of the mean residual.
"""
# Predicted model positions at each epoch
- motion_model_dict = motion_model.validate_motion_model_dict(motion_model_dict, tab, None)
i_all_detected = np.where(~np.any(np.isnan(tab['t']),axis=1))[0][0]
- xt_mod, yt_mod, xt_mod_err, yt_mod_err = tab.get_star_positions_at_time(tab['t'][i_all_detected], motion_model_dict, allow_alt_models=True)
+ xt_mod, yt_mod, xt_mod_err, yt_mod_err = tab.predict_positions(tab['t'][i_all_detected])
# Residuals
dx = tab['x'] - xt_mod
@@ -2221,7 +2226,7 @@ def plot_chi2_dist(tab, Ndetect, motion_model_dict={}, xlim=40, n_bins=50, boot_
plt.hist(x[idx], bins=chi2_bins, histtype='step', label='X', density=True)
plt.hist(y[idx], bins=chi2_bins, histtype='step', label='Y', density=True)
plt.plot(chi2_xaxis, chi2.pdf(chi2_xaxis, Ndof), 'r-', alpha=0.6,
- label='$\chi^2$ ' + str(Ndof) + ' dof')
+ label=r'$\chi^2$ ' + str(Ndof) + ' dof')
plt.title('$N_{epoch} = $' + str(Ndetect) + ', $N_{dof} = $' + str(Ndof))
plt.xlim(0, xlim)
plt.legend()
@@ -2306,7 +2311,7 @@ def plot_chi2_dist_per_filter(tab, Ndetect, motion_model_dict={}, xlim=40, n_bin
plt.hist(x[idx], bins=chi2_bins, histtype='stepfilled', label='RA', density=True, color='skyblue', alpha=0.8, edgecolor='k')
plt.hist(y[idx], bins=chi2_bins, histtype='stepfilled', label='DEC', density=True, color='orange', alpha=0.8, edgecolor='k')
plt.plot(chi2_xaxis, chi2.pdf(chi2_xaxis, Ndof), 'r-', alpha=0.6,
- label='$\chi^2$ ' + str(Ndof) + ' dof')
+ label=r'$\chi^2$ ' + str(Ndof) + ' dof')
#plt.title('$N_{epoch} = $' + str(Ndetect) + ', $N_{dof} = $' + str(Ndof))
plt.title(str(filter)+' (N = '+str(len(chi2_x_list))+')', fontsize=22)
plt.xlim(0, xlim)
@@ -2593,7 +2598,7 @@ def plot_chi2_dist_mag(tab, Ndetect, xlim=40, n_bins=30, boot_err=False):
plt.clf()
plt.hist(chi2_m[idx], bins=np.arange(xlim*10), histtype='step', density=True)
plt.plot(chi2_maxis, chi2.pdf(chi2_maxis, Ndof), 'r-', alpha=0.6,
- label='$\chi^2$ ' + str(Ndof) + ' dof')
+ label=r'$\chi^2$ ' + str(Ndof) + ' dof')
plt.title('$N_{epoch} = $' + str(Ndetect) + ', $N_{dof} = $' + str(Ndof))
plt.xlim(0, xlim)
plt.legend()
@@ -2642,7 +2647,7 @@ def plot_chi2_dist_mag_per_filter(tab, Ndetect, mlim=40, n_bins=30, xlim=40, fil
plt.clf()
plt.hist(chi2_m[idx], bins=np.arange(xlim*10), label='mag', histtype='stepfilled', density=True, color='green', alpha=0.7, edgecolor='k')
plt.plot(chi2_maxis, chi2.pdf(chi2_maxis, Ndof), 'r-', alpha=0.6,
- label='$\chi^2$ ' + str(Ndof) + ' dof')
+ label=r'$\chi^2$ ' + str(Ndof) + ' dof')
#plt.title('$N_{epoch} = $' + str(Ndetect) + ', $N_{dof} = $' + str(Ndof))
plt.xlim(0, xlim)
plt.xlabel(r'$\chi^{2}$', fontsize=28)
@@ -3612,8 +3617,8 @@ def plot_sky(stars_tab,
foo = cnorm(yearsInt[ee])
colorList.append( cmap(cnorm(yearsInt[ee])) )
- py.close(2)
- fig = py.figure(2, figsize=(13,10))
+ plt.close(2)
+ fig = plt.figure(2, figsize=(13,10))
previousYear = 0.0
@@ -3651,13 +3656,13 @@ def plot_sky(stars_tab,
label = '_nolegend_'
if plot_errors:
- (line, foo1, foo2) = py.errorbar(x, y, xerr=xe, yerr=ye,
+ (line, foo1, foo2) = plt.errorbar(x, y, xerr=xe, yerr=ye,
color=colorList[ee], fmt='^',
markeredgecolor=colorList[ee],
markerfacecolor=colorList[ee],
label=label, picker=4)
else:
- (line, foo1, foo2) = py.errorbar(x, y, xerr=None, yerr=None,
+ (line, foo1, foo2) = plt.errorbar(x, y, xerr=None, yerr=None,
color=colorList[ee], fmt='^',
markeredgecolor=colorList[ee],
markerfacecolor=colorList[ee],
@@ -3675,19 +3680,19 @@ def plot_sky(stars_tab,
point_labels[line] = points_info
foo = PrintSelected(point_labels, fig, stars_tab, mag_range, manual_print=manual_print)
- py.connect('pick_event', foo)
+ plt.connect('pick_event', foo)
xlo = xcenter + (range)
xhi = xcenter - (range)
ylo = ycenter - (range)
yhi = ycenter + (range)
- py.axis('equal')
- py.axis([xlo, xhi, ylo, yhi])
- py.xlabel('R.A. Offset from Sgr A* (arcsec)')
- py.ylabel('Dec. Offset from Sgr A* (arcsec)')
+ plt.axis('equal')
+ plt.axis([xlo, xhi, ylo, yhi])
+ plt.xlabel('R.A. Offset from Sgr A* (arcsec)')
+ plt.ylabel('Dec. Offset from Sgr A* (arcsec)')
- py.legend(handles=epochs_legend, numpoints=1, loc='lower left', fontsize=12)
+ plt.legend(handles=epochs_legend, numpoints=1, loc='lower left', fontsize=12)
if show_names:
xpos = stars_tab['x0']
@@ -3695,16 +3700,16 @@ def plot_sky(stars_tab,
goodind = np.where((xpos <= xlo) & (xpos >= xhi) &
(ypos >= ylo) & (ypos <= yhi))[0]
for ind in goodind:
- py.text(xpos[ind], ypos[ind], stars_tab['name'][ind], size=10)
+ plt.text(xpos[ind], ypos[ind], stars_tab['name'][ind], size=10)
if saveplot:
- py.show(block=0)
+ plt.show(block=0)
if (center_star != None):
- py.savefig('plot_sky_' + center_star + '.png')
+ plt.savefig('plot_sky_' + center_star + '.png')
else:
- py.savefig('plot_sky.png')
+ plt.savefig('plot_sky.png')
else:
- py.show()
+ plt.show()
return
diff --git a/flystar/starlists.py b/flystar/starlists.py
index 23df44f..f1f3278 100644
--- a/flystar/starlists.py
+++ b/flystar/starlists.py
@@ -421,7 +421,7 @@ def read_starlist(starlistFile, error=True):
starlist astropy table.
containing: name, m, x, y, xe, ye, t
"""
- t_ref = Table.read(starlistFile, format='ascii', delimiter='\s')
+ t_ref = Table.read(starlistFile, format='ascii', delimiter=r'\s')
# Check if this already has column names:
cols = t_ref.colnames
@@ -624,7 +624,7 @@ def from_lis_file(cls, filename, error=True, fvu_file=None):
------
starlists.StarList() object (subclass of Astropy Table).
"""
- t_ref = Table.read(filename, format='ascii', delimiter='\s')
+ t_ref = Table.read(filename, format='ascii', delimiter=r'\s')
# Check if this already has column names:
cols = t_ref.colnames
diff --git a/flystar/startables.py b/flystar/startables.py
index c12976e..b25f8c5 100644
--- a/flystar/startables.py
+++ b/flystar/startables.py
@@ -11,78 +11,74 @@
import copy
from flystar import motion_model
import pandas as pd
+from flystar.motion_model import Empty, Fixed, Linear
class StarTable(Table):
- """
- A StarTable is an astropy.Table with stars matched from multiple starlists.
+ def __init__(self, *args, ref_list=0, **kwargs):
+ """
+ A StarTable is an astropy.Table with stars matched from multiple starlists.
- Required table columns (input as keywords):
- -------------------------
- name : 1D numpy.array with shape = N_stars
- List of unique names for each of the stars in the table.
+ Required table columns (input as keywords):
+ -------------------------
+ name : 1D numpy.array with shape = N_stars
+ List of unique names for each of the stars in the table.
- x : 2D numpy.array with shape = (N_stars, N_lists)
- Positions of N_stars in each of N_lists in the x dimension.
+ x : 2D numpy.array with shape = (N_stars, N_lists)
+ Positions of N_stars in each of N_lists in the x dimension.
- y : 2D numpy.array with shape = (N_stars, N_lists)
- Positions of N_stars in each of N_lists in the y dimension.
+ y : 2D numpy.array with shape = (N_stars, N_lists)
+ Positions of N_stars in each of N_lists in the y dimension.
- m : 2D numpy.array with shape = (N_stars, N_lists)
- Magnitudes of N_stars in each of N_lists.
+ m : 2D numpy.array with shape = (N_stars, N_lists)
+ Magnitudes of N_stars in each of N_lists.
- Optional table columns (input as keywords):
- -------------------------
- motion_model : 1D numpy.array with shape = N_stars
- string indicating motion model type for each star
-
- xe : 2D numpy.array with shape = (N_stars, N_lists)
- Position uncertainties of N_stars in each of N_lists in the x dimension.
+ Optional table columns (input as keywords):
+ -------------------------
+ motion_model : 1D numpy.array with shape = N_stars
+ string indicating motion model type for each star
+
+ xe : 2D numpy.array with shape = (N_stars, N_lists)
+ Position uncertainties of N_stars in each of N_lists in the x dimension.
- ye : 2D numpy.array with shape = (N_stars, N_lists)
- Position uncertainties of N_stars in each of N_lists in the y dimension.
+ ye : 2D numpy.array with shape = (N_stars, N_lists)
+ Position uncertainties of N_stars in each of N_lists in the y dimension.
- me : 2D numpy.array with shape = (N_stars, N_lists)
- Magnitude uncertainties of N_stars in each of N_lists.
+ me : 2D numpy.array with shape = (N_stars, N_lists)
+ Magnitude uncertainties of N_stars in each of N_lists.
- ep_name : 2D numpy.array with shape = (N_stars, N_lists)
- Names in each epoch for each of N_stars in each of N_lists. This is
- useful for tracking purposes.
-
- corr : 2D numpy.array with shape = (N_stars, N_lists)
- Fitting correlation for each of N_stars in each of N_lists.
+ ep_name : 2D numpy.array with shape = (N_stars, N_lists)
+ Names in each epoch for each of N_stars in each of N_lists. This is
+ useful for tracking purposes.
+
+ corr : 2D numpy.array with shape = (N_stars, N_lists)
+ Fitting correlation for each of N_stars in each of N_lists.
- Optional table meta data
- -------------------------
- list_names : list of strings
- List of names, one for each of the starlists.
+ Optional table meta data
+ -------------------------
+ list_names : list of strings
+ List of names, one for each of the starlists.
- list_times : list of integers or floats
- List of times/dates for each starlist.
+ list_times : list of integers or floats
+ List of times/dates for each starlist.
- ref_list : int
- Specify which list is the reference list (if any).
+ ref_list : int
+ Specify which list is the reference list (if any).
- Examples
- --------------------------
+ Examples
+ --------------------------
- t = startables.StarTable(name=name, x=x, y=y, m=m)
+ t = startables.StarTable(name=name, x=x, y=y, m=m)
- # Access the data:
- print(t)
- print(t['name'][0:10]) # print the first 10 star names
- print(t['x'][0:10, 0]) # print x from the first epoch/list/column for the first 10 stars
- """
- def __init__(self, *args, ref_list=0, **kwargs):
- """
+ # Access the data:
+ print(t)
+ print(t['name'][0:10]) # print the first 10 star names
+ print(t['x'][0:10, 0]) # print x from the first epoch/list/column for the first 10 stars
"""
# Check if the required arguments are present
arg_req = ('name', 'x', 'y', 'm')
-
- found_all_required = True
- for arg_test in arg_req:
- if arg_test not in kwargs:
- found_all_required = False
+
+ found_all_required = all(arg in kwargs for arg in arg_req)
if not found_all_required:
if len(args) > 1: # If there are no arguments, it's because the
@@ -130,6 +126,7 @@ def __init__(self, *args, ref_list=0, **kwargs):
# We have to have special handling of meta-data (i.e. info that has
# dimensions of n_lists).
meta_tab = ('list_times', 'list_names')
+ meta_tab = ('list_times', 'list_names')
meta_type = ((float, int), str)
for mm in range(len(meta_tab)):
meta_test = meta_tab[mm]
@@ -151,7 +148,7 @@ def __init__(self, *args, ref_list=0, **kwargs):
names=('name', 'x', 'y', 'm'))
self['name'] = self['name'].astype('U20')
self.meta = {'n_stars': n_stars, 'n_lists': n_lists, 'ref_list': ref_list}
-
+
for meta_arg in meta_tab:
if meta_arg in kwargs:
self.meta[meta_arg] = kwargs[meta_arg]
@@ -161,7 +158,7 @@ def __init__(self, *args, ref_list=0, **kwargs):
del kwargs[meta_arg]
for arg in kwargs:
- if arg in ['name', 'x', 'y', 'm']:
+ if arg in ['name', 'x', 'y', 'm', 'list_times', 'list_names']:
continue
else:
self.add_column(Column(data=kwargs[arg], name=arg))
@@ -225,7 +222,7 @@ def _add_list_data_from_starlist(self, starlist):
else: # Add junk data it if wasn't input
self._set_invalid_list_values(col_name, -1)
-
+
##########
# Update the table meta-data. Remember that entries are lists not numpy arrays.
##########
@@ -234,7 +231,7 @@ def _add_list_data_from_starlist(self, starlist):
lis_meta_keys = list(starlist.meta.keys())
# append 's' to the end to pluralize the input starlist.
lis_meta_keys_plural = [lis_meta_key + 's' for lis_meta_key in lis_meta_keys]
-
+
for kk in range(len(tab_meta_keys)):
tab_key = tab_meta_keys[kk]
@@ -244,19 +241,19 @@ def _add_list_data_from_starlist(self, starlist):
# If we find the key in the starlists' meta argument, then add the new values.
# Otherwise, add "None".
- idx = np.where(lis_meta_keys_plural == tab_key)[0]
- if len(idx) > 0:
- lis_key = lis_meta_keys[idx[0]]
+ idx = lis_meta_keys_plural.index(tab_key) if tab_key in lis_meta_keys_plural else None
+ if idx is not None:
+ lis_key = lis_meta_keys[idx]
self.meta[tab_key] = np.append(self.meta[tab_key], [starlist.meta[lis_key]])
else:
self._append_invalid_meta_values(tab_key)
# Update the n_lists meta keyword.
self.meta['n_lists'] += 1
-
+
return
-
-
+
+
def _add_list_data_from_keywords(self, **kwargs):
# # Check if the required arguments are present
# arg_req = ('x', 'y', 'm')
@@ -539,331 +536,438 @@ def detections(self):
return
- def fit_velocities(self, weighting='var', use_scipy=True, absolute_sigma=True, bootstrap=0,
- fixed_t0=False, verbose=False, mask_val=None, mask_lists=False, show_progress=True,
- default_motion_model='Linear', reassign_motion_model=False, select_stars=None, motion_model_dict={}):
- """Fit velocities for all stars in the table and add to the columns 'vx', 'vxe', 'vy', 'vye', 'x0', 'x0e', 'y0', 'y0e'.
+ def fit_motion_model(
+ self,
+ motion_models=None,
+ fixed_params_dict=None,
+ weighting='var',
+ use_scipy=False,
+ absolute_sigma=True,
+ select_stars=None,
+ bootstrap=0,
+ verbose=True,
+ mask_value=None,
+ mask_lists=None,
+ fill_value=np.nan,
+ show_progress=True
+ ):
+ """Fit velocity for star table
Parameters
----------
+ motion_models : list of MotionModel or str, optional
+ Motion models to use, by default Empty, Fixed and Linear.
+ Empty and Fixed models are always added automatically for stars with n_fit = 0 or 1.
+ The behavior is as follows:
+ 1. If 'motion_model_input' column is NOT in table:
+ - Use the most complex model that has enough parameters to fit the data (n_fit >= n_params).
+ - If multiple models are supplied, prioritize the model with the most parameters to fit.
+ - If multiple models have the same number of parameters, raise AssertionError: not sure which to use.
+ 2. If 'motion_model_input' column IS in table:
+ - Use the model specified in the 'motion_model_input' column.
+ - If not enough data points to fit the specified model, use the most complex model in any 'motion_model_input' column that has enough parameters to fit the data (n_fit >= n_params) among the provided motion_models and 'motion_model_input'.
+ The actual used motion model is stored in the 'motion_model_used' column. The default motion_models are [Empty, Fixed, Linear].
+ fixed_params_dict : dict, optional
+ Dictionary of fixed parameters for motion models, e.g., {'t0': 0., 'ra': np.array([...]), 'dec': np.array([...])}.
+ - Scalar values are used for all stars, array values should have length = N_stars.
+ - t0 is automatically calculated as np.average(t, weights=1/np.hypot(xe, ye)) if not provided.
+ - The keys should match the fixed parameter names in the motion models. See MotionModel class for details, by default None
weighting : str, optional
- Weight by variance 'var' or standard deviation 'std', by default 'var'
+ Uncertainty weighting, 'std' for weight=1/xe(ye) or 'var' for weight=1/xe(ye)**2, by default 'var'
+ use_scipy : bool, optional
+ Use scipy.optimize.curve_fit or algebraic solution (for Linear model only), by default False
+ absolute_sigma : bool, optional
+ Use absolute sigma or not, see scipy curve_fit for details, by default True
+ select_stars : list of int, optional
+ Indices of stars to fit, by default None (fit all stars)
bootstrap : int, optional
- Calculate uncertainty using bootstraping or not, by default 0
- fixed_t0 : bool or array-like, optional
- Fix the t0 in dt = time - t0 if user provides an array with the same length of the table, or automatically calculate t0 = np.average(time, weights=1/np.hypot(xe, ye)) if False, by default False
+ Number of bootstrap for uncertainty resampling, by default 0
verbose : bool, optional
- Output verbose information or not, by default False
- mask_val : float, optional
- Value that needs to be masked in the data, e.g. -100000, by default None
- mask_lists : list, optional
- Columns that needs to be masked, by default False
+ Print verbose messages or not, by default True
+ mask_value : float, optional
+ Values to mask in data, by default None
+ mask_lists : list of int, optional
+ Indices of lists to mask/exclude from fitting, by default None
+ fill_value : float, optional
+ Fill value when there is not enough data points to fit, by default np.nan
show_progress : bool, optional
Show progress bar or not, by default True
Raises
------
ValueError
- If weighting is neither 'var' or 'std'
+ If weighting is not 'var' or 'std'.
KeyError
- If there's not time information in the table
+ If time values are not found in the table or meta.
+ KeyError
+ If required columns 'x' and 'y' are missing in the table.
"""
+ ###########################
+ ####### Check Params ######
+ ###########################
if weighting not in ['var', 'std']:
- raise ValueError(f"fit_velocities: Weighting must either be 'var' or 'std', not {weighting}!")
-
+ raise ValueError(f"fit_motion_model: Weighting must either be 'var' or 'std', not {weighting}!")
+
if ('t' not in self.colnames) and ('list_times' not in self.meta):
- raise KeyError("fit_velocities: Failed to access time values. No 't' column in table, no 'list_times' in meta.")
-
+ raise KeyError("fit_motion_model: Failed to access time values. No 't' column in table, no 'list_times' in meta.")
+
# Check if we have the required columns
if not all([_ in self.colnames for _ in ['x', 'y']]):
- raise KeyError(f"fit_velocities: Missing required columns in the table: {', '.join(['x', 'y'])}!")
+ raise KeyError(f"fit_motion_model: Missing required columns in the table: {', '.join(['x', 'y'])}!")
+
+ # Check fixed_params_dict is a dict
+ if fixed_params_dict is not None:
+ if not isinstance(fixed_params_dict, dict):
+ raise ValueError("fit_motion_model: fixed_params_dict must be a dictionary!")
+
+ # Convert motion_models to MotionModel objects if they are strings:
+ if motion_models is None:
+ # Setting the default to None to avoid mutable default argument issue
+ # See https://stackoverflow.com/questions/15189245/assigning-class-variable-as-default-value-to-class-method-argument
+ motion_models = [Empty, Fixed, Linear]
+ all_mm_map = motion_model.motion_model_map()
+ if all(isinstance(mm, str) for mm in motion_models):
+ mm_names = motion_models
+ motion_models = [all_mm_map[mm] for mm in motion_models]
+ else:
+ mm_names = [mm.name for mm in motion_models]
+ # Always add Empty and Fixed in motion models
+ if 'Fixed' not in mm_names:
+ motion_models.insert(0, Fixed)
+ if 'Empty' not in mm_names:
+ motion_models.insert(0, Empty)
+ mm_names = [mm.name for mm in motion_models]
+
+ # Construct motion models if motion_model_input column exists
+ if 'motion_model_input' in self.colnames:
+ input_mm_names = np.unique(self['motion_model_input'])
+ assert all([name in all_mm_map.keys() for name in input_mm_names]), \
+ f"fit_motion_model: Unknown motion model name(s) in 'motion_model_input' column. Available motion models are: {', '.join(all_mm_map.keys())}."
+ for mm_name in input_mm_names:
+ if mm_name not in mm_names:
+ motion_models.append(all_mm_map[mm_name])
+
+ # Sort motion models by n_params
+ motion_models = sorted(motion_models, key=lambda mm: mm.n_params)
+
+ input_mm_map = {mm.name: mm for mm in motion_models}
+
+ mm_n_params = np.sort([mm.n_params for mm in motion_models])
+ if 'motion_model_input' not in self.colnames:
+ # If motion_model_input column is not provided, assert that motion model n_params are unique and sorted
+ # Otherwise the fitter does not know which motion model to use based on n_obs
+ assert len(mm_n_params) == len(set(mm_n_params)), \
+ f"fit_motion_model: Provided motion model n_params are not unique! Motion Models are: {[_.name for _ in motion_models]} Cannot decide which motion model to use based on n_obs. Please provide unique motion_models or a 'motion_model_input' column."
+
+
+ ###########################
+ ####### Prepare Data ######
+ ###########################
+ # Prepare data for fitting
N_stars = len(self)
+ x_data = np.ma.masked_invalid(self['x'].data, copy=True)
+ y_data = np.ma.masked_invalid(self['y'].data, copy=True)
+ xe_data = np.ma.masked_invalid(self['xe'].data, copy=True) if 'xe' in self.colnames else np.ones_like(x_data)
+ ye_data = np.ma.masked_invalid(self['ye'].data, copy=True) if 'ye' in self.colnames else np.ones_like(y_data)
+
+ if mask_lists is not None:
+ x_data.mask[:, mask_lists] = True
+ y_data.mask[:, mask_lists] = True
+ xe_data.mask[:, mask_lists] = True
+ ye_data.mask[:, mask_lists] = True
+
+ # t_data: 2d array with shape (N_stars, N_epochs)
+ # t0: 1d array with shape (N_stars,)
+ if 't' in self.colnames:
+ t_data = copy.deepcopy(self['t'].data)
+ else:
+ t_data = copy.deepcopy(np.array(self.meta['list_times']))
+ t_data = np.broadcast_to(t_data, x_data.shape)
+
+ # Add default t0 if not provided in fixed_params_dict
+ if fixed_params_dict is None:
+ weights = 1/np.hypot(xe_data, ye_data) if xe_data is not None else None
+ fixed_params_dict = {'t0': np.average(t_data, axis=1, weights=weights)}
+ elif 't0' not in fixed_params_dict:
+ weights = 1/np.hypot(xe_data, ye_data) if xe_data is not None else None
+ fixed_params_dict['t0'] = np.average(t_data, axis=1, weights=weights)
+ else:
+ if np.ndim(fixed_params_dict['t0']) == 0:
+ fixed_params_dict['t0'] = np.full(N_stars, fixed_params_dict['t0'])
+
+ t0 = fixed_params_dict['t0']
+
+ # Prepare fixed_params_dict for each star
+ # This avoids checking types and slicing inside the fitting loop
+ fixed_params_stars = [{} for _ in range(N_stars)]
+ # Identify array parameters (length N_stars) and scalar parameters
+ array_params = {k: v for k, v in fixed_params_dict.items() if np.ndim(v) > 0 and len(v) == N_stars}
+ scalar_params = {k: v for k, v in fixed_params_dict.items() if k not in array_params}
+
+ # Construct list of dicts for each star
+ # Using list comprehension for speed
+ fixed_params_stars = [
+ {**scalar_params, **{k: v[i] for k, v in array_params.items()}}
+ for i in range(N_stars)
+ ]
+
+ # Apply mask_value if provided
+ if mask_value:
+ x_data = np.ma.masked_values(x_data, mask_value)
+ y_data = np.ma.masked_values(y_data, mask_value)
+ if xe_data is not None:
+ xe_data = np.ma.masked_values(xe_data, mask_value)
+ if ye_data is not None:
+ ye_data = np.ma.masked_values(ye_data, mask_value)
+
+
+ # Calculate mask array
+ xy_mask = (~x_data.mask) & (~y_data.mask)
+ self['n_fit'] = xy_mask.sum(axis=1)
+
+ # Convert to lists of arrays for faster access during fitting
+ t_stars = [np.array(t_data[i][xy_mask[i]]) for i in range(N_stars)]
+ x_stars = [np.array(x_data[i][xy_mask[i]]) for i in range(N_stars)]
+ y_stars = [np.array(y_data[i][xy_mask[i]]) for i in range(N_stars)]
+ xe_stars = [np.array(xe_data[i][xy_mask[i]]) if xe_data is not None else None for i in range(N_stars)]
+ ye_stars = [np.array(ye_data[i][xy_mask[i]]) if ye_data is not None else None for i in range(N_stars)]
+
+
+ ###########################
+ ####### Determine MM ######
+ ###########################
+ n_fit = np.array(self['n_fit'])
+ if 'motion_model_input' in self.colnames:
+ # Determine which motion model to use based on motion_model_input column
+ # If n_fit < required n_params for the input motion model, use the most complicated motion model with n_fit >= n_params
+ required_params = np.array([all_mm_map[mm_name].n_params for mm_name in self['motion_model_input']])
+ reassign_mm = n_fit < required_params
+
+ mm_digitized = np.digitize(
+ x=n_fit[reassign_mm],
+ bins=mm_n_params
+ ) - 1 # Convert to 0-based index
+
+ # Assign motion models to stars
+ self['motion_model_used'] = self['motion_model_input']
+ self['motion_model_used'][reassign_mm] = np.array([motion_models[d].name for d in mm_digitized], dtype='U20')
- if verbose:
- start_time = time.time()
- msg = 'Starting startable.fit_velocities for {0:d} stars with n={1:d} bootstrap'
- print(msg.format(N_stars, bootstrap))
-
- # Set all to default_motion_model if none assigned already.
- # Reset motion_model_used to the inputs for now -> will change as fits run
- if ('motion_model_input' not in self.colnames) or reassign_motion_model:
- self['motion_model_input'] = default_motion_model
- self['motion_model_used'] = self['motion_model_input']
+ else:
+ mm_digitized = np.digitize(
+ x=n_fit,
+ bins=mm_n_params
+ ) - 1 # Convert to 0-based index
- motion_model_dict = motion_model.validate_motion_model_dict(motion_model_dict, self, default_motion_model)
-
- #
- # Fill table with all possible motion model parameter names as new
- # columns. Make everything empty for now.
- #
- all_motion_models = np.unique(self['motion_model_input'].tolist() + ['Fixed']+[default_motion_model]).tolist()
- new_col_list = motion_model.get_list_motion_model_param_names(all_motion_models, with_errors=True)
- # Append goodness of fit metrics and t0.
+ # Assign motion models to stars
+ self['motion_model_used'] = np.array([motion_models[d].name for d in mm_digitized], dtype='U20')
+
+ # Add default obsLocation if not provided in fixed_params_dict
+ mm_used = np.unique(self['motion_model_used'].name)
+ if 'Parallax' in mm_used and 'obsLocation' not in fixed_params_dict:
+ fixed_params_dict['obsLocation'] = 'earth'
+
+ ############################
+ ####### Prepare Table ######
+ ############################
+ # Fill table with all possible motion model parameter names as new columns.
+ motion_model_used = [all_mm_map[name] for name in np.unique(self['motion_model_used'])]
+ new_col_list = motion_model.motion_model_param_names(motion_model_used, with_errors=True, with_fixed=False)
new_col_list += ['chi2_x', 'chi2_y', 'n_params']
+
if 't0' not in new_col_list:
new_col_list.append('t0')
- # Define output arrays for the best-fit parameters.
+ # Add new columns if they do not exist
for col in new_col_list:
- # Clean/remove up old arrays.
- if col in self.colnames: self.remove_column(col)
- # Add column #TODO: is this good for filling???
- self.add_column(Column(data = np.full(N_stars, np.nan, dtype=float), name = col))
-
- # Add a column to keep track of the number of points used in a fit.
- self['n_fit'] = 0
-
- # Preserve the number of bootstraps that will be run (if any).
- self.meta['n_fit_bootstrap'] = bootstrap
-
- # (FIXME: Do we need to catch the case where there's a single *unmasked* epoch?)
- # Catch the case when there is only a single epoch. Just return 0 velocity
- # and the same input position for the x0/y0.
- if len(self['x'].shape) == 1:
- self['motion_model_used'] = 'Fixed'
- self['x0'] = self['x']
- self['y0'] = self['y']
- if 't' in self.colnames:
- self['t0'] = self['t']
+ if col in self.colnames:
+ # Keep old data if the column already exists
+ continue
+ if col.endswith('_err'):
+ self.add_column(
+ Column(data=np.full(N_stars, np.inf, dtype=float), name=col),
+ rename_duplicate=True
+ )
else:
- self['t0'] = self.meta['list_times'][0]
- if 'xe' in self.colnames:
- self['x0_err'] = self['xe']
- self['y0_err'] = self['ye']
- self['n_fit'] = 1
- self['n_params'] = 1
- return
-
- if (self['x'].shape[1] == 1):
- self['motion_model_used'] = 'Fixed'
- self['x0'] = self['x'][:,0]
- self['y0'] = self['y'][:,0]
- if 't' in self.colnames:
- self['t0'] = self['t'][:, 0]
+ self.add_column(
+ Column(data=np.full(N_stars, fill_value, dtype=float), name=col),
+ rename_duplicate=True
+ )
+
+ # Add fixed parameter columns if they do not exist
+ fixed_param_names = []
+ for mm in motion_model_used:
+ for param in mm.fixed_param_names:
+ if param not in fixed_param_names:
+ fixed_param_names.append(param)
+ # Remove t0 from fixed_param_names as it will be saved during fitting
+ if 't0' in fixed_param_names:
+ fixed_param_names.remove('t0')
+
+ # Add fixed parameter columns
+ for param in fixed_param_names:
+ coldata = np.array([fixed_params_stars[i][param] for i in range(N_stars)])
+ if param in self.colnames:
+ # If the column already exists, check if the data are the same
+ if np.allclose(self[param], coldata, equal_nan=True):
+ # Same data, skip
+ continue
+ else:
+ # Different data, add with _mm suffix to avoid name conflict
+ colname = param + '_mm'
else:
- self['t0'] = self.meta['list_times'][0]
- if 'xe' in self.colnames:
- self['x0_err'] = self['xe'][:,0]
- self['y0_err'] = self['ye'][:,0]
- self['n_fit'] = 1
- self['n_params'] = 1
- return
-
- # Only fit selected stars, if list given
- fit_star_idxs = range(N_stars)
+ colname = param
+
+ self.add_column(Column(data=coldata, name=colname))
+
+
+ # Add a column to keep track of the number of points used in a fit and number of bootstrap used.
+ self.meta['n_bootstrap'] = bootstrap
+
+
+ ###########################
+ ######### FITTING #########
+ ###########################
+ unique_motion_models, unique_inv_indices = np.unique(self['motion_model_used'], return_inverse=True)
if select_stars is not None:
- fit_star_idxs = select_stars
- # STARS LOOP through the stars and work on them 1 at a time.
- # This is slow; but robust.
- if show_progress:
- for ss in tqdm(fit_star_idxs):
- self.fit_velocity_for_star(ss, motion_model_dict, weighting=weighting, bootstrap=bootstrap,
- use_scipy=use_scipy, absolute_sigma=absolute_sigma,
- fixed_t0=fixed_t0, default_motion_model=default_motion_model,
- mask_val=mask_val, mask_lists=mask_lists)
+ select_stars = np.asarray(select_stars)
+ if select_stars.dtype == bool:
+ select_stars = np.flatnonzero(select_stars)
+ else:
+ select_stars = np.asarray(select_stars, dtype=int)
+ indices_by_motion_model = {key: np.intersect1d(select_stars, np.flatnonzero(unique_inv_indices == k)) for k, key in enumerate(unique_motion_models)}
else:
- for ss in fit_star_idxs:
- self.fit_velocity_for_star(ss, motion_model_dict, weighting=weighting, bootstrap=bootstrap,
- use_scipy=use_scipy, absolute_sigma=absolute_sigma,
- fixed_t0=fixed_t0, default_motion_model=default_motion_model,
- mask_val=mask_val, mask_lists=mask_lists)
- if verbose:
- stop_time = time.time()
- print('startable.fit_velocities runtime = {0:.0f} s for {1:d} stars'.format(stop_time - start_time, N_stars))
-
+ indices_by_motion_model = {key: np.flatnonzero(unique_inv_indices == k) for k, key in enumerate(unique_motion_models)}
+
+
+ # Expensive for loop! Prepare everything beforehand to speed up.
+ for unique_motion_model, unique_index in indices_by_motion_model.items():
+ # Create motion model instance
+ motion_model_instance = input_mm_map[unique_motion_model]()
+ param_names = motion_model_instance.fit_param_names
+ # Initialize arrays to store results
+ n_stars_this_model = len(unique_index)
+ n_params = len(param_names)
+
+ params_array = np.full((n_stars_this_model, n_params), fill_value, dtype=float)
+ param_errs_array = np.full((n_stars_this_model, n_params), np.inf, dtype=float)
+ chi2_x_array = np.full(n_stars_this_model, np.nan, dtype=float)
+ chi2_y_array = np.full(n_stars_this_model, np.nan, dtype=float)
+
+ # Expensive for loop! Prepare everything beforehand to speed up.
+ for idx, i_star in enumerate(tqdm(unique_index, disable=not show_progress, desc=f"Fitting motion model {unique_motion_model}")):
+ # Fit the star
+ params, param_errs, chi2_x, chi2_y = motion_model_instance.fit(
+ t=t_stars[i_star],
+ x=x_stars[i_star],
+ y=y_stars[i_star],
+ xe=xe_stars[i_star],
+ ye=ye_stars[i_star],
+ fixed_params_dict=fixed_params_stars[i_star],
+ weighting=weighting,
+ use_scipy=use_scipy,
+ absolute_sigma=absolute_sigma,
+ bootstrap=bootstrap,
+ fill_value=fill_value,
+ return_chi2=True,
+ verbose=verbose
+ )
+ params_array[idx] = params
+ param_errs_array[idx] = param_errs
+ chi2_x_array[idx] = chi2_x
+ chi2_y_array[idx] = chi2_y
+
+ # Store results back to the table
+ for j, param_name in enumerate(param_names):
+ self[param_name][unique_index] = params_array[:, j]
+ self[param_name + '_err'][unique_index] = param_errs_array[:, j]
+ self['chi2_x'][unique_index] = chi2_x_array
+ self['chi2_y'][unique_index] = chi2_y_array
+ self['n_params'][unique_index] = motion_model_instance.n_params
+ self['t0'][unique_index] = t0[unique_index]
return
- def fit_velocity_for_star(self, ss, motion_model_dict, weighting='var', use_scipy=True, absolute_sigma=True,
- bootstrap=False, fixed_t0=False, mask_val=None, mask_lists=False,
- default_motion_model='Linear'):
- # TODO: "weighting" is not used
- #
- # Make a mask of invalid (NaN) values and a user-specified invalid value.
- #
-
- x = np.ma.masked_invalid(self['x'][ss, :].data)
- y = np.ma.masked_invalid(self['y'][ss, :].data)
- if mask_val:
- x = np.ma.masked_values(x, mask_val)
- y = np.ma.masked_values(y, mask_val)
- # If no mask, convert x.mask to list
- if not np.ma.is_masked(x):
- x.mask = np.zeros_like(x.data, dtype=bool)
- if not np.ma.is_masked(y):
- y.mask = np.zeros_like(y.data, dtype=bool)
-
- if mask_lists is not False:
- # Remove a list
- if isinstance(mask_lists, list):
- if all(isinstance(item, int) for item in mask_lists):
- x.mask[mask_lists] = True
- y.mask[mask_lists] = True
-
- # Throw a warning if mask_lists is not a list
- if not isinstance(mask_lists, list):
- raise RuntimeError('mask_lists needs to be a list.')
- #
- # Assign the appropriate positional errors
- #
- if 'xe' in self.colnames:
- # Make a mask of invalid (NaN) values and a user-specified invalid value.
- xe = np.ma.masked_invalid(self['xe'][ss, :].data)
- ye = np.ma.masked_invalid(self['ye'][ss, :].data)
-
- # Catch the case where we have positions but no errors for
- # some of the entries... we need to "fill in" reasonable
- # weights for these... just use the average weights over
- # all the other epochs.
- pos_no_err = np.where((np.isfinite(x) & np.isfinite(y)) &
- (np.isfinite(xe) == False) & (np.isfinite(ye) == False))[0]
- pos_with_err = np.where((np.isfinite(x) & np.isfinite(y)) &
- (np.isfinite(xe) & np.isfinite(ye)))[0]
-
- if len(pos_with_err) > 0:
- xe[pos_no_err] = xe[pos_with_err].mean()
- ye[pos_no_err] = ye[pos_with_err].mean()
- else:
- xe[pos_no_err] = 1.0
- ye[pos_no_err] = 1.0
- else:
- N_epochs = len(x)
- xe = np.ones(N_epochs, dtype=float)
- ye = np.ones(N_epochs, dtype=float)
- xe = np.ma.masked_invalid(xe)
- ye = np.ma.masked_invalid(xe)
+ def infer_positions(self, times, fill_value=np.nan):
+ """Infer star positions at given times using fitted motion models.
- if mask_val:
- xe = np.ma.masked_values(xe, mask_val)
- ye = np.ma.masked_values(ye, mask_val)
- # If no mask, convert xe.mask to list
- if not np.ma.is_masked(xe):
- xe.mask = np.zeros_like(xe.data, dtype=bool)
- if not np.ma.is_masked(ye):
- ye.mask = np.zeros_like(ye.data, dtype=bool)
-
- if mask_lists is not False:
- # Remove a list
- if isinstance(mask_lists, list):
- if all(isinstance(item, int) for item in mask_lists):
- xe.mask[mask_lists] = True
- ye.mask[mask_lists] = True
-
- # Throw a warning if mask_lists is not a list
- if not isinstance(mask_lists, list):
- raise RuntimeError('mask_lists needs to be a list.')
+ Parameters
+ ----------
+ times : array_like
+ Times at which to predict positions.
+ fill_value : float, optional
+ Value to use for missing data, by default np.nan
- #
- # Make a mask of invalid (NaN) values and a user-specified invalid value.
- #
- if 't' in self.colnames:
- t = np.ma.masked_invalid(self['t'][ss, :].data)
+ Returns
+ -------
+ x, y, xe, ye : ndarray
+ Arrays of predicted x, y positions and their uncertainties xe, ye, with shape (N_stars, N_times) or (N_stars,) if N_times=1, or (N_times,) if N_stars=1, or scalar.
+ """
+ assert 'motion_model_used' in self.colnames, \
+ "infer_positions: 'motion_model_used' column not found in the table. Please run fit_motion_model() first."
+
+ N_stars = len(self)
+ times = np.atleast_1d(times)
+ N_times = len(times)
+
+ if (N_stars > 1) and (N_times > 1):
+ x_pred = np.full((N_stars, N_times), fill_value, dtype=float)
+ y_pred = np.full((N_stars, N_times), fill_value, dtype=float)
+ xe_pred = np.full((N_stars, N_times), np.inf, dtype=float)
+ ye_pred = np.full((N_stars, N_times), np.inf, dtype=float)
+ elif N_stars==1:
+ x_pred = np.full(N_times, fill_value, dtype=float)
+ y_pred = np.full(N_times, fill_value, dtype=float)
+ xe_pred = np.full(N_times, np.inf, dtype=float)
+ ye_pred = np.full(N_times, np.inf, dtype=float)
else:
- t = np.ma.masked_invalid(self.meta['list_times'])
+ x_pred = np.full(N_stars, fill_value, dtype=float)
+ y_pred = np.full(N_stars, fill_value, dtype=float)
+ xe_pred = np.full(N_stars, np.inf, dtype=float)
+ ye_pred = np.full(N_stars, np.inf, dtype=float)
- if mask_val:
- t = np.ma.masked_values(t, mask_val)
- if not np.ma.is_masked(t):
- t.mask = np.zeros_like(t.data, dtype=bool)
+
+ unique_motion_models, unique_inv_indices = np.unique(self['motion_model_used'], return_inverse=True)
+ indices_by_motion_model = {key: np.flatnonzero(unique_inv_indices == k) for k, key in enumerate(unique_motion_models)}
+
+ # Prepare fit_params, fixed_params, fit_param_errs for each star
+
+ for unique_motion_model, unique_index in indices_by_motion_model.items():
+ # Create motion model instance
+ motion_model_instance = motion_model.motion_model_map()[unique_motion_model]()
+ # Prepare parameters for prediction
+ fit_params = np.array([
+ self[param_name][unique_index] for param_name in motion_model_instance.fit_param_names
+ ]).T # shape (N_stars_this_model, N_params)
+
+ fit_param_errs = np.array([
+ self[param_name + '_err'][unique_index] for param_name in motion_model_instance.fit_param_names
+ ]).T # shape (N_stars_this_model, N_params)
+
+ fixed_params = {}
+ for param_name in motion_model_instance.fixed_param_names:
+ col_name = param_name
+ if param_name + '_mm' in self.colnames:
+ col_name = param_name + '_mm'
+ fixed_params[param_name] = self[col_name][unique_index]
- if mask_lists is not False:
- # Remove a list
- if isinstance(mask_lists, list):
- if all(isinstance(item, int) for item in mask_lists):
- t.mask[mask_lists] = True
+ # TODO: vectorize obsLocation handling in motion models
+ if (param_name == 'obsLocation'):
+ assert np.unique(fixed_params[param_name]).size == 1, \
+ "infer_positions: obsLocation fixed parameter has different values for different stars. Vectorized handling not implemented yet."
+ fixed_params[param_name] = fixed_params[param_name][0]
- # Throw a warning if mask_lists is not a list
- if not isinstance(mask_lists, list):
- raise RuntimeError('mask_lists needs to be a list.')
+ # Predict positions
+ x, y, xe, ye = motion_model_instance.model(
+ times, fit_params, fit_param_errs, fixed_params
+ )
+ x_pred[unique_index] = x
+ y_pred[unique_index] = y
+ xe_pred[unique_index] = xe
+ ye_pred[unique_index] = ye
+
+ return x_pred, y_pred, xe_pred, ye_pred
- # For inconsistent masks, mask the star if any of the values are masked.
- new_mask = np.logical_or.reduce((t.mask, x.mask, y.mask, xe.mask, ye.mask))
-
- #
- # Figure out where we have detections (as indicated by error columns)
- #
- good = np.where((xe != 0) & (ye != 0) &
- np.isfinite(xe) & np.isfinite(ye) &
- np.isfinite(x) & np.isfinite(y) & ~new_mask)[0]
-
- N_good = len(good)
-
- # Catch the case where there is NO good data.
- if N_good == 0:
- #self['motion_model_used'][ss] = 'None'
- self['n_fit'][ss] = N_good
- self['n_params'][ss] = 0
- return
- # Everything below has N_good >= 1
- x = x[good]
- y = y[good]
- t = t[good]
- xe = xe[good]
- ye = ye[good]
-
- #
- # Unless t0 is fixed, calculate the t0 for the stars.
- #
- if fixed_t0 is False:
- t_weight = 1.0 / np.hypot(xe, ye)
- t0 = np.average(t, weights=t_weight)
- elif fixed_t0 is True:
- t0 = self.t0
- else:
- t0 = fixed_t0[ss]
- self['t0'][ss] = t0
- self['n_fit'][ss] = N_good
-
- #
- # Decide which motion_model to fit.
- #
- motion_model_use = self['motion_model_input'][ss]
- # Go to default model if not enough points for assigned but enough for default
- # TODO: think about whether we want other fallbacks besides the singular default and Fixed
- if (N_good < motion_model_dict[motion_model_use].n_pts_req) and \
- (N_good >= motion_model_dict[default_motion_model].n_pts_req):
- motion_model_use = default_motion_model
- # If not enough points for either, go to a fixed model
- elif (N_good < motion_model_dict[motion_model_use].n_pts_req) and \
- (N_good < motion_model_dict[default_motion_model].n_pts_req):
- motion_model_use = 'Fixed'
- # If the points do not cover multiple times, go to a fixed model
- if (t == t[0]).all():
- motion_model_use = 'Fixed'
-
- self['motion_model_used'][ss] = motion_model_use
-
-# # Get the motion model object.
-# modClass = motion_model_dict[motion_model_use]
-#
-# # Load up any prior information on parameters for this model.
-# param_dict = {}
-# for par in modClass.fitter_param_names+modClass.fixed_param_names:
-# if ~np.isnan(self[par][ss]):
-# param_dict[par] = self[par][ss]
-
- # Model object
- mod = motion_model_dict[motion_model_use]
- fixed_params = [self[par][ss] for par in mod.fixed_param_names]
-
- # Fit for the best parameters
- params, param_errs = mod.fit_motion_model(t, x, y, xe, ye, t0, bootstrap=bootstrap,
- weighting=weighting, use_scipy=use_scipy, absolute_sigma=absolute_sigma)
- chi2_x,chi2_y = mod.get_chi2(params,fixed_params, t,x,y,xe,ye)
- self['chi2_x'][ss]=chi2_x
- self['chi2_y'][ss]=chi2_y
- self['n_params'][ss] = mod.n_params
-
- # Save parameters and errors to table.
- for pp in range(len(mod.fitter_param_names)):
- par = mod.fitter_param_names[pp]
- par_err = par + '_err'
- self[par][ss] = params[pp]
- self[par_err][ss] = param_errs[pp]
-
- return
-
# New function, to use in align
def get_star_positions_at_time(self, t, motion_model_dict, allow_alt_models=True):
""" Get current x,y positions of each star according to its motion_model
@@ -893,7 +997,7 @@ def get_star_positions_at_time(self, t, motion_model_dict, allow_alt_models=True
mod = motion_model_dict[mm]
# Set up parameters
param_dict = {}
- for par in mod.fitter_param_names + mod.fixed_param_names + [pm+'_err' for pm in mod.fitter_param_names]:
+ for par in mod.fit_param_names + mod.fixed_param_names + [pm+'_err' for pm in mod.fit_param_names]:
param_dict[par] = self[par][idx]
x[idx],y[idx],xe[idx],ye[idx] = mod.get_batch_pos_at_time(t,**param_dict)
except:
@@ -913,147 +1017,9 @@ def get_star_positions_at_time(self, t, motion_model_dict, allow_alt_models=True
param_dict[par] = self[par][idx]
x[idx],y[idx],xe[idx],ye[idx] = mod.get_batch_pos_at_time(t,**param_dict)
- return x,y,xe,ye
+ return x, y, xe, ye
- def fit_velocities_all_detected(self, motion_model_to_fit, weighting='var', use_scipy=True, absolute_sigma=True, times=None,
- select_stars=None, epoch_cols='all', mask_val=None, art_star=False, return_result=False):
- """Fit velocities for stars detected in all epochs specified by epoch_cols.
- Criterion: xe/ye error > 0 and finite, x/y not masked.
-
- Parameters
- ----------
- motion_model_to_fit : MotionModel
- Motion model object to use for fitting all stars
- weighting : str, optional
- Variance weighting('var') or standard deviation weighting ('std'), by default 'var'
- select_idx : array-like, optional
- Indices of stars to select for fitting, by default None (fit all detected stars)
- epoch_cols : str or list of intergers, optional
- List of epoch column indices used for fitting velocity, by default 'all'
- mask_val : float, optional
- Values in x, y to be masked
- art_star : bool, optional
- Artificial star or observation star catalog. If artificial star, use 'det' column to select stars detected in all epochs, by default False
- return_result : bool, optional
- Return the velocity results or not, by default False
-
- Returns
- -------
- vel_result : astropy Table
- Astropy Table with velocity results
- """
-
- N_stars = len(self)
- if select_stars is None:
- select_stars = np.arange(N_stars)
- else:
- select_stars = np.asarray(select_stars)
-
- if epoch_cols == 'all':
- epoch_cols = np.arange(np.shape(self['x'])[1])
-
- # Artificial Star
- if art_star:
- detected_in_all_epochs = np.all(self['det'][select_stars, :][:, epoch_cols], axis=1)
-
- # Observation Star
- else:
- valid_xe = np.all(self['xe'][select_stars, :][:, epoch_cols]!=0, axis=1) & np.all(np.isfinite(self['xe'][select_stars, :][:, epoch_cols]), axis=1)
- valid_ye = np.all(self['ye'][select_stars, :][:, epoch_cols]!=0, axis=1) & np.all(np.isfinite(self['ye'][select_stars, :][:, epoch_cols]), axis=1)
-
- if mask_val:
- x = np.ma.masked_values(self['x'][select_stars, :][:, epoch_cols], mask_val)
- y = np.ma.masked_values(self['y'][select_stars, :][:, epoch_cols], mask_val)
-
- # If no mask, convert x.mask to list
- if not np.ma.is_masked(x):
- x.mask = np.zeros_like(self['x'][select_stars, :][:, epoch_cols].data, dtype=bool)
- if not np.ma.is_masked(y):
- y.mask = np.zeros_like(self['y'][select_stars, :][:, epoch_cols].data, dtype=bool)
-
- valid_x = ~np.any(x.mask, axis=1)
- valid_y = ~np.any(y.mask, axis=1)
- detected_in_all_epochs = np.logical_and.reduce((
- valid_x, valid_y, valid_xe, valid_ye))
- else:
- detected_in_all_epochs = np.logical_and(valid_xe, valid_ye)
-
- N = len(self['x'][select_stars, :])
- fit_params = motion_model_to_fit.fitter_param_names
- param_data = {p: np.zeros(N) for p in fit_params}
- param_data.update({p+'_err': np.zeros(N) for p in fit_params})
- param_data.update({p: np.zeros(N) for p in motion_model_to_fit.fixed_param_names})
- param_data['chi2_x'] = np.zeros(N)
- param_data['chi2_y'] = np.zeros(N)
-
- if times is None:
- if 'YEARS' in self.meta:
- times = np.array(self.meta['YEARS'])[epoch_cols]
- elif 't' in self.colnames:
- times = self['t'][0, epoch_cols]
- else:
- raise ValueError("No valid time column found.")
-
- if not art_star:
- x_arr = self['x'][select_stars, :][:, epoch_cols]
- y_arr = self['y'][select_stars, :][:, epoch_cols]
- else:
- x_arr = self['x'][select_stars, :][:, epoch_cols, 1]
- y_arr = self['y'][select_stars, :][:, epoch_cols, 1]
-
- xe_arr = self['xe'][select_stars, :][:, epoch_cols]
- ye_arr = self['ye'][select_stars, :][:, epoch_cols]
-
- # Only fit for >1 epochs, otherwise all velocities will be 0
- if len(epoch_cols) > 1:
- # For each star
- for i in tqdm(range(N)):
- x = x_arr[i]
- y = y_arr[i]
- xe = xe_arr[i]
- ye = ye_arr[i]
- t0 = np.average(times, weights=1. / np.hypot(xe, ye))
-
- # Run fit and record results
- params, param_errs = motion_model_to_fit.fit_motion_model(
- times, x, y, xe, ye, t0, weighting=weighting,
- use_scipy=use_scipy, absolute_sigma=absolute_sigma
- )
- if 't0' in motion_model_to_fit.fixed_param_names:
- param_data['t0'][i] = t0
- for j, param in enumerate(fit_params):
- param_data[param][i] = params[j]
- param_data[f'{param}_err'][i] = param_errs[j]
- chi2x, chi2y = motion_model_to_fit.get_chi2(params, [t0], times, x, y, xe, ye)
- param_data['chi2_x'][i] = chi2x
- param_data['chi2_y'][i] = chi2y
-
- vel_result = Table.from_pandas(pd.DataFrame(param_data))
-
- # Add n_vfit
- n_fit = len(epoch_cols)
- vel_result['n_fit'] = n_fit
-
- # Clean/remove up old arrays.
- columns = [*vel_result.keys(), 'n_fit']
- for column in columns:
- if column in self.colnames: self.remove_column(column)
-
- # Update self
- for column in columns:
- column_array = MaskedColumn(np.ma.zeros(N_stars), dtype=float, name=column)
- column_array[select_stars] = vel_result[column]
- column_array[select_stars][~detected_in_all_epochs] = np.nan
- column_array.mask[select_stars] = ~detected_in_all_epochs
- # Mask unselected indices
- column_array.mask[~np.isin(np.arange(N_stars), select_stars)] = True
- self[column] = column_array
-
- if return_result:
- return vel_result
- else:
- return
def shift_reference_frame(self, delta_vx=0.0, delta_vy=0.0, delta_pi=0.0,
motion_model_dict={}):
diff --git a/flystar/tests/test_align.ipynb b/flystar/tests/test_align.ipynb
deleted file mode 100644
index 02442b9..0000000
--- a/flystar/tests/test_align.ipynb
+++ /dev/null
@@ -1,366 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Notebook for Running Align Tests"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {},
- "outputs": [],
- "source": [
- "from flystar.tests import test_align\n",
- "from flystar import starlists\n",
- "from astropy.table import Table"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Test: make_fake_starlists_poly1_vel\n",
- "\n",
- "Just make sure the tables look sensible and are in the right units."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " name m0 m0e ... vye t0 \n",
- "-------- ----------------- -------------------- ... ------------------- ------\n",
- "star_155 9.106905292995506 0.054167528156861204 ... 0.1564397531527286 2019.5\n",
- "star_113 9.153031462110043 0.0421090989942197 ... 0.08128628950126615 2019.5\n",
- "star_077 9.16547870263162 0.02021147759307802 ... 0.05907352582911862 2019.5\n",
- "star_069 9.169817788300977 0.027788213230369625 ... 0.04965351499764548 2019.5\n",
- "star_037 9.173200786855755 0.007665400875860144 ... 0.22723357600795704 2019.5\n",
- " name m me ... ye t \n",
- "-------- ----------------- -------------------- ... -------------------- ------\n",
- "star_155 9.198437965086988 0.054167528156861204 ... 0.02649499466969545 2018.5\n",
- "star_113 9.257333243243941 0.0421090989942197 ... 0.02606700846524875 2018.5\n",
- "star_077 9.252158908537464 0.02021147759307802 ... 0.04250920654497108 2018.5\n",
- "star_069 9.267901667333167 0.027788213230369625 ... 0.042689240225924296 2018.5\n",
- "star_037 9.276780126418494 0.007665400875860144 ... 0.03592203011554212 2018.5\n",
- " name m me ... ye t \n",
- "-------- ----------------- -------------------- ... -------------------- ------\n",
- "star_155 9.478887659623185 0.054167528156861204 ... 0.02649499466969545 2019.5\n",
- "star_113 9.569878576042546 0.0421090989942197 ... 0.02606700846524875 2019.5\n",
- "star_077 9.575998150724095 0.02021147759307802 ... 0.04250920654497108 2019.5\n",
- "star_069 9.593581807234129 0.027788213230369625 ... 0.042689240225924296 2019.5\n",
- "star_037 9.553127108740597 0.007665400875860144 ... 0.03592203011554212 2019.5\n",
- "['name', 'm0', 'm0e', 'x0', 'x0e', 'y0', 'y0e', 'vx', 'vxe', 'vy', 'vye', 't0']\n",
- "['name', 'm', 'me', 'x', 'xe', 'y', 'ye', 't']\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/Users/jlu/code/python/flystar/flystar/starlists.py:386: UserWarning: The StarList class requires a arguments('name', 'x', 'y', 'm')\n",
- " warnings.warn(err_msg, UserWarning)\n"
- ]
- }
- ],
- "source": [
- "test_align.make_fake_starlists_poly1_vel()\n",
- "\n",
- "ref = Table.read('random_vel_ref.fits')\n",
- "lis0 = Table.read('random_vel_0.fits')\n",
- "lis1 = Table.read('random_vel_1.fits')\n",
- "\n",
- "print(ref[0:5])\n",
- "print(lis0[0:5])\n",
- "print(lis1[0:5])\n",
- "\n",
- "print(ref.colnames)\n",
- "print(lis0.colnames)\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## test_align_vel\n",
- "\n",
- "Make sure it runs, make some plots along the way, etc."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/Users/jlu/code/python/flystar/flystar/starlists.py:386: UserWarning: The StarList class requires a arguments('name', 'x', 'y', 'm')\n",
- " warnings.warn(err_msg, UserWarning)\n",
- "/Users/jlu/code/python/flystar/flystar/starlists.py:386: UserWarning: The StarList class requires a arguments('name', 'x', 'y', 'm')\n",
- " warnings.warn(err_msg, UserWarning)\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " \n",
- "**********\n",
- "**********\n",
- "Starting iter 0 with ref_table shape: (200, 1)\n",
- "**********\n",
- "**********\n",
- " \n",
- " **********\n",
- " Matching catalog 1 / 4 in iteration 0 with 200 stars\n",
- " **********\n",
- "initial_guess: 50 stars matched between starlist and reference list\n",
- "initial_guess: [-6.05144456e+00 1.01098279e+00 -2.50608887e-04] [-1.07161761e+01 4.89226304e-05 1.01096529e+00]\n",
- " Found 0 duplicates out of 196 matches\n",
- "In Loop 0 found 196 matches\n",
- " Found 0 duplicates out of 196 matches\n",
- " \n",
- " **********\n",
- " Matching catalog 2 / 4 in iteration 0 with 200 stars\n",
- " **********\n",
- "initial_guess: 49 stars matched between starlist and reference list\n",
- "initial_guess: [-1.02158015e+02 1.02080743e+00 -1.45081519e-04] [-5.07779471e+01 -2.60729494e-05 9.99423500e-01]\n",
- " Found 0 duplicates out of 200 matches\n",
- "In Loop 0 found 200 matches\n",
- " Found 0 duplicates out of 200 matches\n",
- " \n",
- " **********\n",
- " Matching catalog 3 / 4 in iteration 0 with 200 stars\n",
- " **********\n",
- "initial_guess: 50 stars matched between starlist and reference list\n",
- "initial_guess: [-2.14220566e-10 1.00000000e+00 -2.24089697e-16] [2.50622339e-10 0.00000000e+00 1.00000000e+00]\n",
- " Found 0 duplicates out of 200 matches\n",
- "In Loop 0 found 200 matches\n",
- " Found 0 duplicates out of 200 matches\n",
- " \n",
- " **********\n",
- " Matching catalog 4 / 4 in iteration 0 with 200 stars\n",
- " **********\n",
- "initial_guess: 50 stars matched between starlist and reference list\n",
- "initial_guess: [-2.57803428e+02 1.03052409e+00 -5.28390832e-05] [ 2.49886631e+02 -6.00884405e-05 9.98642952e-01]\n",
- " Found 0 duplicates out of 200 matches\n",
- "In Loop 0 found 200 matches\n",
- " Found 0 duplicates out of 200 matches\n",
- " \n",
- "**********\n",
- "**********\n",
- "Starting iter 1 with ref_table shape: (204, 4)\n",
- "**********\n",
- "**********\n",
- " \n",
- " **********\n",
- " Matching catalog 1 / 4 in iteration 1 with 200 stars\n",
- " **********\n",
- " Found 0 duplicates out of 199 matches\n",
- "In Loop 1 found 199 matches\n",
- " Found 0 duplicates out of 199 matches\n",
- " \n",
- " **********\n",
- " Matching catalog 2 / 4 in iteration 1 with 200 stars\n",
- " **********\n",
- " Found 0 duplicates out of 198 matches\n",
- "In Loop 1 found 198 matches\n",
- " Found 0 duplicates out of 199 matches\n",
- " \n",
- " **********\n",
- " Matching catalog 3 / 4 in iteration 1 with 200 stars\n",
- " **********\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/Users/jlu/code/python/flystar/flystar/starlists.py:386: UserWarning: The StarList class requires a arguments('name', 'x', 'y', 'm')\n",
- " warnings.warn(err_msg, UserWarning)\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " Found 0 duplicates out of 200 matches\n",
- "In Loop 1 found 200 matches\n",
- " Found 0 duplicates out of 200 matches\n",
- " \n",
- " **********\n",
- " Matching catalog 4 / 4 in iteration 1 with 200 stars\n",
- " **********\n",
- " Found 0 duplicates out of 200 matches\n",
- "In Loop 1 found 200 matches\n",
- " Found 0 duplicates out of 200 matches\n",
- "**********\n",
- "Final Matching\n",
- "**********\n",
- " Found 0 duplicates out of 199 matches\n",
- "Matched 199 out of 200 stars in list 0\n",
- " Found 0 duplicates out of 199 matches\n",
- "Matched 199 out of 200 stars in list 1\n",
- " Found 0 duplicates out of 200 matches\n",
- "Matched 200 out of 200 stars in list 2\n",
- " Found 0 duplicates out of 199 matches\n",
- "Matched 199 out of 200 stars in list 3\n",
- "\n",
- " Preparing the reference table...\n"
- ]
- }
- ],
- "source": [
- "test_align.test_mosaic_lists_vel()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "> /Users/jlu/code/python/flystar/flystar/align.py(3244)apply_mag_lim()\n",
- "-> star_list_T.restrict_by_value(**conditions)\n"
- ]
- },
- {
- "name": "stdin",
- "output_type": "stream",
- "text": [
- "(Pdb) conditions\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{'m0_min': None, 'm0_max': None}\n"
- ]
- },
- {
- "name": "stdin",
- "output_type": "stream",
- "text": [
- "(Pdb) type(star_list_T)\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n"
- ]
- },
- {
- "name": "stdin",
- "output_type": "stream",
- "text": [
- "(Pdb) type(ref_list)\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "*** NameError: name 'ref_list' is not defined\n"
- ]
- },
- {
- "name": "stdin",
- "output_type": "stream",
- "text": [
- "(Pdb) ref_list\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "*** NameError: name 'ref_list' is not defined\n"
- ]
- },
- {
- "name": "stdin",
- "output_type": "stream",
- "text": [
- "(Pdb) u\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "> /Users/jlu/code/python/flystar/flystar/align.py(991)mosaic_lists()\n",
- "-> ref_list_T = apply_mag_lim(ref_list, mag_lim[ref_index])\n"
- ]
- },
- {
- "name": "stdin",
- "output_type": "stream",
- "text": [
- "(Pdb) type(ref_list)\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n"
- ]
- },
- {
- "name": "stdin",
- "output_type": "stream",
- "text": [
- "(Pdb) q\n"
- ]
- }
- ],
- "source": [
- "import pdb\n",
- "pdb.pm()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "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.6.7"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/flystar/tests/test_align.py b/flystar/tests/test_align.py
index 2d6b0dc..3937ea6 100644
--- a/flystar/tests/test_align.py
+++ b/flystar/tests/test_align.py
@@ -6,10 +6,8 @@
from flystar import motion_model
from astropy.table import Table
import numpy as np
-import pylab as plt
+import matplotlib.pyplot as plt
import pdb
-import datetime
-import pytest
def test_MosaicSelfRef():
"""
@@ -28,7 +26,7 @@ def test_MosaicSelfRef():
trans_args={'order': 2})
msc.fit()
-
+
# Check some of the output quantities on the final table.
assert 'x0' in msc.ref_table.colnames
assert 'x0_err' in msc.ref_table.colnames
@@ -42,7 +40,6 @@ def test_MosaicSelfRef():
assert msc.ref_table['use_in_trans'].shape == msc.ref_table['x0'].shape
assert msc.ref_table['used_in_trans'].shape == msc.ref_table['x'].shape
-
# Check that we have some matched stars... should be at least 35 stars
# that are detected in all 4 starlists.
@@ -50,11 +47,11 @@ def test_MosaicSelfRef():
assert len(idx) > 35
# Check that the transformation error isn't too big
- assert (msc.ref_table['x0_err'] < 3.0).all() # less than 1 pix
- assert (msc.ref_table['y0_err'] < 3.0).all()
- #assert (msc.ref_table['m0_err'] < 1.0).all() # less than 0.5 mag
- assert (msc.ref_table['m0_err'] < 1.5).all() # less than 0.5 mag
-
+ valid_err = np.isfinite(msc.ref_table['x0_err']) & np.isfinite(msc.ref_table['y0_err']) & np.isfinite(msc.ref_table['m0_err'])
+ assert (msc.ref_table['x0_err'][valid_err] < 3.0).all() # less than 1 pix
+ assert (msc.ref_table['y0_err'][valid_err] < 3.0).all()
+ #assert (msc.ref_table['m0_err'][valid_err] < 1.0).all() # less than 0.5 mag
+ assert (msc.ref_table['m0_err'][valid_err] < 1.5).all() # less than 0.5 mag
# Check that the transformation lists aren't too wacky
for ii in range(4):
np.testing.assert_allclose(msc.trans_list[ii].px.c1_0, 1.0, rtol=1e-2)
@@ -81,7 +78,7 @@ def test_MosaicSelfRef():
plt.plot(msc.ref_table['x0'],
msc.ref_table['y0'],
'.', color='black', alpha=0.2)
-
+
return
@@ -102,11 +99,11 @@ def test_MosaicSelfRef_vel_tconst():
dr_tol=[3, 3], dm_tol=[1, 1],
trans_class=transforms.PolyTransform,
trans_args={'order': 2},
- default_motion_model='Linear',
+ motion_models=['Empty', 'Fixed', 'Linear'],
verbose=False)
msc.fit()
-
+
# Check some of the output quantities on the final table.
assert 'x0' in msc.ref_table.colnames
assert 'x0_err' in msc.ref_table.colnames
@@ -126,21 +123,16 @@ def test_MosaicSelfRef_vel_tconst():
assert len(idx) > 35
# Check that the transformation error isn't too big
- assert (msc.ref_table['x0_err'] < 3.0).all() # less than 1 pix
- assert (msc.ref_table['y0_err'] < 3.0).all()
- assert (msc.ref_table['m0_err'] < 1.0).all() # less than 0.5 mag
-
+ valid_err = np.isfinite(msc.ref_table['x0_err']) & np.isfinite(msc.ref_table['y0_err']) & np.isfinite(msc.ref_table['m0_err'])
+ assert (msc.ref_table['x0_err'][valid_err] < 3.0).all() # less than 1 pix
+ assert (msc.ref_table['y0_err'][valid_err] < 3.0).all()
+ assert (msc.ref_table['m0_err'][valid_err] < 1.0).all() # less than 0.5 mag
+
# Check that the transformation lists aren't too wacky
for ii in range(4):
np.testing.assert_allclose(msc.trans_list[ii].px.c1_0, 1.0, rtol=1e-2)
np.testing.assert_allclose(msc.trans_list[ii].py.c0_1, 1.0, rtol=1e-2)
- # Check that the velocities aren't crazy...
- # they should be non-existent (since there is no time difference)
- assert np.isnan(msc.ref_table['vx']).all()
- assert np.isnan(msc.ref_table['vy']).all()
- assert np.isnan(msc.ref_table['vx_err']).all()
- assert np.isnan(msc.ref_table['vy_err']).all()
return
@@ -172,7 +164,7 @@ def test_MosaicSelfRef_vel():
msc = align.MosaicSelfRef(lists, ref_index=0, iters=3,
dr_tol=[5, 3, 3], dm_tol=[1, 1, 0.5], outlier_tol=None,
trans_class=transforms.PolyTransform,
- trans_args={'order': 2}, default_motion_model='Linear',
+ trans_args={'order': 2}, motion_models=['Empty', 'Fixed', 'Linear'],
verbose=False)
msc.fit()
@@ -196,10 +188,11 @@ def test_MosaicSelfRef_vel():
assert len(idx) > 35
# Check that the transformation error isn't too big
- assert (msc.ref_table['x0_err'] < 3.0).all() # less than 1 pix
- assert (msc.ref_table['y0_err'] < 3.0).all()
- assert (msc.ref_table['m0_err'] < 1.0).all() # less than 0.5 mag
-
+ valid_err = np.isfinite(msc.ref_table['x0_err']) & np.isfinite(msc.ref_table['y0_err']) & np.isfinite(msc.ref_table['m0_err'])
+ assert (msc.ref_table['x0_err'][valid_err] < 3.0).all() # less than 1 pix
+ assert (msc.ref_table['y0_err'][valid_err] < 3.0).all()
+ assert (msc.ref_table['m0_err'][valid_err] < 1.0).all() # less than 0.5 mag
+
# Check that the transformation lists aren't too wacky
for ii in range(4):
np.testing.assert_allclose(msc.trans_list[ii].px.c1_0, 1.0, rtol=1e-2)
@@ -214,7 +207,7 @@ def test_MosaicSelfRef_vel():
def test_MosaicToRef():
make_fake_starlists_poly1(seed=42)
-
+
ref_file = 'random_ref.fits'
list_files = ['random_0.fits',
'random_1.fits',
@@ -235,7 +228,7 @@ def test_MosaicToRef():
msc = align.MosaicToRef(ref_list, lists, iters=2,
dr_tol=[0.2, 0.1], dm_tol=[1, 0.5],
trans_class=transforms.PolyTransform,
- trans_args={'order': 2}, default_motion_model='Fixed',
+ trans_args={'order': 2}, motion_models=['Empty', 'Fixed'],
update_ref_orig=False, verbose=False)
msc.fit()
@@ -266,12 +259,12 @@ def test_MosaicToRef():
# Also double check that they aren't exactly the same for the reference stars.
assert np.not_equal(msc.ref_table['x0'], ref_list['x0']).all()
assert np.not_equal(msc.ref_table['y0'], ref_list['y0']).all()
-
+
return msc
def test_MosaicToRef_p0_vel():
make_fake_starlists_poly0_vel(seed=42)
-
+
ref_file = 'random_vel_ref.fits'
list_files = ['random_vel_p0_0.fits',
'random_vel_p0_1.fits',
@@ -293,14 +286,14 @@ def test_MosaicToRef_p0_vel():
# Switch our list to a "increasing to the West" list.
ref_list['x0'] *= -1.0
ref_list['vx'] *= -1.0
-
+
lists = [starlists.StarList.read(lf) for lf in list_files]
msc = align.MosaicToRef(ref_list, lists, iters=2,
dr_tol=[0.2, 0.1], dm_tol=[1, 0.5],
outlier_tol=[None, None],
trans_class=transforms.PolyTransform,
- trans_args={'order': 1}, default_motion_model='Linear',
+ trans_args={'order': 1}, motion_models=['Empty', 'Fixed', 'Linear'],
update_ref_orig=False, verbose=False)
msc.fit()
@@ -326,18 +319,18 @@ def test_MosaicToRef_p0_vel():
# The velocities should be almost the same (but not as close as before)
# as the input velocities since update_ref == True.
assert (msc.ref_table['name']==ref_list['name']).all()
- assert np.max(np.abs(msc.ref_table['vx']-ref_list['vx']))<3e-4
- assert np.max(np.abs(msc.ref_table['vy']-ref_list['vy']))<3e-4
+ np.testing.assert_allclose(msc.ref_table['vx'], ref_list['vx'], rtol=1e-1, atol=3e-4)
+ np.testing.assert_allclose(msc.ref_table['vy'], ref_list['vy'], rtol=1e-1, atol=3e-4)
# Also double check that they aren't exactly the same for the reference stars.
#assert np.any(np.not_equal(msc.ref_table['vx'], ref_list['vx']))
assert np.not_equal(msc.ref_table['vx'], ref_list['vx']).any()
-
+
return msc
def test_MosaicToRef_vel():
make_fake_starlists_poly1_vel(seed=42)
-
+
ref_file = 'random_vel_ref.fits'
list_files = ['random_vel_0.fits',
'random_vel_1.fits',
@@ -359,14 +352,14 @@ def test_MosaicToRef_vel():
# Switch our list to a "increasing to the West" list.
ref_list['x0'] *= -1.0
ref_list['vx'] *= -1.0
-
+
lists = [starlists.StarList.read(lf) for lf in list_files]
msc = align.MosaicToRef(ref_list, lists, iters=2,
dr_tol=[0.2, 0.1], dm_tol=[1, 0.5],
outlier_tol=[None, None],
trans_class=transforms.PolyTransform,
- trans_args={'order': 1}, default_motion_model='Linear',
+ trans_args={'order': 1}, motion_models=['Empty', 'Fixed', 'Linear'],
update_ref_orig=False, verbose=False)
msc.fit()
@@ -398,12 +391,12 @@ def test_MosaicToRef_vel():
# Also double check that they aren't exactly the same for the reference stars.
#assert np.any(np.not_equal(msc.ref_table['vx'], ref_list['vx']))
assert np.not_equal(msc.ref_table['vx'], ref_list['vx']).any()
-
+
return msc
def test_MosaicToRef_acc():
make_fake_starlists_poly1_acc(seed=42)
-
+
ref_file = 'random_acc_ref.fits'
list_files = ['random_acc_0.fits',
'random_acc_1.fits',
@@ -417,29 +410,29 @@ def test_MosaicToRef_acc():
ref_list = Table.read(ref_file)
# Convert velocities to arcsec/yr
- ref_list['vx0'] *= 1e-3
- ref_list['vy0'] *= 1e-3
- ref_list['vx0_err'] *= 1e-3
- ref_list['vy0_err'] *= 1e-3
+ ref_list['vx'] *= 1e-3
+ ref_list['vy'] *= 1e-3
+ ref_list['vx_err'] *= 1e-3
+ ref_list['vy_err'] *= 1e-3
# Convert accelerations to arcsec/yr**2
ref_list['ax'] *= 1e-3
ref_list['ay'] *= 1e-3
ref_list['ax_err'] *= 1e-3
ref_list['ay_err'] *= 1e-3
-
+
# Switch our list to a "increasing to the West" list.
ref_list['x0'] *= -1.0
- ref_list['vx0'] *= -1.0
+ ref_list['vx'] *= -1.0
ref_list['ax'] *= -1.0
-
+
lists = [starlists.StarList.read(lf) for lf in list_files]
msc = align.MosaicToRef(ref_list, lists, iters=2,
dr_tol=[0.4, 0.2], dm_tol=[1, 0.5],
trans_class=transforms.PolyTransform,
trans_args={'order': 2},
- default_motion_model='Acceleration',
+ motion_models=['Acceleration'],
update_ref_orig=False, verbose=False)
msc.fit()
@@ -476,336 +469,511 @@ def test_MosaicToRef_acc():
if ~np.isnan(msc.ref_table['ax'][ix_fit]):
i_orig.append(i)
i_fit.append(ix_fit)
- np.testing.assert_allclose(msc.ref_table['ax'][i_fit], ref_list['ax'][i_orig], rtol=1e-1, atol=3e-4)
- np.testing.assert_allclose(msc.ref_table['ay'][i_fit], ref_list['ay'][i_orig], rtol=1e-1, atol=3e-4)
-
- # Also double check that they aren't exactly the same for the reference stars.
- assert np.any(np.not_equal(msc.ref_table['ax'][:200], ref_list['ax'][:200]))
+ # Accelerations all too small, rtol doesn't work well here.
+ atol = 3e-4
+ np.testing.assert_allclose(msc.ref_table['ax'][i_fit], ref_list['ax'][i_orig], atol=atol)
+ np.testing.assert_allclose(msc.ref_table['ay'][i_fit], ref_list['ay'][i_orig], atol=atol)
+
+ ax_min = np.min(ref_list['ax'][i_orig])
+ ax_max = np.max(ref_list['ax'][i_orig])
+ ay_min = np.min(ref_list['ay'][i_orig])
+ ay_max = np.max(ref_list['ay'][i_orig])
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
+ ax1.plot(ref_list['ax'][i_orig], msc.ref_table['ax'][i_fit], '.')
+ ax1.plot([ax_min, ax_max], [ax_min, ax_max], color='C3')
+ ax1.plot([ax_min, ax_max], [ax_min - atol, ax_max - atol], ls='--', color='C3')
+ ax1.plot([ax_min, ax_max], [ax_min + atol, ax_max + atol], ls='--', color='C3')
+ ax1.set_xlabel('Input ax')
+ ax1.set_ylabel('Ref Table ax')
+ ax1.set_title('Acceleration in X')
- return msc
-
+ ax2.plot(ref_list['ay'][i_orig], msc.ref_table['ay'][i_fit], '.')
+ ax2.plot([ay_min, ay_max], [ay_min, ay_max], color='C3')
+ ax2.plot([ay_min, ay_max], [ay_min - atol, ay_max - atol], ls='--', color='C3')
+ ax2.plot([ay_min, ay_max], [ay_min + atol, ay_max + atol], ls='--', color='C3')
+ ax2.set_xlabel('Input ay')
+ ax2.set_ylabel('Ref Table ay')
+ ax2.set_title('Acceleration in Y')
+ plt.tight_layout()
+ plt.show()
-def make_fake_starlists_shifts():
- N_stars = 200
- x = np.random.rand(N_stars) * 1000
- y = np.random.rand(N_stars) * 1000
- m = (np.random.rand(N_stars) * 8) + 9
-
- sdx = np.argsort(m)
- x = x[sdx]
- y = y[sdx]
- m = m[sdx]
-
- name = ['star_{0:03d}'.format(ii) for ii in range(N_stars)]
+ # Also double check that they aren't exactly the same for the reference stars.
+ assert np.any(np.not_equal(msc.ref_table['ax'][i_fit], ref_list['ax'][i_orig]))
- # Save original positions as reference (1st) list.
- fmt = '{0:10s} {1:5.2f} 2015.0 {2:9.4f} {3:9.4f} 0 0 0 0\n'
- _out = open('random_0.lis', 'w')
- for ii in range(N_stars):
- _out.write(fmt.format(name[ii], m[ii], x[ii], y[ii]))
- _out.close()
+ return msc
+def test_MosaicToRef_hst_me():
+ """
+ Test Casey's issue with 'me' not getting propogated
+ from the input starlists to the output table.
- ##########
- # Shifts
- ##########
- # Make 4 new starlists with different shifts.
- shifts = [[ 6.5, 10.1],
- [100.3, 50.5],
- [-30.0,-100.7],
- [250.0,-250.0]]
+ Use data from MB10-364 microlensing target for the test.
+ """
+ # Target RA and Dec (MOA data download)
+ # ra = '17:57:05.401'
+ # dec = '-34:27:05.01'
- for ss in range(len(shifts)):
- xnew = x - shifts[ss][0]
- ynew = y - shifts[ss][1]
+ # Load up a Gaia catalog (queried around the RA/Dec above)
+ my_gaia = Table.read('mb10364_data/my_gaia.fits')
+ my_gaia['me'] = 0.01
- # Perturb with small errors (0.1 pix)
- xnew += np.random.randn(N_stars) * 0.1
- ynew += np.random.randn(N_stars) * 0.1
+ # Gather the list of starlists. For first pass, don't modify the starlists.
+ # Loop through the observations and read them in, in prep for alignment with Gaia
+ epochs = [2011.83, 2012.73, 2013.81]
+ starlist_names = ['mb10364_data/2011_10_31_F606W_MATCHUP_XYMEEE_final.calib',
+ 'mb10364_data/2012_09_25_F606W_MATCHUP_XYMEEE_final.calib',
+ 'mb10364_data/2013_10_24_F606W_MATCHUP_XYMEEE_final.calib']
- mnew = m + np.random.randn(N_stars) * 0.05
+ list_of_starlists = []
- _out = open('random_shift_{0:d}.lis'.format(ss+1), 'w')
- for ii in range(N_stars):
- _out.write(fmt.format(name[ii], mnew[ii], xnew[ii], ynew[ii]))
- _out.close()
+ # Just using the F606W filters first.
+ for ee in range(len(starlist_names)):
+ lis = starlists.StarList.from_lis_file(starlist_names[ee])
- return shifts
+ # # Add additive error term. MAYBE YOU DON'T NEED THIS
+ # lis['xe'] = np.hypot(lis['xe'], 0.01) # Adding 0.01 pix (0.1 mas) in quadrature.
+ # lis['ye'] = np.hypot(lis['ye'], 0.01)
-def make_fake_starlists_poly1(seed=-1):
- # If seed >=0, then set random seed to that value
- if seed >= 0:
- np.random.seed(seed=seed)
-
- N_stars = 200
+ lis['t'] = epochs[ee]
- x0 = np.random.rand(N_stars) * 10.0 # arcsec (increasing to East)
- y0 = np.random.rand(N_stars) * 10.0 # arcsec
- x0e = np.random.randn(N_stars) * 5.0e-4 # arcsec
- y0e = np.random.randn(N_stars) * 5.0e-4 # arcsec
- m0 = (np.random.rand(N_stars) * 8) + 9 # mag
- m0e = np.random.randn(N_stars) * 0.05 # mag
- t0 = np.ones(N_stars) * 2019.5
+ # Lets dump the faint stars.
+ idx = np.where(lis['m'] < 20.0)[0]
+ lis = lis[idx]
- # Make all the errors positive
- x0e = np.abs(x0e)
- y0e = np.abs(y0e)
- m0e = np.abs(m0e)
-
- name = ['star_{0:03d}'.format(ii) for ii in range(N_stars)]
+ list_of_starlists.append(lis)
- # Make an StarList
- lis = starlists.StarList([name, m0, m0e, x0, x0e, y0, y0e, t0],
- names = ('name', 'm0', 'm0_err', 'x0', 'x0_err', 'y0', 'y0_err', 't0'))
-
- sdx = np.argsort(m0)
- lis = lis[sdx]
+ msc = align.MosaicToRef(my_gaia, list_of_starlists, iters=1,
+ dr_tol=[0.1], dm_tol=[5],
+ outlier_tol=[None], mag_lim=[13, 21],
+ trans_class=transforms.PolyTransform,
+ trans_args=[{'order': 1}],
+ motion_models=['Empty', 'Fixed'],
+ use_ref_new=False,
+ update_ref_orig=False,
+ mag_trans=False,
+ trans_weighting='both,std',
+ init_guess_mode='miracle', verbose=False)
+ msc.fit()
- # Save original positions as reference (1st) list
- # in a StarList format (with velocities).
- lis.write('random_ref.fits', overwrite=True)
+ assert 'me' in msc.ref_table.colnames
+ return
- ##########
- # Shifts
- ##########
- # Make 4 new starlists with different shifts.
- times = [2018.5, 2019.0, 2019.5, 2020.0, 2020.5, 2021.0, 2021.5, 2022.0]
- xy_trans = [[[ 6.5, 0.99, 1e-5], [ 10.1, 1e-5, 0.99]],
- [[100.3, 0.98, 1e-5], [ 50.5, 9e-6, 1.001]],
- [[ 0.0, 1.00, 0.0], [ 0.0, 0.0, 1.0]],
- [[250.0, 0.97, 2e-5], [-250.0, 1e-5, 1.001]],
- [[ 50.0, 1.01, 1e-5], [ -31.0, 1e-5, 1.000]],
- [[ 78.0, 0.98, 0.0 ], [ 45.0, 9e-6, 1.001]],
- [[-13.0, 0.99, 1e-5], [ 150, 2e-5, 1.002]],
- [[ 94.0, 1.00, 9e-6], [-182.0, 0.0, 0.99]]]
- mag_trans = [0.1, 0.4, 0.0, -0.3, 0.2, 0.0, -0.1, -0.3]
-
- # Convert into pixels (undistorted) with the following info.
- scale = 0.01 # arcsec / pix
- shift = [1.0, 1.0] # pix
+def test_bootstrap():
+ """
+ Test to make sure calc_bootstrap_error() call is working
+ properly (e.g., only called when user calls calc_bootstrap_error,
+ n_boot param for calc_bootstrap_error only, boot_epochs_min working,
+ etc.)
+ """
+ # Read in starlists for MosaicToRef
+ ref = Table.read('ref_vel.lis', format='ascii')
+ list1 = Table.read('E.lis', format='ascii')
+ list2 = Table.read('F.lis', format='ascii')
- for ss in range(len(times)):
- dt = times[ss] - lis['t0']
-
- x = lis['x0']
- y = lis['y0']
- t = np.ones(N_stars) * times[ss]
+ list1 = starlists.StarList.from_table(list1)
+ list2 = starlists.StarList.from_table(list2)
- # Convert into pixels
- xp = (x / -scale) + shift[0] # -1 from switching to increasing to West (right)
- yp = (y / scale) + shift[1]
- xpe = lis['x0_err'] / scale
- ype = lis['y0_err'] / scale
+ # Set parameters for alignment
+ transModel = transforms.PolyTransform
+ trans_args = {'order':2}
+ N_loop = 1
+ dr_tol = 0.08
+ dm_tol = 99
+ outlier_tol = None
+ mag_lim = None
+ ref_mag_lim = None
+ trans_weighting = 'both,var'
+ mag_trans = False
- # Distort the positions
- trans = transforms.PolyTransform(1, xy_trans[ss][0], xy_trans[ss][1], mag_offset=mag_trans[ss])
- xd, yd = trans.evaluate(xp, yp)
- md = trans.evaluate_mag(lis['m0'])
+ n_boot = 15
+ boot_epochs_min=-1
- # Perturb with small errors (0.1 pix)
- xd += np.random.randn(N_stars) * 0.1
- yd += np.random.randn(N_stars) * 0.1
- md += np.random.randn(N_stars) * 0.02
- xde = xpe
- yde = ype
- mde = lis['m0_err']
+ # Run FLYSTAR, no bootstraps yet!
+ match1 = align.MosaicToRef(ref, [list1, list2], iters=N_loop, dr_tol=dr_tol,
+ dm_tol=dm_tol, outlier_tol=outlier_tol,
+ trans_class=transModel,
+ trans_args=trans_args,
+ mag_trans=mag_trans,
+ mag_lim=mag_lim,
+ ref_mag_lim=ref_mag_lim,
+ trans_weighting=trans_weighting,
+ motion_models=['Linear'],
+ use_ref_new=False,
+ update_ref_orig=False,
+ init_guess_mode='name',
+ verbose=False)
+ match1.fit()
- # Save the new list as a starlist.
- new_lis = starlists.StarList([lis['name'], md, mde, xd, xde, yd, yde, t],
- names=('name', 'm', 'me', 'x', 'xe', 'y', 'ye', 't'))
+ # Make sure no bootstrap columns exist
+ assert 'xe_boot' not in match1.ref_table.keys()
+ assert 'ye_boot' not in match1.ref_table.keys()
+ assert 'vxe_boot' not in match1.ref_table.keys()
+ assert 'vye_boot' not in match1.ref_table.keys()
- new_lis.write('random_{0:d}.fits'.format(ss), overwrite=True)
+ # Run bootstrap: no boot_epochs_min
+ match1.calc_bootstrap_errors(n_boot=n_boot, boot_epochs_min=boot_epochs_min)
+ # Make sure columns exist, and none of them are nan values
+ assert np.sum(np.isnan(match1.ref_table['xe_boot'])) == 0
+ assert np.sum(np.isnan(match1.ref_table['ye_boot'])) == 0
+ assert np.sum(np.isnan(match1.ref_table['vx_err_boot'])) == 0
+ assert np.sum(np.isnan(match1.ref_table['vy_err_boot'])) == 0
- return (xy_trans,mag_trans)
+ # Test 2: make sure boot_epochs_min is working
+ # Eliminate some rows to list2, so some stars are only in 1 epoch.
+ # Rerun align. Some stars should only be detected in 1 epoch
+ list3 = list2[0:60]
-def make_fake_starlists_poly0_vel(seed=-1):
- # If seed >=0, then set random seed to that value
- if seed >= 0:
- np.random.seed(seed=seed)
-
- N_stars = 200
+ match2 = align.MosaicToRef(ref, [list1, list3], iters=N_loop, dr_tol=dr_tol,
+ dm_tol=dm_tol, outlier_tol=outlier_tol,
+ trans_class=transModel,
+ trans_args=trans_args,
+ mag_trans=mag_trans,
+ mag_lim=mag_lim,
+ ref_mag_lim=ref_mag_lim,
+ trans_weighting=trans_weighting,
+ motion_models=['Linear'],
+ use_ref_new=False,
+ update_ref_orig=False,
+ init_guess_mode='name',
+ verbose=False)
+ match2.fit()
- x0 = np.random.rand(N_stars) * 10.0 # arcsec (increasing to East)
- y0 = np.random.rand(N_stars) * 10.0 # arcsec
- x0e = np.ones(N_stars) * 1.0e-4 # arcsec
- y0e = np.ones(N_stars) * 1.0e-4 # arcsec
- vx = np.random.randn(N_stars) * 5.0 # mas / yr
- vy = np.random.randn(N_stars) * 5.0 # mas / yr
- vxe = np.ones(N_stars) * 0.05 # mas / yr
- vye = np.ones(N_stars) * 0.05 # mas / yr
- m0 = (np.random.rand(N_stars) * 8) + 9 # mag
- m0e = np.random.randn(N_stars) * 0.05 # mag
- t0 = np.ones(N_stars) * 2019.5
+ # Now run_calc_bootstrap_error, with boot_epochs_min engaged
+ boot_epochs_min2 = 2
+ match2.calc_bootstrap_errors(n_boot=n_boot, boot_epochs_min=boot_epochs_min2)
- # Make all the errors positive
- x0e = np.abs(x0e)
- y0e = np.abs(y0e)
- m0e = np.abs(m0e)
- vxe = np.abs(vxe)
- vye = np.abs(vye)
-
- name = ['star_{0:03d}'.format(ii) for ii in range(N_stars)]
+ # Make sure boot_epochs_min cut worked as intended
+ out = match2.ref_table
+ bad = np.where( (out['n_detect'] == 1) & (out['use_in_trans'] == False) )
+ good = np.where(out['n_detect'] == 2)
- # Make an StarList
- lis = starlists.StarList([name, m0, m0e, x0, x0e, y0, y0e, vx, vxe, vy, vye, t0],
- names = ('name', 'm0', 'm0_err', 'x0', 'x0_err', 'y0', 'y0_err',
- 'vx', 'vx_err', 'vy', 'vy_err', 't0'))
-
- sdx = np.argsort(m0)
- lis = lis[sdx]
+ # Some stars must exist in both "good" and "bad" criteria,
+ # otherwise this test isn't as useful as intended.
+ assert len(bad[0]) > 0
+ assert len(good[0]) > 0
- # Save original positions as reference (1st) list
- # in a StarList format (with velocities).
- lis.write('random_vel_ref.fits', overwrite=True)
-
- ##########
- # Propogate to new times and distort.
- ##########
- # Make 4 new starlists with different epochs and transformations.
- times = [2018.5, 2019.0, 2019.5, 2020.0, 2020.5, 2021.0, 2021.5, 2022.0]
- xy_trans = [[[ 6.5], [ 10.1]],
- [[100.3], [ 50.5]],
- [[ 0.0], [ 0.0]],
- [[250.0], [-250.0]],
- [[ 50.0], [ -31.0]],
- [[ 78.0], [ 45.0]],
- [[-13.0], [ 150]],
- [[ 94.0], [-182.0]]]
- mag_trans = [0.1, 0.4, 0.0, -0.3, 0.2, 0.0, -0.1, -0.3]
+ # For "good" stars: all bootstrap vals should be present
+ assert np.sum(~np.isfinite(out['xe_boot'][good])) == 0
+ assert np.sum(~np.isfinite(out['ye_boot'][good])) == 0
+ assert np.sum(~np.isfinite(out['vx_err_boot'][good])) == 0
+ assert np.sum(~np.isfinite(out['vy_err_boot'][good])) == 0
- # Convert into pixels (undistorted) with the following info.
- scale = 0.01 # arcsec / pix
- shift = [1.0, 1.0] # pix
+ # For "bad" stars, all bootstrap vals should be nans
+ assert np.sum(np.isfinite(out['xe_boot'][bad])) == 0
+ assert np.sum(np.isfinite(out['ye_boot'][bad])) == 0
+ assert np.sum(np.isfinite(out['vx_err_boot'][bad])) == 0
+ assert np.sum(np.isfinite(out['vy_err_boot'][bad])) == 0
+
+ return
+
+def test_calc_vel_in_bootstrap():
+ """
+ Check calc_vel_in_bootstrap performance in calc_bootstrap_errors()
- for ss in range(len(times)):
- dt = times[ss] - lis['t0']
-
- x = lis['x0'] + (lis['vx']/1e3) * dt
- y = lis['y0'] + (lis['vy']/1e3) * dt
- t = np.ones(N_stars) * times[ss]
+ Only calculate velocity bootstrap (e.g., bootstrap over epochs and
+ calculating proper motions) if calc_vel_in_bootstrap=True.
- # Convert into pixels
- xp = (x / -scale) + shift[0] # -1 from switching to increasing to West (right)
- yp = (y / scale) + shift[1]
- xpe = lis['x0_err'] / scale
- ype = lis['y0_err'] / scale
+ """
+ import copy
- # Distort the positions
- trans = transforms.PolyTransform(0, xy_trans[ss][0], xy_trans[ss][1], mag_offset=mag_trans[ss])
- xd, yd = trans.evaluate(xp, yp)
- md = trans.evaluate_mag(lis['m0'])
+ # Define match parameters
+ ref = Table.read('ref_vel.lis', format='ascii')
- # Perturb with small errors (0.1 pix)
- xd += np.random.randn(N_stars) * xpe
- yd += np.random.randn(N_stars) * ype
- md += np.random.randn(N_stars) * 0.02
- xde = xpe
- yde = ype
- mde = lis['m0_err']
+ list1 = Table.read('E.lis', format='ascii')
+ list2 = Table.read('F.lis', format='ascii')
- # Save the new list as a starlist.
- new_lis = starlists.StarList([lis['name'], md, mde, xd, xde, yd, yde, t],
- names=('name', 'm', 'me', 'x', 'xe', 'y', 'ye', 't'))
+ list1 = starlists.StarList.from_table(list1)
+ list2 = starlists.StarList.from_table(list2)
+
+ # Set parameters for alignment
+ transModel = transforms.PolyTransform
+ trans_args = {'order':2}
+ N_loop = 1
+ dr_tol = 0.08
+ dm_tol = 99
+ outlier_tol = None
+ mag_lim = None
+ ref_mag_lim = None
+ trans_weighting = 'both,var'
+ mag_trans = False
- new_lis.write('random_vel_p0_{0:d}.fits'.format(ss), overwrite=True)
+ n_boot = 15
+ boot_epochs_min=-1
- return (xy_trans, mag_trans)
+ # Run match
+ match = align.MosaicToRef(ref, [list1, list2], iters=N_loop, dr_tol=dr_tol,
+ dm_tol=dm_tol, outlier_tol=outlier_tol,
+ trans_class=transModel,
+ trans_args=trans_args,
+ mag_trans=mag_trans,
+ mag_lim=mag_lim,
+ ref_mag_lim=ref_mag_lim,
+ trans_weighting=trans_weighting,
+ motion_models=['Linear'],
+ use_ref_new=False,
+ update_ref_orig=False,
+ init_guess_mode='name',
+ verbose=False)
+ match.fit()
+ # Make 2 copies of match object: one to test
+ # each case of calc_vel_in_bootstrap
+ match_vel = copy.deepcopy(match)
-def make_fake_starlists_poly1_vel(seed=-1):
- # If seed >=0, then set random seed to that value
- if seed >= 0:
- np.random.seed(seed=seed)
-
- N_stars = 200
+ # Run calc_bootstrap_error function with calc_vel_in_bootstrap=True.
+ # Make sure bootstrap velocity errors are calculated and valid
+ n_boot = 50
+ match_vel.calc_bootstrap_errors(n_boot=n_boot, calc_vel_in_bootstrap=True)
- x0 = np.random.rand(N_stars) * 10.0 # arcsec (increasing to East)
- y0 = np.random.rand(N_stars) * 10.0 # arcsec
- x0e = np.ones(N_stars) * 1.0e-4 # arcsec
- y0e = np.ones(N_stars) * 1.0e-4 # arcsec
- vx = np.random.randn(N_stars) * 5.0 # mas / yr
- vy = np.random.randn(N_stars) * 5.0 # mas / yr
- vxe = np.ones(N_stars) * 0.05 # mas / yr
- vye = np.ones(N_stars) * 0.05 # mas / yr
- m0 = (np.random.rand(N_stars) * 8) + 9 # mag
- m0e = np.random.randn(N_stars) * 0.05 # mag
- t0 = np.ones(N_stars) * 2019.5
+ assert 'xe_boot' in match_vel.ref_table.keys()
+ assert np.sum(np.isnan(match_vel.ref_table['xe_boot'])) == 0
+ assert 'vx_err_boot' in match_vel.ref_table.keys()
+ assert np.sum(np.isnan(match_vel.ref_table['vx_err_boot'])) == 0
- # Make all the errors positive
- x0e = np.abs(x0e)
- y0e = np.abs(y0e)
- m0e = np.abs(m0e)
- vxe = np.abs(vxe)
- vye = np.abs(vye)
-
- name = ['star_{0:03d}'.format(ii) for ii in range(N_stars)]
+ # Run without calc_vel_in_bootstrap, make sure velocities are NOT calculated
+ match.calc_bootstrap_errors(n_boot=n_boot, calc_vel_in_bootstrap=False)
- # Make an StarList
- lis = starlists.StarList([name, m0, m0e, x0, x0e, y0, y0e, vx, vxe, vy, vye, t0],
- names = ('name', 'm0', 'm0_err', 'x0', 'x0_err', 'y0', 'y0_err',
- 'vx', 'vx_err', 'vy', 'vy_err', 't0'))
+ assert 'xe_boot' in match.ref_table.keys()
+ assert np.sum(np.isnan(match.ref_table['xe_boot'])) == 0
+ assert 'vx_err_boot' not in match.ref_table.keys()
- sdx = np.argsort(m0)
- lis = lis[sdx]
+ return
- # Save original positions as reference (1st) list
- # in a StarList format (with velocities).
- lis.write('random_vel_ref.fits', overwrite=True)
-
- ##########
- # Propogate to new times and distort.
- ##########
- # Make 4 new starlists with different epochs and transformations.
- times = [2018.5, 2019.0, 2019.5, 2020.0, 2020.5, 2021.0, 2021.5, 2022.0]
- xy_trans = [[[ 6.5, 0.99, 1e-5], [ 10.1, 1e-5, 0.99]],
- [[100.3, 0.98, 1e-5], [ 50.5, 9e-6, 1.001]],
- [[ 0.0, 1.00, 0.0], [ 0.0, 0.0, 1.000]],
- [[250.0, 1.01, 2e-5], [-250.0, 1e-5, 0.98]],
- [[ 50.0, 1.01, 1e-5], [ -31.0, 1e-5, 1.000]],
- [[ 78.0, 0.98, 0.0 ], [ 45.0, 9e-6, 1.001]],
- [[-13.0, 0.99, 1e-5], [ 150, 2e-5, 1.002]],
- [[ 94.0, 1.00, 9e-6], [-182.0, 0.0, 0.99]]]
- mag_trans = [0.1, 0.4, 0.0, -0.3, 0.2, 0.0, -0.1, -0.3]
+def test_transform_xym():
+ """
+ Test to make sure transforms are being done to mags only
+ if mag_trans = True. This can cause subtle bugs
+ otherwise
+ """
+ #---Align 1: self.mag_Trans = False---#
+ ref = Table.read('ref_vel.lis', format='ascii')
+ list1 = Table.read('E.lis', format='ascii')
+ list2 = Table.read('F.lis', format='ascii')
- # Convert into pixels (undistorted) with the following info.
- scale = 0.01 # arcsec / pix
- shift = [1.0, 1.0] # pix
-
- for ss in range(len(times)):
- dt = times[ss] - lis['t0']
-
- x = lis['x0'] + (lis['vx']/1e3) * dt
- y = lis['y0'] + (lis['vy']/1e3) * dt
- t = np.ones(N_stars) * times[ss]
+ list1 = starlists.StarList.from_table(list1)
+ list2 = starlists.StarList.from_table(list2)
- # Convert into pixels
- xp = (x / -scale) + shift[0] # -1 from switching to increasing to West (right)
- yp = (y / scale) + shift[1]
- xpe = lis['x0_err'] / scale
- ype = lis['y0_err'] / scale
+ # Set parameters for alignment
+ transModel = transforms.PolyTransform
+ trans_args = {'order':2}
+ N_loop = 1
+ dr_tol = 0.08
+ dm_tol = 99
+ outlier_tol = None
+ mag_lim = None
+ ref_mag_lim = None
+ trans_weighting = 'both,var'
+ n_boot = 15
- # Distort the positions
- trans = transforms.PolyTransform(1, xy_trans[ss][0], xy_trans[ss][1], mag_offset=mag_trans[ss])
- xd, yd = trans.evaluate(xp, yp)
- md = trans.evaluate_mag(lis['m0'])
+ mag_trans = False
- # Perturb with small errors (0.1 mas)
- xd += np.random.randn(N_stars) * xpe
- yd += np.random.randn(N_stars) * ype
- md += np.random.randn(N_stars) * 0.02
- xde = xpe
- yde = ype
- mde = lis['m0_err']
+ # Run FLYSTAR, with bootstraps
+ match1 = align.MosaicToRef(ref, [list1, list2], iters=N_loop, dr_tol=dr_tol,
+ dm_tol=dm_tol, outlier_tol=outlier_tol,
+ trans_class=transModel,
+ trans_args=trans_args,
+ mag_trans=mag_trans,
+ mag_lim=mag_lim,
+ ref_mag_lim=ref_mag_lim,
+ trans_weighting=trans_weighting,
+ motion_models=['Fixed'],
+ use_ref_new=False,
+ update_ref_orig=False,
+ init_guess_mode='name',
+ verbose=False)
- # Save the new list as a starlist.
- new_lis = starlists.StarList([lis['name'], md, mde, xd, xde, yd, yde, t],
- names=('name', 'm', 'me', 'x', 'xe', 'y', 'ye', 't'))
+ match1.fit()
+ match1.calc_bootstrap_errors(n_boot=n_boot)
- new_lis.write('random_vel_{0:d}.fits'.format(ss), overwrite=True)
+ # Make sure all transformations have mag_offset = 0
+ trans_list = match1.trans_list
- return (xy_trans, mag_trans)
+ for ii in trans_list:
+ assert ii.mag_offset == 0
-def make_fake_starlists_poly1_acc(seed=-1):
+ # Check that no mag transformation has been applied to m col in ref_table
+ tab1 = match1.ref_table
+ assert np.all(tab1['m'] == tab1['m_orig'])
+
+ # Check me_boost == 0 or really small (should be the case
+ # since we don't transform mags)
+ assert np.isclose(np.max(tab1['me_boot']), 0, rtol=10**-5)
+ print('Done mag_trans = False case')
+
+ #---Align 2: self.mag_Trans = True---#
+ # Repeat, this time with mag_trans = False
+ mag_trans = True
+ match2 = align.MosaicToRef(ref, [list1, list2], iters=N_loop, dr_tol=dr_tol,
+ dm_tol=dm_tol, outlier_tol=outlier_tol,
+ trans_class=transModel,
+ trans_args=trans_args,
+ mag_trans=mag_trans,
+ mag_lim=mag_lim,
+ ref_mag_lim=ref_mag_lim,
+ trans_weighting=trans_weighting,
+ motion_models=['Fixed'],
+ use_ref_new=False,
+ update_ref_orig=False,
+ init_guess_mode='name',
+ verbose=False)
+
+ match2.fit()
+ match2.calc_bootstrap_errors(n_boot=n_boot)
+
+
+ # Make sure all transformations have correct mag offset
+ trans_list2 = match2.trans_list
+
+ for ii in trans_list2:
+ assert ii.mag_offset > 20
+
+ # Make sure final table mags have transform applied (i.e,
+ tab2 = match2.ref_table
+ assert np.all(tab2['m'] != tab2['m_orig'])
+
+ # Check me_boost > 0
+ assert np.min(tab2['me_boot']) > 10**-3
+
+ print('Done mag_trans = True case')
+
+ return
+
+def test_MosaicToRef_mag_bug():
+ """
+ Bug found by Tuan Do on 2020-04-12.
+ """
+ make_fake_starlists_poly1_vel()
+
+ ref_list = starlists.StarList.read('random_vel_0.fits')
+ lists = [ref_list]
+
+ msc = align.MosaicToRef(ref_list, lists,
+ mag_trans=True,
+ iters=1,
+ dr_tol=[0.2], dm_tol=[1],
+ outlier_tol=None,
+ trans_class=transforms.PolyTransform,
+ trans_args=[{'order': 1}],
+ motion_models=['Fixed'],
+ use_ref_new=False,
+ update_ref_orig=False,
+ verbose=True)
+
+ msc.fit()
+
+ out_tab = msc.ref_table
+
+ # The issue is that in the initial guess with
+ # mag_trans = True
+ # somehow the transformed magnitudes are nan.
+ # This causes zero matches to occur.
+ assert len(out_tab) == len(ref_list)
+
+ return
+
+def test_masked_cols():
+ """
+ Test to make sure analysis.prepare_gaia_for_flystar
+ produces an astropy.table.Table, NOT a masked column
+ table. MosaicToRef cannot handle masked column tables.
+
+ Also make sure this example works, since we use it for the examples
+ jupyter notebook.
+ """
+ # Get gaia reference stars using analysis.py
+ # around a test location.
+ # target = 'ob150029'
+ ra = '17:59:46.60'
+ dec = '-28:38:41.8'
+
+ # Coordinates are arcsecs offset +x to the East.
+ targets_dict = {
+ 'ob150029': [0.0, 0.0],
+ 'S005': [1.1416, 3.7405],
+ 'S002': [-4.421, 0.027]
+ }
+
+ # Get gaia catalog stars. Note that this produces a masked column table
+ search_rad = 10.0 # arcsec
+ gaia = analysis.query_gaia(ra, dec, search_radius=search_rad)
+ my_gaia = analysis.prepare_gaia_for_flystar(gaia, ra, dec, targets_dict=targets_dict)
+
+ assert isinstance(my_gaia, Table)
+
+ # Let's make sure the entire align runs, just to be safe
+
+ # Get starlists to align to gaia
+ epochs = ['15jun07','16jul14', '17may21']
+
+ list_of_starlists = []
+
+ for ee in range(len(epochs)):
+ lis_file = 'mag' + epochs[ee] + '_ob150029_kp_rms_named.lis'
+ lis = starlists.StarList.from_lis_file(lis_file)
+ list_of_starlists.append(lis)
+
+ # Run the align
+ msc = align.MosaicToRef(my_gaia, list_of_starlists, iters=2,
+ dr_tol=[0.2, 0.1], dm_tol=[1, 1],
+ trans_class=transforms.PolyTransform,
+ trans_args=[{'order': 1}, {'order': 1}],
+ motion_models=['Linear'],
+ use_ref_new=False,
+ update_ref_orig=False,
+ mag_trans=True,
+ init_guess_mode='name', verbose=True)
+
+ msc.fit()
+ return
+
+def make_fake_starlists_shifts():
+ N_stars = 200
+ x = np.random.rand(N_stars) * 1000
+ y = np.random.rand(N_stars) * 1000
+ m = (np.random.rand(N_stars) * 8) + 9
+
+ sdx = np.argsort(m)
+ x = x[sdx]
+ y = y[sdx]
+ m = m[sdx]
+
+ name = ['star_{0:03d}'.format(ii) for ii in range(N_stars)]
+
+ # Save original positions as reference (1st) list.
+ fmt = '{0:10s} {1:5.2f} 2015.0 {2:9.4f} {3:9.4f} 0 0 0 0\n'
+ _out = open('random_0.lis', 'w')
+ for ii in range(N_stars):
+ _out.write(fmt.format(name[ii], m[ii], x[ii], y[ii]))
+ _out.close()
+
+
+ ##########
+ # Shifts
+ ##########
+ # Make 4 new starlists with different shifts.
+ shifts = [[ 6.5, 10.1],
+ [100.3, 50.5],
+ [-30.0,-100.7],
+ [250.0,-250.0]]
+
+ for ss in range(len(shifts)):
+ xnew = x - shifts[ss][0]
+ ynew = y - shifts[ss][1]
+
+ # Perturb with small errors (0.1 pix)
+ xnew += np.random.randn(N_stars) * 0.1
+ ynew += np.random.randn(N_stars) * 0.1
+
+ mnew = m + np.random.randn(N_stars) * 0.05
+
+ _out = open('random_shift_{0:d}.lis'.format(ss+1), 'w')
+ for ii in range(N_stars):
+ _out.write(fmt.format(name[ii], mnew[ii], xnew[ii], ynew[ii]))
+ _out.close()
+
+ return shifts
+
+def make_fake_starlists_poly1(seed=-1):
# If seed >=0, then set random seed to that value
if seed >= 0:
np.random.seed(seed=seed)
@@ -814,16 +982,8 @@ def make_fake_starlists_poly1_acc(seed=-1):
x0 = np.random.rand(N_stars) * 10.0 # arcsec (increasing to East)
y0 = np.random.rand(N_stars) * 10.0 # arcsec
- x0e = np.ones(N_stars) * 1.0e-4 # arcsec
- y0e = np.ones(N_stars) * 1.0e-4 # arcsec
- vx = np.random.randn(N_stars) * 5.0 # mas / yr
- vy = np.random.randn(N_stars) * 5.0 # mas / yr
- vxe = np.ones(N_stars) * 0.1 # mas / yr
- vye = np.ones(N_stars) * 0.1 # mas / yr
- ax = np.random.randn(N_stars) * 0.5 # mas / yr^2
- ay = np.random.randn(N_stars) * 0.5 # mas / yr^2
- axe = np.ones(N_stars) * 0.01 # mas / yr^2
- aye = np.ones(N_stars) * 0.01 # mas / yr^2
+ x0e = np.random.randn(N_stars) * 5.0e-4 # arcsec
+ y0e = np.random.randn(N_stars) * 5.0e-4 # arcsec
m0 = (np.random.rand(N_stars) * 8) + 9 # mag
m0e = np.random.randn(N_stars) * 0.05 # mag
t0 = np.ones(N_stars) * 2019.5
@@ -832,56 +992,44 @@ def make_fake_starlists_poly1_acc(seed=-1):
x0e = np.abs(x0e)
y0e = np.abs(y0e)
m0e = np.abs(m0e)
- vxe = np.abs(vxe)
- vye = np.abs(vye)
- axe = np.abs(axe)
- aye = np.abs(aye)
name = ['star_{0:03d}'.format(ii) for ii in range(N_stars)]
# Make an StarList
- lis = starlists.StarList([name, m0, m0e,
- x0, x0e, y0, y0e,
- vx, vxe, vy, vye,
- ax, axe, ay, aye,
- t0],
- names = ('name', 'm0', 'm0_err',
- 'x0', 'x0_err', 'y0', 'y0_err',
- 'vx0', 'vx0_err', 'vy0', 'vy0_err',
- 'ax', 'ax_err', 'ay', 'ay_err',
- 't0'))
+ lis = starlists.StarList([name, m0, m0e, x0, x0e, y0, y0e, t0],
+ names = ('name', 'm0', 'm0_err', 'x0', 'x0_err', 'y0', 'y0_err', 't0'))
sdx = np.argsort(m0)
lis = lis[sdx]
# Save original positions as reference (1st) list
# in a StarList format (with velocities).
- lis.write('random_acc_ref.fits', overwrite=True)
-
+ lis.write('random_ref.fits', overwrite=True)
+
##########
- # Propogate to new times and distort.
+ # Shifts
##########
- # Make 4 new starlists with different epochs and transformations.
+ # Make 4 new starlists with different shifts.
times = [2018.5, 2019.0, 2019.5, 2020.0, 2020.5, 2021.0, 2021.5, 2022.0]
xy_trans = [[[ 6.5, 0.99, 1e-5], [ 10.1, 1e-5, 0.99]],
[[100.3, 0.98, 1e-5], [ 50.5, 9e-6, 1.001]],
- [[ 0.0, 1.00, 0.0], [ 0.0, 0.0, 1.000]],
+ [[ 0.0, 1.00, 0.0], [ 0.0, 0.0, 1.0]],
[[250.0, 0.97, 2e-5], [-250.0, 1e-5, 1.001]],
[[ 50.0, 1.01, 1e-5], [ -31.0, 1e-5, 1.000]],
[[ 78.0, 0.98, 0.0 ], [ 45.0, 9e-6, 1.001]],
[[-13.0, 0.99, 1e-5], [ 150, 2e-5, 1.002]],
[[ 94.0, 1.00, 9e-6], [-182.0, 0.0, 0.99]]]
mag_trans = [0.1, 0.4, 0.0, -0.3, 0.2, 0.0, -0.1, -0.3]
-
+
# Convert into pixels (undistorted) with the following info.
scale = 0.01 # arcsec / pix
shift = [1.0, 1.0] # pix
-
+
for ss in range(len(times)):
dt = times[ss] - lis['t0']
- x = lis['x0'] + (lis['vx0']/1e3) * dt + 0.5*(lis['ax']/1e3) * dt**2
- y = lis['y0'] + (lis['vy0']/1e3) * dt + 0.5*(lis['ay']/1e3) * dt**2
+ x = lis['x0']
+ y = lis['y0']
t = np.ones(N_stars) * times[ss]
# Convert into pixels
@@ -896,8 +1044,8 @@ def make_fake_starlists_poly1_acc(seed=-1):
md = trans.evaluate_mag(lis['m0'])
# Perturb with small errors (0.1 pix)
- xd += np.random.randn(N_stars) * xpe
- yd += np.random.randn(N_stars) * ype
+ xd += np.random.randn(N_stars) * 0.1
+ yd += np.random.randn(N_stars) * 0.1
md += np.random.randn(N_stars) * 0.02
xde = xpe
yde = ype
@@ -907,11 +1055,11 @@ def make_fake_starlists_poly1_acc(seed=-1):
new_lis = starlists.StarList([lis['name'], md, mde, xd, xde, yd, yde, t],
names=('name', 'm', 'me', 'x', 'xe', 'y', 'ye', 't'))
- new_lis.write('random_acc_{0:d}.fits'.format(ss), overwrite=True)
+ new_lis.write('random_{0:d}.fits'.format(ss), overwrite=True)
- return (xy_trans, mag_trans)
-
-def make_fake_starlists_poly1_par(seed=-1):
+ return (xy_trans,mag_trans)
+
+def make_fake_starlists_poly0_vel(seed=-1):
# If seed >=0, then set random seed to that value
if seed >= 0:
np.random.seed(seed=seed)
@@ -920,14 +1068,12 @@ def make_fake_starlists_poly1_par(seed=-1):
x0 = np.random.rand(N_stars) * 10.0 # arcsec (increasing to East)
y0 = np.random.rand(N_stars) * 10.0 # arcsec
- x0e = np.random.randn(N_stars) * 5.0e-4 # arcsec
- y0e = np.random.randn(N_stars) * 5.0e-4 # arcsec
+ x0e = np.ones(N_stars) * 1.0e-4 # arcsec
+ y0e = np.ones(N_stars) * 1.0e-4 # arcsec
vx = np.random.randn(N_stars) * 5.0 # mas / yr
vy = np.random.randn(N_stars) * 5.0 # mas / yr
- vxe = np.random.randn(N_stars) * 0.1 # mas / yr
- vye = np.random.randn(N_stars) * 0.1 # mas / yr
- pi = np.random.randn(N_stars) * 0.5 # mas
- pie = np.random.randn(N_stars) * 0.01 # mas
+ vxe = np.ones(N_stars) * 0.05 # mas / yr
+ vye = np.ones(N_stars) * 0.05 # mas / yr
m0 = (np.random.rand(N_stars) * 8) + 9 # mag
m0e = np.random.randn(N_stars) * 0.05 # mag
t0 = np.ones(N_stars) * 2019.5
@@ -938,50 +1084,35 @@ def make_fake_starlists_poly1_par(seed=-1):
m0e = np.abs(m0e)
vxe = np.abs(vxe)
vye = np.abs(vye)
- pie = np.abs(pie)
name = ['star_{0:03d}'.format(ii) for ii in range(N_stars)]
# Make an StarList
- lis = starlists.StarList([name, m0, m0e,
- x0, x0e, y0, y0e,
- vx, vxe, vy, vye,
- pi, pie,
- t0],
- names = ('name', 'm0', 'm0_err',
- 'x0', 'x0_err', 'y0', 'y0_err',
- 'vx', 'vx_err', 'vy', 'vy_err',
- 'pi', 'pi_err',
- 't0'))
+ lis = starlists.StarList([name, m0, m0e, x0, x0e, y0, y0e, vx, vxe, vy, vye, t0],
+ names = ('name', 'm0', 'm0_err', 'x0', 'x0_err', 'y0', 'y0_err',
+ 'vx', 'vx_err', 'vy', 'vy_err', 't0'))
sdx = np.argsort(m0)
lis = lis[sdx]
# Save original positions as reference (1st) list
# in a StarList format (with velocities).
- lis.write('random_par_ref.fits', overwrite=True)
+ lis.write('random_vel_ref.fits', overwrite=True)
##########
# Propogate to new times and distort.
##########
# Make 4 new starlists with different epochs and transformations.
- '''times = [2018.5, 2019.5, 2020.5, 2021.5]
- xy_trans = [[[ 6.5, 0.99, 1e-5], [ 10.1, 1e-5, 0.99]],
- [[100.3, 0.98, 1e-5], [ 50.5, 9e-6, 1.001]],
- [[ 0.0, 1.00, 0.0], [ 0.0, 0.0, 1.0]],
- [[250.0, 0.97, 2e-5], [-250.0, 1e-5, 1.001]]]
- mag_trans = [0.1, 0.4, 0.0, -0.3]'''
-
times = [2018.5, 2019.0, 2019.5, 2020.0, 2020.5, 2021.0, 2021.5, 2022.0]
- xy_trans = [[[ 6.5, 0.99, 1e-5], [ 10.1, 1e-5, 0.99]],
- [[100.3, 0.98, 1e-5], [ 50.5, 9e-6, 1.001]],
- [[ 0.0, 1.00, 0.0], [ 0.0, 0.0, 1.0]],
- [[250.0, 0.97, 2e-5], [-250.0, 1e-5, 1.001]],
- [[ 50.0, 1.00, 0.0], [ -31.0, 0.0, 1.000]],
- [[ 78.0, 1.00, 0.0 ], [ 45.0, 0.0, 1.00]],
- [[-13.0, 1.00, 0.0], [ 150, 0.0, 1.00]],
- [[ 94.0, 1.00, 0.0], [-182.0, 0.0, 1.00]]]
- mag_trans = [0.1, 0.4, 0.0, -0.3, 0.0, 0.0, 0.0, 0.0]
+ xy_trans = [[[ 6.5], [ 10.1]],
+ [[100.3], [ 50.5]],
+ [[ 0.0], [ 0.0]],
+ [[250.0], [-250.0]],
+ [[ 50.0], [ -31.0]],
+ [[ 78.0], [ 45.0]],
+ [[-13.0], [ 150]],
+ [[ 94.0], [-182.0]]]
+ mag_trans = [0.1, 0.4, 0.0, -0.3, 0.2, 0.0, -0.1, -0.3]
# Convert into pixels (undistorted) with the following info.
scale = 0.01 # arcsec / pix
@@ -990,10 +1121,8 @@ def make_fake_starlists_poly1_par(seed=-1):
for ss in range(len(times)):
dt = times[ss] - lis['t0']
- par_mod = motion_model.Parallax(PA=0,RA=18.0, Dec=-30.0)
- par_mod_dat = par_mod.get_batch_pos_at_time(dt+lis['t0'], x0=lis['x0'],vx=lis['vx']/1e3, pi=lis['pi'],
- y0=lis['y0'], vy=lis['vy']/1e3, t0=lis['t0'])
- x,y = par_mod_dat[0], par_mod_dat[1]
+ x = lis['x0'] + (lis['vx']/1e3) * dt
+ y = lis['y0'] + (lis['vy']/1e3) * dt
t = np.ones(N_stars) * times[ss]
# Convert into pixels
@@ -1003,13 +1132,13 @@ def make_fake_starlists_poly1_par(seed=-1):
ype = lis['y0_err'] / scale
# Distort the positions
- trans = transforms.PolyTransform(1, xy_trans[ss][0], xy_trans[ss][1], mag_offset=mag_trans[ss])
+ trans = transforms.PolyTransform(0, xy_trans[ss][0], xy_trans[ss][1], mag_offset=mag_trans[ss])
xd, yd = trans.evaluate(xp, yp)
md = trans.evaluate_mag(lis['m0'])
# Perturb with small errors (0.1 pix)
- xd += np.random.randn(N_stars) * 0.1
- yd += np.random.randn(N_stars) * 0.1
+ xd += np.random.randn(N_stars) * xpe
+ yd += np.random.randn(N_stars) * ype
md += np.random.randn(N_stars) * 0.02
xde = xpe
yde = ype
@@ -1019,435 +1148,318 @@ def make_fake_starlists_poly1_par(seed=-1):
new_lis = starlists.StarList([lis['name'], md, mde, xd, xde, yd, yde, t],
names=('name', 'm', 'me', 'x', 'xe', 'y', 'ye', 't'))
- new_lis.write('random_par_{0:d}.fits'.format(ss), overwrite=True)
+ new_lis.write('random_vel_p0_{0:d}.fits'.format(ss), overwrite=True)
return (xy_trans, mag_trans)
-
-def test_MosaicToRef_hst_me():
- """
- Test Casey's issue with 'me' not getting propogated
- from the input starlists to the output table.
- Use data from MB10-364 microlensing target for the test.
- """
- # Target RA and Dec (MOA data download)
- ra = '17:57:05.401'
- dec = '-34:27:05.01'
-
- # Load up a Gaia catalog (queried around the RA/Dec above)
- my_gaia = Table.read('mb10364_data/my_gaia.fits')
- my_gaia['me'] = 0.01
-
- # Gather the list of starlists. For first pass, don't modify the starlists.
- # Loop through the observations and read them in, in prep for alignment with Gaia
- epochs = [2011.83, 2012.73, 2013.81]
- starlist_names = ['mb10364_data/2011_10_31_F606W_MATCHUP_XYMEEE_final.calib',
- 'mb10364_data/2012_09_25_F606W_MATCHUP_XYMEEE_final.calib',
- 'mb10364_data/2013_10_24_F606W_MATCHUP_XYMEEE_final.calib']
-
- list_of_starlists = []
-
- # Just using the F606W filters first.
- for ee in range(len(starlist_names)):
- lis = starlists.StarList.from_lis_file(starlist_names[ee])
-
- # # Add additive error term. MAYBE YOU DON'T NEED THIS
- # lis['xe'] = np.hypot(lis['xe'], 0.01) # Adding 0.01 pix (0.1 mas) in quadrature.
- # lis['ye'] = np.hypot(lis['ye'], 0.01)
+def make_fake_starlists_poly1_vel(seed=-1):
+ # If seed >=0, then set random seed to that value
+ if seed >= 0:
+ np.random.seed(seed=seed)
- lis['t'] = epochs[ee]
-
- # Lets dump the faint stars.
- idx = np.where(lis['m'] < 20.0)[0]
- lis = lis[idx]
+ N_stars = 200
- list_of_starlists.append(lis)
-
- msc = align.MosaicToRef(my_gaia, list_of_starlists, iters=1,
- dr_tol=[0.1], dm_tol=[5],
- outlier_tol=[None], mag_lim=[13, 21],
- trans_class=transforms.PolyTransform,
- trans_args=[{'order': 1}],
- default_motion_model='Fixed',
- use_ref_new=False,
- update_ref_orig=False,
- mag_trans=False,
- trans_weights='both,std',
- init_guess_mode='miracle', verbose=False)
- msc.fit()
- tab = msc.ref_table
+ x0 = np.random.rand(N_stars) * 10.0 # arcsec (increasing to East)
+ y0 = np.random.rand(N_stars) * 10.0 # arcsec
+ x0e = np.ones(N_stars) * 1.0e-4 # arcsec
+ y0e = np.ones(N_stars) * 1.0e-4 # arcsec
+ vx = np.random.randn(N_stars) * 5.0 # mas / yr
+ vy = np.random.randn(N_stars) * 5.0 # mas / yr
+ vxe = np.ones(N_stars) * 0.05 # mas / yr
+ vye = np.ones(N_stars) * 0.05 # mas / yr
+ m0 = (np.random.rand(N_stars) * 8) + 9 # mag
+ m0e = np.random.randn(N_stars) * 0.05 # mag
+ t0 = np.ones(N_stars) * 2019.5
- assert 'me' in tab.colnames
+ # Make all the errors positive
+ x0e = np.abs(x0e)
+ y0e = np.abs(y0e)
+ m0e = np.abs(m0e)
+ vxe = np.abs(vxe)
+ vye = np.abs(vye)
+
+ name = ['star_{0:03d}'.format(ii) for ii in range(N_stars)]
- return
+ # Make an StarList
+ lis = starlists.StarList([name, m0, m0e, x0, x0e, y0, y0e, vx, vxe, vy, vye, t0],
+ names = ('name', 'm0', 'm0_err', 'x0', 'x0_err', 'y0', 'y0_err',
+ 'vx', 'vx_err', 'vy', 'vy_err', 't0'))
+
+ sdx = np.argsort(m0)
+ lis = lis[sdx]
-def test_bootstrap():
- """
- Test to make sure calc_bootstrap_error() call is working
- properly (e.g., only called when user calls calc_bootstrap_error,
- n_boot param for calc_bootstrap_error only, boot_epochs_min working,
- etc.)
- """
- # Read in starlists for MosaicToRef
- ref = Table.read('ref_vel.lis', format='ascii')
- list1 = Table.read('E.lis', format='ascii')
- list2 = Table.read('F.lis', format='ascii')
+ # Save original positions as reference (1st) list
+ # in a StarList format (with velocities).
+ lis.write('random_vel_ref.fits', overwrite=True)
+
+ ##########
+ # Propogate to new times and distort.
+ ##########
+ # Make 4 new starlists with different epochs and transformations.
+ times = [2018.5, 2019.0, 2019.5, 2020.0, 2020.5, 2021.0, 2021.5, 2022.0]
+ xy_trans = [[[ 6.5, 0.99, 1e-5], [ 10.1, 1e-5, 0.99]],
+ [[100.3, 0.98, 1e-5], [ 50.5, 9e-6, 1.001]],
+ [[ 0.0, 1.00, 0.0], [ 0.0, 0.0, 1.000]],
+ [[250.0, 1.01, 2e-5], [-250.0, 1e-5, 0.98]],
+ [[ 50.0, 1.01, 1e-5], [ -31.0, 1e-5, 1.000]],
+ [[ 78.0, 0.98, 0.0 ], [ 45.0, 9e-6, 1.001]],
+ [[-13.0, 0.99, 1e-5], [ 150, 2e-5, 1.002]],
+ [[ 94.0, 1.00, 9e-6], [-182.0, 0.0, 0.99]]]
+ mag_trans = [0.1, 0.4, 0.0, -0.3, 0.2, 0.0, -0.1, -0.3]
- list1 = starlists.StarList.from_table(list1)
- list2 = starlists.StarList.from_table(list2)
+ # Convert into pixels (undistorted) with the following info.
+ scale = 0.01 # arcsec / pix
+ shift = [1.0, 1.0] # pix
+
+ for ss in range(len(times)):
+ dt = times[ss] - lis['t0']
- # Set parameters for alignment
- transModel = transforms.PolyTransform
- trans_args = {'order':2}
- N_loop = 1
- dr_tol = 0.08
- dm_tol = 99
- outlier_tol = None
- mag_lim = None
- ref_mag_lim = None
- trans_weights = 'both,var'
- mag_trans = False
+ x = lis['x0'] + (lis['vx']/1e3) * dt
+ y = lis['y0'] + (lis['vy']/1e3) * dt
+ t = np.ones(N_stars) * times[ss]
- n_boot = 15
- boot_epochs_min=-1
+ # Convert into pixels
+ xp = (x / -scale) + shift[0] # -1 from switching to increasing to West (right)
+ yp = (y / scale) + shift[1]
+ xpe = lis['x0_err'] / scale
+ ype = lis['y0_err'] / scale
- # Run FLYSTAR, no bootstraps yet!
- match1 = align.MosaicToRef(ref, [list1, list2], iters=N_loop, dr_tol=dr_tol,
- dm_tol=dm_tol, outlier_tol=outlier_tol,
- trans_class=transModel,
- trans_args=trans_args,
- mag_trans=mag_trans,
- mag_lim=mag_lim,
- ref_mag_lim=ref_mag_lim,
- trans_weights=trans_weights,
- default_motion_model='Linear',
- use_ref_new=False,
- update_ref_orig=False,
- init_guess_mode='name',
- verbose=False)
- match1.fit()
+ # Distort the positions
+ trans = transforms.PolyTransform(1, xy_trans[ss][0], xy_trans[ss][1], mag_offset=mag_trans[ss])
+ xd, yd = trans.evaluate(xp, yp)
+ md = trans.evaluate_mag(lis['m0'])
- # Make sure no bootstrap columns exist
- assert 'xe_boot' not in match1.ref_table.keys()
- assert 'ye_boot' not in match1.ref_table.keys()
- assert 'vxe_boot' not in match1.ref_table.keys()
- assert 'vye_boot' not in match1.ref_table.keys()
+ # Perturb with small errors (0.1 mas)
+ xd += np.random.randn(N_stars) * xpe
+ yd += np.random.randn(N_stars) * ype
+ md += np.random.randn(N_stars) * 0.02
+ xde = xpe
+ yde = ype
+ mde = lis['m0_err']
- # Run bootstrap: no boot_epochs_min
- match1.calc_bootstrap_errors(n_boot=n_boot, boot_epochs_min=boot_epochs_min)
- # Make sure columns exist, and none of them are nan values
- assert np.sum(np.isnan(match1.ref_table['xe_boot'])) == 0
- assert np.sum(np.isnan(match1.ref_table['ye_boot'])) == 0
- assert np.sum(np.isnan(match1.ref_table['vx_err_boot'])) == 0
- assert np.sum(np.isnan(match1.ref_table['vy_err_boot'])) == 0
- #pdb.set_trace()
+ # Save the new list as a starlist.
+ new_lis = starlists.StarList([lis['name'], md, mde, xd, xde, yd, yde, t],
+ names=('name', 'm', 'me', 'x', 'xe', 'y', 'ye', 't'))
- # Test 2: make sure boot_epochs_min is working
- # Eliminate some rows to list2, so some stars are only in 1 epoch.
- # Rerun align. Some stars should only be detected in 1 epoch
- list3 = list2[0:60]
+ new_lis.write('random_vel_{0:d}.fits'.format(ss), overwrite=True)
- match2 = align.MosaicToRef(ref, [list1, list3], iters=N_loop, dr_tol=dr_tol,
- dm_tol=dm_tol, outlier_tol=outlier_tol,
- trans_class=transModel,
- trans_args=trans_args,
- mag_trans=mag_trans,
- mag_lim=mag_lim,
- ref_mag_lim=ref_mag_lim,
- trans_weights=trans_weights,
- default_motion_model='Linear',
- use_ref_new=False,
- update_ref_orig=False,
- init_guess_mode='name',
- verbose=False)
- match2.fit()
-
- # Now run_calc_bootstrap_error, with boot_epochs_min engaged
- boot_epochs_min2 = 2
- match2.calc_bootstrap_errors(n_boot=n_boot, boot_epochs_min=boot_epochs_min2)
-
- # Make sure boot_epochs_min cut worked as intended
- out = match2.ref_table
- bad = np.where( (out['n_detect'] == 1) & (out['use_in_trans'] == False) )
- good = np.where(out['n_detect'] == 2)
-
- # Some stars must exist in both "good" and "bad" criteria,
- # otherwise this test isn't as useful as intended.
- assert len(bad[0]) > 0
- assert len(good[0]) > 0
-
- # For "good" stars: all bootstrap vals should be present
- assert np.sum(np.isnan(out['xe_boot'][good])) == 0
- assert np.sum(np.isnan(out['ye_boot'][good])) == 0
- assert np.sum(np.isnan(out['vx_err_boot'][good])) == 0
- assert np.sum(np.isnan(out['vy_err_boot'][good])) == 0
+ return (xy_trans, mag_trans)
- # For "bad" stars, all bootstrap vals should be nans
- assert np.sum(np.isfinite(out['xe_boot'][bad])) == 0
- assert np.sum(np.isfinite(out['ye_boot'][bad])) == 0
- assert np.sum(np.isfinite(out['vx_err_boot'][bad])) == 0
- assert np.sum(np.isfinite(out['vy_err_boot'][bad])) == 0
+def make_fake_starlists_poly1_acc(seed=-1):
+ # If seed >=0, then set random seed to that value
+ if seed >= 0:
+ np.random.seed(seed=seed)
+
+ N_stars = 200
- return
+ x0 = np.random.rand(N_stars) * 10.0 # arcsec (increasing to East)
+ y0 = np.random.rand(N_stars) * 10.0 # arcsec
+ x0e = np.ones(N_stars) * 1.0e-4 # arcsec
+ y0e = np.ones(N_stars) * 1.0e-4 # arcsec
+ vx = np.random.randn(N_stars) * 5.0 # mas / yr
+ vy = np.random.randn(N_stars) * 5.0 # mas / yr
+ vxe = np.ones(N_stars) * 0.1 # mas / yr
+ vye = np.ones(N_stars) * 0.1 # mas / yr
+ ax = np.random.randn(N_stars) * 0.5 # mas / yr^2
+ ay = np.random.randn(N_stars) * 0.5 # mas / yr^2
+ axe = np.ones(N_stars) * 0.01 # mas / yr^2
+ aye = np.ones(N_stars) * 0.01 # mas / yr^2
+ m0 = (np.random.rand(N_stars) * 8) + 9 # mag
+ m0e = np.random.randn(N_stars) * 0.05 # mag
+ t0 = np.ones(N_stars) * 2019.5
-def test_calc_vel_in_bootstrap():
- """
- Check calc_vel_in_bootstrap performance in calc_bootstrap_errors()
+ # Make all the errors positive
+ x0e = np.abs(x0e)
+ y0e = np.abs(y0e)
+ m0e = np.abs(m0e)
+ vxe = np.abs(vxe)
+ vye = np.abs(vye)
+ axe = np.abs(axe)
+ aye = np.abs(aye)
- Only calculate velocity bootstrap (e.g., bootstrap over epochs and
- calculating proper motions) if calc_vel_in_bootstrap=True.
+ name = ['star_{0:03d}'.format(ii) for ii in range(N_stars)]
- """
- import copy
+ # Make an StarList
+ lis = starlists.StarList([name, m0, m0e,
+ x0, x0e, y0, y0e,
+ vx, vxe, vy, vye,
+ ax, axe, ay, aye,
+ t0],
+ names = ('name', 'm0', 'm0_err',
+ 'x0', 'x0_err', 'y0', 'y0_err',
+ 'vx0', 'vx0_err', 'vy0', 'vy0_err',
+ 'ax', 'ax_err', 'ay', 'ay_err',
+ 't0'))
- # Define match parameters
- ref = Table.read('ref_vel.lis', format='ascii')
+ sdx = np.argsort(m0)
+ lis = lis[sdx]
- list1 = Table.read('E.lis', format='ascii')
- list2 = Table.read('F.lis', format='ascii')
+ # Save original positions as reference (1st) list
+ # in a StarList format (with velocities).
+ lis.write('random_acc_ref.fits', overwrite=True)
+
+ ##########
+ # Propogate to new times and distort.
+ ##########
+ # Make 4 new starlists with different epochs and transformations.
+ times = [2018.5, 2019.0, 2019.5, 2020.0, 2020.5, 2021.0, 2021.5, 2022.0]
+ xy_trans = [[[ 6.5, 0.99, 1e-5], [ 10.1, 1e-5, 0.99]],
+ [[100.3, 0.98, 1e-5], [ 50.5, 9e-6, 1.001]],
+ [[ 0.0, 1.00, 0.0], [ 0.0, 0.0, 1.000]],
+ [[250.0, 0.97, 2e-5], [-250.0, 1e-5, 1.001]],
+ [[ 50.0, 1.01, 1e-5], [ -31.0, 1e-5, 1.000]],
+ [[ 78.0, 0.98, 0.0 ], [ 45.0, 9e-6, 1.001]],
+ [[-13.0, 0.99, 1e-5], [ 150, 2e-5, 1.002]],
+ [[ 94.0, 1.00, 9e-6], [-182.0, 0.0, 0.99]]]
+ mag_trans = [0.1, 0.4, 0.0, -0.3, 0.2, 0.0, -0.1, -0.3]
- list1 = starlists.StarList.from_table(list1)
- list2 = starlists.StarList.from_table(list2)
+ # Convert into pixels (undistorted) with the following info.
+ scale = 0.01 # arcsec / pix
+ shift = [1.0, 1.0] # pix
+
+ for ss in range(len(times)):
+ dt = times[ss] - lis['t0']
- # Set parameters for alignment
- transModel = transforms.PolyTransform
- trans_args = {'order':2}
- N_loop = 1
- dr_tol = 0.08
- dm_tol = 99
- outlier_tol = None
- mag_lim = None
- ref_mag_lim = None
- trans_weights = 'both,var'
- mag_trans = False
-
- n_boot = 15
- boot_epochs_min=-1
+ x = lis['x0'] + (lis['vx0']/1e3) * dt + 0.5*(lis['ax']/1e3) * dt**2
+ y = lis['y0'] + (lis['vy0']/1e3) * dt + 0.5*(lis['ay']/1e3) * dt**2
+ t = np.ones(N_stars) * times[ss]
- # Run match
- match = align.MosaicToRef(ref, [list1, list2], iters=N_loop, dr_tol=dr_tol,
- dm_tol=dm_tol, outlier_tol=outlier_tol,
- trans_class=transModel,
- trans_args=trans_args,
- mag_trans=mag_trans,
- mag_lim=mag_lim,
- ref_mag_lim=ref_mag_lim,
- trans_weights=trans_weights,
- default_motion_model='Linear',
- use_ref_new=False,
- update_ref_orig=False,
- init_guess_mode='name',
- verbose=False)
- match.fit()
+ # Convert into pixels
+ xp = (x / -scale) + shift[0] # -1 from switching to increasing to West (right)
+ yp = (y / scale) + shift[1]
+ xpe = lis['x0_err'] / scale
+ ype = lis['y0_err'] / scale
- # Make 2 copies of match object: one to test
- # each case of calc_vel_in_bootstrap
- match_vel = copy.deepcopy(match)
+ # Distort the positions
+ trans = transforms.PolyTransform(1, xy_trans[ss][0], xy_trans[ss][1], mag_offset=mag_trans[ss])
+ xd, yd = trans.evaluate(xp, yp)
+ md = trans.evaluate_mag(lis['m0'])
- # Run calc_bootstrap_error function with calc_vel_in_bootstrap=True.
- # Make sure bootstrap velocity errors are calculated and valid
- n_boot = 50
- match_vel.calc_bootstrap_errors(n_boot=n_boot, calc_vel_in_bootstrap=True)
+ # Perturb with small errors (0.1 pix)
+ xd += np.random.randn(N_stars) * xpe
+ yd += np.random.randn(N_stars) * ype
+ md += np.random.randn(N_stars) * 0.02
+ xde = xpe
+ yde = ype
+ mde = lis['m0_err']
- assert 'xe_boot' in match_vel.ref_table.keys()
- assert np.sum(np.isnan(match_vel.ref_table['xe_boot'])) == 0
- assert 'vx_err_boot' in match_vel.ref_table.keys()
- assert np.sum(np.isnan(match_vel.ref_table['vx_err_boot'])) == 0
+ # Save the new list as a starlist.
+ new_lis = starlists.StarList([lis['name'], md, mde, xd, xde, yd, yde, t],
+ names=('name', 'm', 'me', 'x', 'xe', 'y', 'ye', 't'))
- # Run without calc_vel_in_bootstrap, make sure velocities are NOT calculated
- match.calc_bootstrap_errors(n_boot=n_boot, calc_vel_in_bootstrap=False)
+ new_lis.write('random_acc_{0:d}.fits'.format(ss), overwrite=True)
- assert 'xe_boot' in match.ref_table.keys()
- assert np.sum(np.isnan(match.ref_table['xe_boot'])) == 0
- assert 'vx_err_boot' not in match.ref_table.keys()
+ return (xy_trans, mag_trans)
- return
+def make_fake_starlists_poly1_par(seed=-1):
+ # If seed >=0, then set random seed to that value
+ if seed >= 0:
+ np.random.seed(seed=seed)
+
+ N_stars = 200
-def test_transform_xym():
- """
- Test to make sure transforms are being done to mags only
- if mag_trans = True. This can cause subtle bugs
- otherwise
- """
- #---Align 1: self.mag_Trans = False---#
- ref = Table.read('ref_vel.lis', format='ascii')
- list1 = Table.read('E.lis', format='ascii')
- list2 = Table.read('F.lis', format='ascii')
+ x0 = np.random.rand(N_stars) * 10.0 # arcsec (increasing to East)
+ y0 = np.random.rand(N_stars) * 10.0 # arcsec
+ x0e = np.random.randn(N_stars) * 5.0e-4 # arcsec
+ y0e = np.random.randn(N_stars) * 5.0e-4 # arcsec
+ vx = np.random.randn(N_stars) * 5.0 # mas / yr
+ vy = np.random.randn(N_stars) * 5.0 # mas / yr
+ vxe = np.random.randn(N_stars) * 0.1 # mas / yr
+ vye = np.random.randn(N_stars) * 0.1 # mas / yr
+ pi = np.random.randn(N_stars) * 0.5 # mas
+ pie = np.random.randn(N_stars) * 0.01 # mas
+ m0 = (np.random.rand(N_stars) * 8) + 9 # mag
+ m0e = np.random.randn(N_stars) * 0.05 # mag
+ t0 = np.ones(N_stars) * 2019.5
- list1 = starlists.StarList.from_table(list1)
- list2 = starlists.StarList.from_table(list2)
+ # Make all the errors positive
+ x0e = np.abs(x0e)
+ y0e = np.abs(y0e)
+ m0e = np.abs(m0e)
+ vxe = np.abs(vxe)
+ vye = np.abs(vye)
+ pie = np.abs(pie)
- # Set parameters for alignment
- transModel = transforms.PolyTransform
- trans_args = {'order':2}
- N_loop = 1
- dr_tol = 0.08
- dm_tol = 99
- outlier_tol = None
- mag_lim = None
- ref_mag_lim = None
- trans_weights = 'both,var'
- n_boot = 15
-
- mag_trans = False
-
- # Run FLYSTAR, with bootstraps
- match1 = align.MosaicToRef(ref, [list1, list2], iters=N_loop, dr_tol=dr_tol,
- dm_tol=dm_tol, outlier_tol=outlier_tol,
- trans_class=transModel,
- trans_args=trans_args,
- mag_trans=mag_trans,
- mag_lim=mag_lim,
- ref_mag_lim=ref_mag_lim,
- trans_weights=trans_weights,
- default_motion_model='Fixed',
- use_ref_new=False,
- update_ref_orig=False,
- init_guess_mode='name',
- verbose=False)
-
- match1.fit()
- match1.calc_bootstrap_errors(n_boot=n_boot)
-
- # Make sure all transformations have mag_offset = 0
- trans_list = match1.trans_list
-
- for ii in trans_list:
- assert ii.mag_offset == 0
+ name = ['star_{0:03d}'.format(ii) for ii in range(N_stars)]
- # Check that no mag transformation has been applied to m col in ref_table
- tab1 = match1.ref_table
- assert np.all(tab1['m'] == tab1['m_orig'])
+ # Make an StarList
+ lis = starlists.StarList([name, m0, m0e,
+ x0, x0e, y0, y0e,
+ vx, vxe, vy, vye,
+ pi, pie,
+ t0],
+ names = ('name', 'm0', 'm0_err',
+ 'x0', 'x0_err', 'y0', 'y0_err',
+ 'vx', 'vx_err', 'vy', 'vy_err',
+ 'pi', 'pi_err',
+ 't0'))
- # Check me_boost == 0 or really small (should be the case
- # since we don't transform mags)
- assert np.isclose(np.max(tab1['me_boot']), 0, rtol=10**-5)
- print('Done mag_trans = False case')
-
- #---Align 2: self.mag_Trans = True---#
- # Repeat, this time with mag_trans = False
- mag_trans = True
- match2 = align.MosaicToRef(ref, [list1, list2], iters=N_loop, dr_tol=dr_tol,
- dm_tol=dm_tol, outlier_tol=outlier_tol,
- trans_class=transModel,
- trans_args=trans_args,
- mag_trans=mag_trans,
- mag_lim=mag_lim,
- ref_mag_lim=ref_mag_lim,
- trans_weights=trans_weights,
- default_motion_model='Fixed',
- use_ref_new=False,
- update_ref_orig=False,
- init_guess_mode='name',
- verbose=False)
-
- match2.fit()
- match2.calc_bootstrap_errors(n_boot=n_boot)
-
-
- # Make sure all transformations have correct mag offset
- trans_list2 = match2.trans_list
-
- for ii in trans_list2:
- assert ii.mag_offset > 20
+ sdx = np.argsort(m0)
+ lis = lis[sdx]
- # Make sure final table mags have transform applied (i.e,
- tab2 = match2.ref_table
- assert np.all(tab2['m'] != tab2['m_orig'])
+ # Save original positions as reference (1st) list
+ # in a StarList format (with velocities).
+ lis.write('random_par_ref.fits', overwrite=True)
- # Check me_boost > 0
- assert np.min(tab2['me_boot']) > 10**-3
-
- print('Done mag_trans = True case')
-
- return
-
-def test_MosaicToRef_mag_bug():
- """
- Bug found by Tuan Do on 2020-04-12.
- """
- make_fake_starlists_poly1_vel()
-
- ref_list = starlists.StarList.read('random_vel_0.fits')
- lists = [ref_list]
-
- msc = align.MosaicToRef(ref_list, lists,
- mag_trans=True,
- iters=1,
- dr_tol=[0.2], dm_tol=[1],
- outlier_tol=None,
- trans_class=transforms.PolyTransform,
- trans_args=[{'order': 1}],
- default_motion_model='Fixed',
- use_ref_new=False,
- update_ref_orig=False,
- verbose=True)
-
- msc.fit()
-
- out_tab = msc.ref_table
-
- # The issue is that in the initial guess with
- # mag_trans = True
- # somehow the transformed magnitudes are nan.
- # This causes zero matches to occur.
- assert len(out_tab) == len(ref_list)
-
- return
-
-def test_masked_cols():
- """
- Test to make sure analysis.prepare_gaia_for_flystar
- produces an astropy.table.Table, NOT a masked column
- table. MosaicToRef cannot handle masked column tables.
-
- Also make sure this example works, since we use it for the examples
- jupyter notebook.
- """
- # Get gaia reference stars using analysis.py
- # around a test location.
- target = 'ob150029'
- ra = '17:59:46.60'
- dec = '-28:38:41.8'
-
- # Coordinates are arcsecs offset +x to the East.
- targets_dict = {'ob150029': [0.0, 0.0],
- 'S005': [1.1416, 3.7405],
- 'S002': [-4.421, 0.027]
- }
-
- # Get gaia catalog stars. Note that this produces a masked column table
- search_rad = 10.0 # arcsec
- gaia = analysis.query_gaia(ra, dec, search_radius=search_rad)
- my_gaia = analysis.prepare_gaia_for_flystar(gaia, ra, dec, targets_dict=targets_dict)
-
- assert isinstance(my_gaia, Table)
+ ##########
+ # Propogate to new times and distort.
+ ##########
+ # Make 4 new starlists with different epochs and transformations.
+ '''times = [2018.5, 2019.5, 2020.5, 2021.5]
+ xy_trans = [[[ 6.5, 0.99, 1e-5], [ 10.1, 1e-5, 0.99]],
+ [[100.3, 0.98, 1e-5], [ 50.5, 9e-6, 1.001]],
+ [[ 0.0, 1.00, 0.0], [ 0.0, 0.0, 1.0]],
+ [[250.0, 0.97, 2e-5], [-250.0, 1e-5, 1.001]]]
+ mag_trans = [0.1, 0.4, 0.0, -0.3]'''
+
+ times = [2018.5, 2019.0, 2019.5, 2020.0, 2020.5, 2021.0, 2021.5, 2022.0]
+ xy_trans = [[[ 6.5, 0.99, 1e-5], [ 10.1, 1e-5, 0.99]],
+ [[100.3, 0.98, 1e-5], [ 50.5, 9e-6, 1.001]],
+ [[ 0.0, 1.00, 0.0], [ 0.0, 0.0, 1.0]],
+ [[250.0, 0.97, 2e-5], [-250.0, 1e-5, 1.001]],
+ [[ 50.0, 1.00, 0.0], [ -31.0, 0.0, 1.000]],
+ [[ 78.0, 1.00, 0.0 ], [ 45.0, 0.0, 1.00]],
+ [[-13.0, 1.00, 0.0], [ 150, 0.0, 1.00]],
+ [[ 94.0, 1.00, 0.0], [-182.0, 0.0, 1.00]]]
+ mag_trans = [0.1, 0.4, 0.0, -0.3, 0.0, 0.0, 0.0, 0.0]
- # Let's make sure the entire align runs, just to be safe
+ # Convert into pixels (undistorted) with the following info.
+ scale = 0.01 # arcsec / pix
+ shift = [1.0, 1.0] # pix
- # Get starlists to align to gaia
- epochs = ['15jun07','16jul14', '17may21']
+ for ss in range(len(times)):
+ dt = times[ss] - lis['t0']
+
+ par_mod = motion_model.Parallax(pa=0,ra=18.0, dec=-30.0)
+ par_mod_dat = par_mod.get_batch_pos_at_time(dt+lis['t0'], x0=lis['x0'],vx=lis['vx']/1e3, pi=lis['pi'],
+ y0=lis['y0'], vy=lis['vy']/1e3, t0=lis['t0'])
+ x,y = par_mod_dat[0], par_mod_dat[1]
+ t = np.ones(N_stars) * times[ss]
- list_of_starlists = []
+ # Convert into pixels
+ xp = (x / -scale) + shift[0] # -1 from switching to increasing to West (right)
+ yp = (y / scale) + shift[1]
+ xpe = lis['x0_err'] / scale
+ ype = lis['y0_err'] / scale
- for ee in range(len(epochs)):
- lis_file = 'mag' + epochs[ee] + '_ob150029_kp_rms_named.lis'
- lis = starlists.StarList.from_lis_file(lis_file)
-
- list_of_starlists.append(lis)
+ # Distort the positions
+ trans = transforms.PolyTransform(1, xy_trans[ss][0], xy_trans[ss][1], mag_offset=mag_trans[ss])
+ xd, yd = trans.evaluate(xp, yp)
+ md = trans.evaluate_mag(lis['m0'])
- # Run the align
- msc = align.MosaicToRef(my_gaia, list_of_starlists, iters=2,
- dr_tol=[0.2, 0.1], dm_tol=[1, 1],
- trans_class=transforms.PolyTransform,
- trans_args=[{'order': 1}, {'order': 1}],
- default_motion_model='Linear',
- use_ref_new=False,
- update_ref_orig=False,
- mag_trans=True,
- init_guess_mode='name', verbose=True)
+ # Perturb with small errors (0.1 pix)
+ xd += np.random.randn(N_stars) * 0.1
+ yd += np.random.randn(N_stars) * 0.1
+ md += np.random.randn(N_stars) * 0.02
+ xde = xpe
+ yde = ype
+ mde = lis['m0_err']
- msc.fit()
+ # Save the new list as a starlist.
+ new_lis = starlists.StarList([lis['name'], md, mde, xd, xde, yd, yde, t],
+ names=('name', 'm', 'me', 'x', 'xe', 'y', 'ye', 't'))
- return
+ new_lis.write('random_par_{0:d}.fits'.format(ss), overwrite=True)
+
+ return (xy_trans, mag_trans)
\ No newline at end of file
diff --git a/flystar/tests/test_all_detected.fits b/flystar/tests/test_all_detected.fits
deleted file mode 100644
index ae56198..0000000
--- a/flystar/tests/test_all_detected.fits
+++ /dev/null
@@ -1,2911 +0,0 @@
-SIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions EXTEND = T END XTENSION= 'BINTABLE' / binary table extension BITPIX = 8 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 632 / length of dimension 1 NAXIS2 = 2000 / length of dimension 2 PCOUNT = 0 / number of group parameters GCOUNT = 1 / number of groups TFIELDS = 21 / number of table fields TTYPE1 = 'name ' TFORM1 = 'K ' TTYPE2 = 'x ' TFORM2 = '12D ' TDIM2 = '(2,6) ' TTYPE3 = 'y ' TFORM3 = '12D ' TDIM3 = '(2,6) ' TTYPE4 = 'm ' TFORM4 = '12D ' TDIM4 = '(2,6) ' TTYPE5 = 'xe ' TFORM5 = '6D ' TDIM5 = '(6) ' TTYPE6 = 'ye ' TFORM6 = '6D ' TDIM6 = '(6) ' TTYPE7 = 'me ' TFORM7 = '6D ' TDIM7 = '(6) ' TTYPE8 = 'n ' TFORM8 = '6D ' TDIM8 = '(6) ' TTYPE9 = 'det ' TFORM9 = '6D ' TDIM9 = '(6) ' TTYPE10 = 'vx ' TFORM10 = 'D ' TTYPE11 = 'vy ' TFORM11 = 'D ' TTYPE12 = 'vxe ' TFORM12 = 'D ' TTYPE13 = 'vye ' TFORM13 = 'D ' TTYPE14 = 'x0 ' TFORM14 = 'D ' TTYPE15 = 'y0 ' TFORM15 = 'D ' TTYPE16 = 'x0e ' TFORM16 = 'D ' TTYPE17 = 'y0e ' TFORM17 = 'D ' TTYPE18 = 'chi2_vx ' TFORM18 = 'D ' TTYPE19 = 'chi2_vy ' TFORM19 = 'D ' TTYPE20 = 't0 ' TFORM20 = 'D ' TTYPE21 = 'n_vfit ' TFORM21 = 'D ' EPNAMES = '2005_F814W_F1' EPNAMES = '2010_F125W_F3' EPNAMES = '2010_F139M_F2' EPNAMES = '2010_F160W_F1' EPNAMES = '2013_F160W_F1' EPNAMES = '2015_F160W_F1' ZPOINTS = 32.6783 ZPOINTS = 25.2305 ZPOINTS = 23.2835 ZPOINTS = 24.5698 ZPOINTS = 24.5698 ZPOINTS = 24.5698 YEARS = 2005.485 YEARS = 2010.652 YEARS = 2010.652 YEARS = 2010.652 YEARS = 2013.199 YEARS = 2015.148 HIERARCH DATE PRODUCED = '2025-06-30' HIERARCH INSTRUMENT = 'ACSWFC ' HIERARCH INSTRUMENT = 'WFC3IR ' HIERARCH INSTRUMENT = 'WFC3IR ' HIERARCH INSTRUMENT = 'WFC3IR ' HIERARCH INSTRUMENT = 'WFC3IR ' HIERARCH INSTRUMENT = 'WFC3IR ' END @
1&y@
c+(@
1&y@4U*@
1&y@OS@
1&y@ŕ@
1&y@
!@
1&y@]H/@nzG@ns2ph@nzG@n:t@nzG@mI@nzG@mm@nzG@nb3@nzG@ns@8䎊@8m1@4S@3!d@3~"@3Q@䩤@2@2h4Z@2@2ĊRd@2@2&EK?hjaQ?*?iy?Û?
-Ld?OU=6i?/nI|??`l??!g?'?χ1?# ?jo?/O?ޥe?.Eôv?[\@ @" @ @" @4 @. ? ? ? ? ? ? ?Ek ?mo ?zS ?T8O@@n?/??Cs?9wZe`?3#@溦z@k%>@ @`ě@\1'@`ě@Q4K@`ě@Mw1@`ě@G@`ě@:6@`ě@4j~@ۊ=p@ێV@ۊ=p@{lD@ۊ=p@۞Q@ۊ=p@ہTɅ@ۊ=p@ۙb@ۊ=p@cA@6=:@6:)^@4hr@4SMj@3`A@3\(@3._o @3:L/|@3._o @3BC,@3._o @3G?Ol?.5?{?d`Xp?͵?>;?
?>%?:?Җhn?|9.)?@~?
-B?7ly\?J鞤?Jf?8? J6Л@ @ @ @ @, @( ? ? ? ? ? ? C &Ԡ ?*2iۂA?Y領~@OûZ@یc?D?tN'p?{Q(?@bn{@ @+. @+. @+. @+. @+@٦@+@ k@(6E. @(6E. @(6E. @(6E. @(6E@)Q@(6E@!p<@8s.>@4S.Mm@3`A7.Qn@2YJ.NC,@2YJ@2>@2YJ@1E2a|@8 J@8 #@8 :@8 >+?BxT?g{=@8 J@8 @8 i@8 ?VYk?Պu@8 p@8
*@8 p@8 ?Z?\ @ @ ? ? @zG@w@zG@rGF@zG@s@zG@=b@zG@*0@zG@X@շKƧ@ռ(@շKƧ@7@շKƧ@շX@շKƧ@շ@շKƧ@նz@շKƧ@ո}H@8g l@8\N@4hr @4&@4"-V@4*͞&@3B@5@3GKƧ@3B@5@3G@3B@5@3H9Xb?q!U?+W?](s?A2x?wX?>V$?TU?[G,?ҌI?,#t?s?|[z?ӖO_?[
S? e?Za7?Us?DΊ@ @ @ @ @* @( ? ? ? ? ? ? ?VM Bx ?QԬy!?Bex.@W.V@ոAA?nɢf?[~?u?+\t@oF5i@ @EQ@9R4@EQ@G2@EQ@?'-9@EQ@DqN@EQ@D@EQ@FW@/j~#@/,l@/j~#@/i3ߢ@/j~#@/qjK>h@/j~#@/fX@/j~#@/m*@/j~#@/uA@8g l@8u@2r Ĝ@2QU|@2gKƧ@2l76@1&@1"@1&@1[@1&@1} t?ڢ??b r}?N[x?},A? J?P*i?6 k?ZU?1O}?=е?zpY?i?V0qRi?@&pp??~?zA?Ad`@ @ @&