Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fit arbitrary abs astrom #356

Merged
merged 39 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
9cd9913
lint (sorry jason)
sblunt Nov 10, 2023
66286a7
add ability to fit type 1 hipparcos sols
sblunt Nov 10, 2023
b409eb0
lint
sblunt Nov 13, 2023
4f07507
separate out model computation in hipparcos.py
sblunt Nov 13, 2023
79bf112
lint
sblunt Nov 13, 2023
48c8cdb
lint
sblunt Nov 13, 2023
b51f416
fix bug introduced with type 1 sols
sblunt Nov 13, 2023
a34a834
another api type 1 bug fixed
sblunt Nov 13, 2023
73e18cb
lint
sblunt Nov 13, 2023
f0eff4f
bugfix to get hipparcos fits working again
sblunt Nov 13, 2023
b99ce71
messed up too much; abort
sblunt Nov 13, 2023
6222680
separate plx/pm prediction from hipparcos into separate class
sblunt Nov 20, 2023
5382c80
untested full implementation
sblunt Nov 20, 2023
9f0cb08
linting
sblunt Nov 21, 2023
0950f63
bugfixes
sblunt Nov 21, 2023
eebe42e
fits running
sblunt Nov 21, 2023
fc50ccf
bugfix for type 1 solution
sblunt Nov 27, 2023
1267f61
add back in var term for type 1 solutions refitting test
sblunt Nov 27, 2023
6a38833
formatting
sblunt Dec 27, 2023
e1aae01
update label on corner plot to me mu_alpha*
sblunt Dec 27, 2023
2e54a39
pep8
sblunt Dec 30, 2023
ee5720e
remove unused imports
sblunt Dec 30, 2023
3b1d84e
pep8
sblunt Dec 30, 2023
0f19a50
Merge branch 'hcga' into fit-arbitrary-abs-astrom
sblunt Jan 19, 2024
0e30855
fix bug causing unit test failures
sblunt Jan 30, 2024
d4c20b4
add test that type 1 hipparcos sols pass
sblunt Jan 30, 2024
3b8a628
add test of pm calculation
sblunt Jan 30, 2024
ee0e7e7
add plx test for arbitrary abs astrom
sblunt Jan 30, 2024
e20eaf4
remove unused import
sblunt Jan 30, 2024
98148b7
fix cos(delta) bug
sblunt Feb 9, 2024
bffd022
add abs astrometry tutorial
sblunt Mar 13, 2024
7dfe1c4
fix bug with loading hipparcos iad from saved run
sblunt Mar 18, 2024
44c9755
Revert "fix bug with loading hipparcos iad from saved run"
sblunt Mar 18, 2024
822b501
Revert "Revert "fix bug with loading hipparcos iad from saved run""
sblunt Mar 18, 2024
1739d5b
fix bug with hipparcos IAD objects loaded from saved file
sblunt Mar 18, 2024
bf81c75
delete rogue print stmt
sblunt Mar 18, 2024
b80e899
fix test bug causing test_abs_astrom test to fail
sblunt Mar 29, 2024
8c0ca9e
Merge branch 'obs-priors' into fit-arbitrary-abs-astrom
sblunt Apr 11, 2024
436a866
add last two v3 changes to changelog!
sblunt Apr 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ User Guide:
Changelog:
++++++++++

**3.0.0 (TBD)**
**3.0.0 (2024-4-11)**

- implementation of Hipparcos-Gaia catalog of accelerations fitting! (@semaphoreP)
- fit arbitrary absolute astrometry (@sblunt)
- implement O'Neil observation-based priors (@sblunt/@clarissardoo)
- discuss MCMC autocorrelation in MCMC tutorial (@michaelkmpoon)
- add time warning if OFTI doesn't accept an orbit in first 60 s (@michaelkmpoon)
- add first parts of orbitize! manual (@sofiacovarrubias/@sblunt)
- bugfix for rebound MCMC fits (issue #357; @sblunt)
- implementation of Hipparcos-Gaia catalog of accelerations fitting! (@semaphoreP)
- implementation of residual plotting method for orbit plots (@Saanikachoudhary and @semaphoreP)
- plot companion RVs (@chihchunhsu)
- add documentation about referencing issues when modifying priors to tutorial (@wcroberson)
Expand Down
1 change: 1 addition & 0 deletions docs/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ us if you are still confused).
tutorials/Changing_bases_tutorial.ipynb
tutorials/Hipparcos_IAD.ipynb
tutorials/HGCA_tutorial.ipynb
tutorials/abs_astrometry.ipynb



8 changes: 2 additions & 6 deletions docs/tutorials/Hipparcos_IAD.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,14 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Go get a coffee. This will take a few mins! :)\n",
"Starting burn-in!\n",
"Starting production chain!\n",
"Done! This fit took 3.1 mins on my machine.\n"
"Go get a coffee. This will take a few mins! :)\n"
]
},
{
Expand Down Expand Up @@ -4281,7 +4278,6 @@
"# although I'd probably run it for 5,000-10,000 steps if I wanted to publish it.\n",
"burn_steps = 100\n",
"mcmc_steps = 100\n",
"\n",
"start = datetime.now()\n",
"\n",
"# run the fit\n",
Expand Down
275 changes: 275 additions & 0 deletions docs/tutorials/abs_astrometry.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Fitting Arbitrary Absolute Astrometry\n",
"\n",
"by Sarah Blunt (2023)\n",
"\n",
"This tutorial walks you through using orbitize! to perform a fit on arbitary absolute astrometry. By \"arbitrary,\" I mean astrometry not taken by Gaia or Hipparcos (which orbitize! has dedicated modules for; see the HGCA and [Hipparcos IAD tutorials](https://orbitize.readthedocs.io/en/latest/tutorials/Hipparcos_IAD.html)). Let's imagine we have astrometry for a single star derived from wide-field images taken over several years, and we want to combine these data with measurements from Hipparcos. We are going to perform a fit to jointly constrain astrometric parameters (parallax and proper motion) and orbital parameters of a secondary companion. \n",
"\n",
"This tutorial will take you through:\n",
"- formatting absolute astrometry measurements for input into orbitize!\n",
"- setting up an orbit fit incorporating these measurements\n",
"\n",
"This tutorial assumes the following prerequities:\n",
"- [Using the Hipparcos IAD](https://orbitize.readthedocs.io/en/latest/tutorials/Hipparcos_IAD.html)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Input Data Format\n",
"\n",
"Following Nielsen et al 2020 (see the Hipparcos IAD tutorial), orbitize! defines astrometric data points as offset from the *reported Hipparcos position* at the *reported Hipparcos epoch*. Let's start by defining an `orbitize.hipparcos.Hipparcos` object, which holds onto information from the Hipparcos mission observations of our object of interest. I'm going to use beta Pictoris as an example since you already have that IAD file in your orbitize! distribution. See the [IAD tutorial](https://orbitize.readthedocs.io/en/latest/tutorials/Hipparcos_IAD.html) for info on how to download the data for your object."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from orbitize import hipparcos, DATADIR\n",
"\n",
"hip_num = \"027321\" # beta Pic\n",
"\n",
"# Location of the Hipparcos IAD file.\n",
"IAD_file = \"{}H{}.d\".format(DATADIR, hip_num)\n",
"\n",
"# The HipparcosLogProb object needs to know how many companions are in your fit\n",
"# in order to compute likelihood. There are 2 known planets around beta Pic, but let's\n",
"# keep it simple for the tutorial\n",
"num_secondary_bodies = 1\n",
"\n",
"betaPicHipObject = hipparcos.HipparcosLogProb(IAD_file, hip_num, num_secondary_bodies)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Generally, when you're deriving (or using published) absolute astrometry, it will be in the form 82 02 14.35787 (J2000). However, `orbitize!` expects astrometry to be input *relative* to the Hipparcos position. Our friends at `astropy` have made these calculations very easy to do! Here's an example:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 377.81305615 1425.17609269] [1044.81957171 933.70290544]\n"
]
}
],
"source": [
"from astropy.coordinates import SkyCoord\n",
"from astropy import units as u\n",
"import numpy as np\n",
"\n",
"# let's imagine our data look like this:\n",
"datapoints = [\"05 47 17.123456 -51 03 59.123456\", \"05 47 17.234567 -51 03 59.234567\"]\n",
"data_epochs = [\"2020.1234\", \"2020.2345\"]\n",
"num_datapoints = len(datapoints)\n",
"\n",
"hipparcos_coordinate = SkyCoord(\n",
" betaPicHipObject.alpha0, betaPicHipObject.delta0, unit=(u.deg, u.deg)\n",
")\n",
"\n",
"raoffs = np.zeros(num_datapoints)\n",
"deoffs = np.zeros(num_datapoints)\n",
"for i in range(num_datapoints):\n",
" my_data_coordinate = SkyCoord(datapoints[i], unit=(u.hourangle, u.deg))\n",
"\n",
" # take difference between reported Hipparcos position and convert to mas\n",
" raoff, deoff = hipparcos_coordinate.spherical_offsets_to(my_data_coordinate)\n",
"\n",
" # n.b. orbitize! expects raw ra offsets, NOT multiplied by cos(delta0). Don't\n",
" # multiply by cos(delta0) here.\n",
" raoffs[i] = raoff.to(u.mas).value\n",
" deoffs[i] = deoff.to(u.mas).value\n",
"\n",
"print(raoffs, deoffs)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sweet! These absolute astrometry points are now suitable for an orbitize! input file. You can add them to an existing file with other types of data (relative astrometry and RVs) and/or fit them on their own. Here's what the data file for our two points would look like:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>epoch</th>\n",
" <th>object</th>\n",
" <th>raoff</th>\n",
" <th>deoff</th>\n",
" <th>deoff_err</th>\n",
" <th>raoff_err</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>58894.1644</td>\n",
" <td>0</td>\n",
" <td>377.813056</td>\n",
" <td>1044.819572</td>\n",
" <td>123.4</td>\n",
" <td>123.4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>58934.8270</td>\n",
" <td>0</td>\n",
" <td>1425.176093</td>\n",
" <td>933.702905</td>\n",
" <td>123.4</td>\n",
" <td>123.4</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" epoch object raoff deoff deoff_err raoff_err\n",
"0 58894.1644 0 377.813056 1044.819572 123.4 123.4\n",
"1 58934.8270 0 1425.176093 933.702905 123.4 123.4"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from pandas import DataFrame\n",
"from astropy.time import Time\n",
"\n",
"df_orbitize = DataFrame(Time(data_epochs, format=\"decimalyear\").mjd, columns=[\"epoch\"])\n",
"\n",
"# this line tells orbitize! \"these measurements are astrometry of the primary\"\n",
"df_orbitize[\"object\"] = 0\n",
"\n",
"df_orbitize[\"raoff\"] = raoffs\n",
"df_orbitize[\"deoff\"] = deoffs\n",
"\n",
"df_orbitize[\"deoff_err\"] = 123.4 # error on the declination measurement, in mas\n",
"df_orbitize[\"raoff_err\"] = 123.4 # error on the RA measurement, in mas\n",
"\n",
"df_orbitize.to_csv(\"data_for_orbit_fit.csv\", index=False)\n",
"df_orbitize"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Setting up & Running Your Fit\n",
"\n",
"The hard part is over-- we have formatted our input data! `orbitize!` will now function the same as any other fit. Behind the scenes, `orbitize!` will automatically recognize that you have inputted absolute astrometry, and set up a fit that includes position, parallax, and proper motion terms as free parameters. Observe:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from orbitize import read_input, system, priors, sampler\n",
"import os\n",
"\n",
"data_table = read_input.read_file(\"data_for_orbit_fit.csv\")\n",
"\n",
"fit_secondary_mass = True # tell orbitize! we want to get dynamical masses\n",
"m0 = 1\n",
"plx = 1\n",
"\n",
"# this sets up a joint fit of Hipparcos time series data and the absolute astrometry\n",
"# from the data table we just created.\n",
"betaPicSystem = system.System(\n",
" num_secondary_bodies,\n",
" data_table,\n",
" m0,\n",
" plx,\n",
" hipparcos_IAD=betaPicHipObject,\n",
" fit_secondary_mass=fit_secondary_mass,\n",
")\n",
"\n",
"# change any priors you want to:\n",
"plx_idx = betaPicSystem.param_idx[\"plx\"]\n",
"betaPicSystem.sys_priors[plx_idx] = priors.UniformPrior(10, 15)\n",
"\n",
"# run the fit!\n",
"tutorialSampler = sampler.MCMC(betaPicSystem)\n",
"# tutorialSampler.run_sampler(you_choose, burn_steps=you_choose)\n",
"\n",
"# clean up\n",
"os.system(\"rm data_for_orbit_fit.csv\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "python3.12",
"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.12.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading
Loading