flystar.motion_model

Attributes

Classes

Acceleration

A 2D accelerating motion model for a star on the sky.

Empty

Helper class that provides a standard way to create an ABC using

Fixed

A non-moving motion model for a star on the sky.

Linear

A 2D linear motion model for a star on the sky.

MotionModel

Helper class that provides a standard way to create an ABC using

Orbit

Newtonian orbit. Fixed or fit is chosen per star, not here.

Parallax

Motion model for linear proper motion + parallax

Functions

all_motion_model_param_names([with_errors, with_fixed])

Get all motion model parameter names from all available MotionModels.

broadcast_times(t, n_stars[, caller])

Normalize a time argument into an explicit (n_stars, n_times) grid.

determine_motion_models(startable[, motion_models, ...])

Determine, per star, which motion model to use.

frozen_motion_mask(table)

Stars that must not be refit.

motion_model_map()

Get a dictionary mapping motion model names to MotionModel classes.

motion_model_param_names(motion_models[, with_errors, ...])

Get the motion model parameter names from a list of MotionModels.

organize_motion_models(motion_models)

Organize a list of motion models of type str or MotionModel into a list of MotionModel classes,

sigma_from_error(xe, ye[, weighting])

Convert x/y position errors into the sigma values a weighted fit

weight_from_sigma(sigma[, valid])

Convert an uncertainty (sigma) array into a safe inverse-variance

Module Contents

class flystar.motion_model.Acceleration[source]

Bases: MotionModel

A 2D accelerating motion model for a star on the sky.

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 type:

None

Notes

fixed_params_dict starts as None. A single-star fit stores the fixed parameters it used there, so a later get_predicted_positions(t, params) call without its own fixed_params_dict can fall back to them.

get_predicted_positions(t, fit_params, fit_param_errs=None, fixed_params_dict=None)[source]

Model positions (and uncertainties, if fit_param_errs is provided) at time t of Acceleration model.

Parameters:
  • t (scalar or array-like) – Time(s) in decimal years. Shape rules are in MotionModel.get_predicted_positions() / broadcast_times().

  • fit_params (array-like) – x0, vx, ax, y0, vy, ay in shape (N_fit_params,) or (N_stars, N_fit_params)

  • fit_param_errs (array-like, optional) – Fit parameter uncertainties with shape (N_stars, N_fit_params) or (N_fit_params,), by default None

  • fixed_params_dict (dict, optional) – t0, shape (1,) or (N_stars,). Falls back to the fixed parameters stored by the last single-star fit, by default None.

Returns:

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

Return type:

x, y (, xe, ye)

run_fit(t, x, y, xe, ye, valid, fixed_params_dict=None, params_init_guess_dict=None, weighting='var', absolute_sigma=True, fill_value=np.nan, verbose=True)[source]

Batch fit for many stars at once. Acceleration’s model (x0 + vx0*dt + 0.5*ax*dt**2) is linear in its fit parameters despite being quadratic in time, so its weighted least-squares fit is closed-form too – same situation as Linear, just with a 3-parameter (instead of 2-parameter) basis [1, dt, 0.5*dt**2] per direction. Unlike Linear, this solves the 3x3 normal-equations system with a batched np.linalg.inv rather than a hand-derived closed-form adjugate – deriving that by hand for a 3x3 system is error-prone for little extra speed over LAPACK’s own (also closed-form, non-iterative) solver.

Parameters:
  • t (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • x (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • y (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • xe (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • ye (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • valid (array-like of bool, shape (n_stars, n_epochs)) – Which entries are usable for each star.

  • fixed_params_dict (dict, optional) – Must contain ‘t0’, either a scalar or shape (n_stars,), by default None.

  • weighting (str, optional) – ‘var’ (w=1/xe**2, 1/ye**2) or ‘std’ (w=1/xe, 1/ye), by default ‘var’

  • absolute_sigma (bool, optional) – If False, parameter errors are rescaled by the reduced chi^2, by default True

  • fill_value (float, optional) – Fill value for parameters when not enough data points to fit model, by default np.nan

  • verbose (bool, optional) – Print warning messages, by default True

Returns:

  • params (ndarray, shape (n_stars, 6) – [x0, vx0, ax, y0, vy0, ay])

  • param_errs (ndarray, shape (n_stars, 6))

  • chi2_x, chi2_y (ndarray, shape (n_stars,))

fit_param_names = ['x0', 'vx0', 'ax', 'y0', 'vy0', 'ay'][source]
fixed_param_names = ['t0'][source]
n_fit_params = 6[source]
n_params = 0[source]
name = 'Acceleration'[source]
optional_fixed_params[source]
required_fixed_param_names = ['t0'][source]
class flystar.motion_model.Empty(**kwargs)[source]

Bases: MotionModel

Helper class that provides a standard way to create an ABC using inheritance.

Empty motion model, returns nan for values and inf for uncertainties.

get_predicted_positions(t, fit_params, fit_param_errs=None, fixed_params_dict=None)[source]

Predicted positions (and uncertainties, if fit_param_errs is provided) at time t of Empty model.

Parameters:
  • t (scalar or array-like) – Time(s) in decimal years. Shape rules are in MotionModel.get_predicted_positions() / broadcast_times().

  • fit_params (array-like) – Fit parameters, shape (N_fit_params,) or (N_stars, N_fit_params)

  • fit_param_errs (array-like, optional) – Uncertainties for fit parameters, not applicable for Empty model, by default None

  • fixed_params_dict (dict, optional) – Not applicable for Empty model, by default None

Returns:

Predicted position (and uncertainties) of Empty model, shape (N_times,)

Return type:

x, y (, xe, ye)

run_fit(t, x, y, xe, ye, valid, fixed_params_dict=None, params_init_guess_dict=None, weighting='var', absolute_sigma=True, fill_value=np.nan, verbose=True)[source]

Batch fit for many stars at once. Empty’s “fit” never looks at any data – it’s always fill_value/inf regardless of what’s passed in – so there’s no actual computation to batch. This exists purely so that a table containing some Empty stars (there is almost always at least a handful, e.g. stars with 0 valid epochs) doesn’t force the caller to spin up a multiprocessing pool – and pay its real, fixed per-worker spawn cost – just to run this trivial, zero-cost case one star at a time.

Parameters:
  • t (array-like, shape (n_stars, n_epochs)) – Unused – accepted only for interface consistency with other motion models’ run_fit.

  • x (array-like, shape (n_stars, n_epochs)) – Unused – accepted only for interface consistency with other motion models’ run_fit.

  • y (array-like, shape (n_stars, n_epochs)) – Unused – accepted only for interface consistency with other motion models’ run_fit.

  • xe (array-like, shape (n_stars, n_epochs)) – Unused – accepted only for interface consistency with other motion models’ run_fit.

  • ye (array-like, shape (n_stars, n_epochs)) – Unused – accepted only for interface consistency with other motion models’ run_fit.

  • valid (array-like, shape (n_stars, n_epochs)) – Unused – accepted only for interface consistency with other motion models’ run_fit.

  • fixed_params_dict (unused.)

  • weighting (unused.)

  • absolute_sigma (unused.)

  • fill_value (float, optional) – Fill value for parameters when not enough data points to fit model, by default np.nan

  • verbose (bool, optional) – Print warning messages, by default True

Returns:

  • params (ndarray, shape (n_stars, 0))

  • param_errs (ndarray, shape (n_stars, 0))

  • chi2_x, chi2_y (ndarray, shape (n_stars,), all nan)

fit_param_names = [][source]
fixed_param_names = [][source]
n_fit_params = 0[source]
n_params = 0[source]
name = 'Empty'[source]
optional_fixed_params[source]
required_fixed_param_names = [][source]
class flystar.motion_model.Fixed(**kwargs)[source]

Bases: MotionModel

A non-moving motion model for a star on the sky.

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 type:

None

Notes

fixed_params_dict starts as None. A single-star fit stores the fixed parameters it used there, so a later get_predicted_positions(t, params) call without its own fixed_params_dict can fall back to them.

get_predicted_positions(t, fit_params, fit_param_errs=None, fixed_params_dict=None)[source]

Predicted positions (and uncertainties, if fit_param_errs is provided) at time t of Fixed model.

Parameters:
  • t (scalar or array-like) – Time(s) in decimal years. Shape rules are in MotionModel.get_predicted_positions() / broadcast_times().

  • fit_params (array-like) – x0, y0 in shape (N_fit_params,) or (N_stars, N_fit_params)

  • fit_param_errs (array-like, optional) – Uncertainties for x0, y0 in shape (N_fit_params,) or (N_stars, N_fit_params), by default None

  • fixed_params_dict (dict, optional) – Not applicable for Fixed, by default None

Returns:

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

Return type:

x, y (, xe, ye)

run_fit(t, x, y, xe, ye, valid, fixed_params_dict=None, params_init_guess_dict=None, weighting='var', absolute_sigma=True, fill_value=np.nan, verbose=True)[source]

Batch fit for many stars at once. Fixed’s fit is closed-form (a weighted average – no iterative optimizer), so nothing about it actually requires fitting one star at a time; this fits the whole batch in one pass instead of looping (or spinning up multiprocessing for) each star individually.

Parameters:
  • t (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • x (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • y (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • xe (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • ye (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • valid (array-like of bool, shape (n_stars, n_epochs)) – Which entries are usable for each star.

  • fixed_params_dict (dict, optional) – Unused – Fixed has no fixed params – accepted only so callers can call run_fit() uniformly across motion models (e.g. Linear requires fixed_params_dict={‘t0’: …}), by default None.

  • weighting (str, optional) – ‘var’ (w=1/xe**2, 1/ye**2) or ‘std’ (w=1/xe, 1/ye), by default ‘var’

  • absolute_sigma (bool, optional) – If False, parameter errors are rescaled by the reduced chi^2, by default True

  • fill_value (float, optional) – Fill value for parameters when not enough data points to fit model, by default np.nan

  • verbose (bool, optional) – Print warning messages, by default True

Returns:

  • params (ndarray, shape (n_stars, 2))

  • param_errs (ndarray, shape (n_stars, 2))

  • chi2_x, chi2_y (ndarray, shape (n_stars,))

fit_param_names = ['x0', 'y0'][source]
fixed_param_names = [][source]
n_fit_params = 2[source]
n_params = 0[source]
name = 'Fixed'[source]
optional_fixed_params[source]
required_fixed_param_names = [][source]
class flystar.motion_model.Linear(**kwargs)[source]

Bases: MotionModel

A 2D linear motion model for a star on the sky.

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 type:

None

Notes

fixed_params_dict starts as None. A single-star fit stores the fixed parameters it used there, so a later get_predicted_positions(t, params) call without its own fixed_params_dict can fall back to them.

get_predicted_positions(t, fit_params, fit_param_errs=None, fixed_params_dict=None)[source]

Model positions (and uncertainties, if fit_param_errs is provided) at time t of Linear model.

Parameters:
  • t (scalar or array-like) – Time(s) in decimal years. Shape rules are in MotionModel.get_predicted_positions() / broadcast_times().

  • fit_params (array-like) – x0, vx, y0, vy in shape (N_fit_params,) or (N_stars, N_fit_params)

  • fit_param_errs (array-like, optional) – Uncertainties of fit parameters in shape (N_fit_params,) or (N_stars, N_fit_params), by default None

  • fixed_params_dict (dict, optional) – t0, shape (1,) or (N_stars,). Falls back to the fixed parameters stored by the last single-star fit, by default None.

Returns:

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

Return type:

x, y (, xe, ye)

run_fit(t, x, y, xe, ye, valid, fixed_params_dict=None, params_init_guess_dict=None, weighting='var', absolute_sigma=True, fill_value=np.nan, verbose=True)[source]

Batch fit for many stars at once. Linear’s weighted least-squares fit is closed-form (the normal equations, no iterative optimizer) – so, like Fixed, it doesn’t actually need to run one star at a time. Rather than building a full (n_epochs, n_epochs) diagonal weight matrix and calling np.linalg.pinv/matrix_rank (SVD-based) per star – wasteful work for what’s always exactly a 2x2 system – this computes the five weighted sums the 2x2 normal-equations matrix needs via vectorized .sum(axis=1) calls across the whole batch, and solves/inverts that 2x2 system with its closed-form (adjugate-over-determinant) formula.

Parameters:
  • t (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • x (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • y (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • xe (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • ye (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs).

  • valid (array-like of bool, shape (n_stars, n_epochs)) – Which entries are usable for each star.

  • fixed_params_dict (dict, optional) – Must contain ‘t0’, either a scalar or shape (n_stars,), by default None.

  • weighting (str, optional) – ‘var’ (w=1/xe**2, 1/ye**2) or ‘std’ (w=1/xe, 1/ye), by default ‘var’

  • absolute_sigma (bool, optional) – If False, parameter errors are rescaled by the reduced chi^2, by default True

  • fill_value (float, optional) – Fill value for parameters when not enough data points to fit model, by default np.nan

  • verbose (bool, optional) – Print warning messages, by default True

Returns:

  • params (ndarray, shape (n_stars, 4) – [x0, vx, y0, vy])

  • param_errs (ndarray, shape (n_stars, 4))

  • chi2_x, chi2_y (ndarray, shape (n_stars,))

fit_param_names = ['x0', 'vx', 'y0', 'vy'][source]
fixed_param_names = ['t0'][source]
n_fit_params = 4[source]
n_params = 0[source]
name = 'Linear'[source]
optional_fixed_params[source]
required_fixed_param_names = ['t0'][source]
class flystar.motion_model.MotionModel(*args, **kwargs)[source]

Bases: abc.ABC

Helper class that provides a standard way to create an ABC using inheritance.

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 type:

None

Notes

fixed_params_dict starts as None. A single-star fit stores the fixed parameters it used there, so a later get_predicted_positions(t, params) call without its own fixed_params_dict can fall back to them.

calc_chi2(t, x, y, xe, ye, fit_params, fixed_params_dict=None, reduced=False, parallax=False)[source]

Get the chi^2 value for the input motion model parameters and data.

Parameters:
  • t (array-like, shape (N_times,)) – One star’s times, positions, and position uncertainties.

  • x (array-like, shape (N_times,)) – One star’s times, positions, and position uncertainties.

  • y (array-like, shape (N_times,)) – One star’s times, positions, and position uncertainties.

  • xe (array-like, shape (N_times,)) – One star’s times, positions, and position uncertainties.

  • ye (array-like, shape (N_times,)) – One star’s times, positions, and position uncertainties.

  • fit_params (array-like, shape (N_fit_params,)) – Motion model parameters, ordered as in fit_param_names.

  • fixed_params_dict (dict, optional) – Fixed (non-fit) parameters, by default None.

  • reduced (bool, optional) – Divide by the degrees of freedom, by default False.

  • parallax (bool, optional) – Count degrees of freedom jointly over x and y, as for the Parallax model, by default False.

Returns:

chi2x, chi2y – Chi^2 (or reduced chi^2) in each direction.

Return type:

float

fit(t, x, y, xe, ye, fixed_params_dict=None, params_init_guess_dict=None, weighting='var', absolute_sigma=True, fill_value=np.nan, return_chi2=False, bootstrap=0, seed=None, verbose=True)[source]

Fit stellar motion parameters – for one star, or for a whole batch of stars at once.

t, x, y, xe, ye1D, shape (n_epochs,)

A single star’s data. The caller is expected to have already filtered this down to that star’s own real epochs – no padding, nothing to mask.

t, x, y, xe, ye2D, shape (n_stars, n_epochs)

A batch of many stars packed into one rectangular array (this is the path StarTable.fit_motion_models uses for real performance – run_fit is never called directly from outside this module). Since stars don’t all have the same number of real epochs, some cells are padding; padding is marked by nan in x and/or y (this codebase’s existing “no data” convention), not by a separate mask the caller has to build. valid = isfinite(x) & isfinite(y) is derived here and handed to run_fit(), which does the actual (closed-form, vectorized) solve for the whole batch in one call.

Every concrete model’s run_fit is closed-form, except Orbit, which loops over stars inside run_fit and calls a nonlinear solver. The single-star case wraps the star’s data into a batch of one row (and, for bootstrap, into a batch of bootstrap rows – one resampled subset/order of this star’s epochs per row). Orbit may append a diagnostics dict as a fifth return value. Callers that unpack four names should slice result[:4].

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’

  • absolute_sigma (bool, optional) – Absolute sigma. If False, parameter errors are rescaled by the reduced chi^2, by default True

  • fill_value (float, optional) – Fill value for parameters when not enough data points to fit model, by default np.nan

  • return_chi2 (bool, optional) – Return chi^2 values along with parameters and uncertainties in params, param_errs, chi2_x, chi2_y, by default False. Ignored for the 2D (batch) case, which always returns all four.

  • bootstrap (int, optional) – Bootstrapping uncertainties (single-star case only), by default 0

  • seed (int, optional) – Seed for the random number generator, by default None

  • verbose (bool, optional) – Print warning messages, by default True

Returns:

Parameters, uncertainties, and chi squares if return_chi2 is True (always for the batch case). The corresponding parameter names are in self.fit_param_names.

Return type:

params, param_errs(, chi2_x, chi2_y)

get_predicted_positions(t, fit_params, fit_param_errs=None, fixed_params_dict=None)[source]

Evaluate the model at the given time(s).

Every concrete subclass overrides this. The time argument follows one contract across all of them, resolved by broadcast_times():

Parameters:
  • t (scalar or array-like) –

    Time(s) at which to evaluate the model. The SHAPE decides whether the times are shared across stars or are per-star – nothing is inferred from len(t) matching N_stars:

    t

    meaning

    scalar

    one time, every star

    (N_times,)

    one shared grid, every star – always, even when N_times == N_stars

    (1, N_times)

    the same, written explicitly

    (N_stars, N_times)

    each star has its own times

    For one time per star, pass a column vector t[:, np.newaxis] of shape (N_stars, 1) – not a bare 1D array. Any other shape raises ValueError rather than being guessed at. See broadcast_times().

  • fit_params (array-like) – Fit parameters, shape (N_fit_params,) or (N_stars, N_fit_params).

  • fit_param_errs (array-like, optional) – Uncertainties on fit_params, same shape, by default None.

  • fixed_params_dict (dict, optional) – Fixed (non-fit) parameters; see each subclass’s fixed_param_names, by default None.

Returns:

Predicted positions, and uncertainties if fit_param_errs is given, with shape (N_stars, N_times) – flattened when N_stars == 1 or N_times == 1.

Return type:

x, y (, xe, ye)

classmethod keep_model_mask(tab, rows)[source]

Decide which under-detected stars keep this model instead of being demoted.

Parameters:
  • tab (StarTable or astropy Table) – Table holding the stars and any initial fit-parameter columns.

  • rows (array of bool, shape = [len(tab)]) – Stars that requested this model but have fewer than n_params epochs.

Returns:

keep – True where the star (in rows order) keeps this model.

Return type:

numpy array, dtype=bool, shape = [rows.sum()]

Notes

Behavior follows the class attribute demote. For 'on-missing-init', a star keeps the model only if every column in fit_param_names exists and is finite for it. A partial set of initial parameters counts as missing.

abstractmethod run_fit(t, x, y, xe, ye, valid, fixed_params_dict=None, params_init_guess_dict=None, weighting='var', absolute_sigma=True, fill_value=np.nan, verbose=True)[source]

Fit a batch of stars at once (used both for the main fit and for fit()’s bootstrap iterations). Every concrete MotionModel subclass must override this – there is no per-star fallback anymore, so a subclass that doesn’t override it would otherwise silently inherit this stub and produce all-fill_value/inf fits with no warning. A subclass whose fit genuinely can’t be vectorized across stars can still satisfy this same batch-in/batch-out signature by looping over stars internally (e.g. calling scipy.optimize.curve_fit once per row) – nothing requires the implementation to be closed-form, only the interface to accept/return a whole batch at once.

demote = 'always'[source]
fit_param_names = [][source]
fixed_meta_data = [][source]
fixed_param_names = [][source]
fixed_params_dict = None[source]
n_fit_params = 0[source]
n_params = 0[source]
name = 'MotionModel'[source]
optional_fixed_params[source]
required_fixed_param_names = [][source]
class flystar.motion_model.Orbit[source]

Bases: MotionModel

Newtonian orbit. Fixed or fit is chosen per star, not here.

The update_ref_motion column on the reference table decides. Both modes read orb_*. A fit updates those columns in place. A failed fit returns its initial parameters.

The sky frame is hardcoded: x = -east, y = +north. mass and dist default to the pair that reproduces the a column of orbits.dat v2.0.2.

Build one Orbit model. No constructor arguments.

Return type:

None

fit_one_star(t, x, y, xe, ye, valid, init_params, mass, dist, bh, weighting, absolute_sigma, verbose)[source]

Fit one star. On failure, return init_params unchanged.

Parameters:
  • t (ndarray, shape (n_epochs,)) – One star’s astrometry.

  • x (ndarray, shape (n_epochs,)) – One star’s astrometry.

  • y (ndarray, shape (n_epochs,)) – One star’s astrometry.

  • xe (ndarray, shape (n_epochs,)) – One star’s astrometry.

  • ye (ndarray, shape (n_epochs,)) – One star’s astrometry.

  • valid (ndarray of bool, shape (n_epochs,)) – Epochs that enter the fit.

  • init_params (ndarray, shape (6,)) – Initial parameters (current elements). Copied before the solve.

  • mass (float) – Black-hole mass and distance.

  • dist (float) – Black-hole mass and distance.

  • bh (tuple of float) – (x_bh, y_bh, vx_bh, vy_bh, t_bh).

  • weighting ({'var', 'std'}) – Same meaning as Linear.run_fit.

  • absolute_sigma (bool) – When False, scale the covariance by the reduced chi-squared.

  • verbose (bool) – Warn when the star is skipped or does not converge.

Returns:

  • elements (ndarray, shape (6,)) – Solution, or the initial parameters if the star was not solved.

  • errs (ndarray, shape (6,)) – Square root of the covariance diagonal, or inf.

  • chi2x, chi2y (float) – Weighted squared residuals in each coordinate.

  • converged (bool) – True only when least_squares succeeded and the covariance is the one belonging to that solution (it may still be non-finite when there is no residual degree of freedom).

  • n_iter (int) – Residual evaluations, or 0 if the solver was not called.

  • cov (ndarray, shape (6, 6)) – Element covariance, or inf.

Notes

Fewer than three distinct epochs, non-finite initial parameters, or initial parameters with P <= 0 or e outside [0, 1) do not call the solver. Initial parameters that cannot be integrated would otherwise be replaced by a fill value on the way back into the table.

get_predicted_positions(t, fit_params, fit_param_errs=None, fixed_params_dict=None)[source]

Predict from the current orb_* elements.

Parameters:
  • t (scalar or array-like) – Time(s) in decimal years. Shape rules are in MotionModel.get_predicted_positions() / broadcast_times().

  • fit_params (array-like, shape (6,) or (n_stars, 6)) – orb_P, orb_t0, orb_e, orb_i, orb_Omega, orb_omega.

  • fit_param_errs (array-like, optional) – Diagonal orb_*_err. Position errors use orb_cov when that covariance is finite, not these diagonals. By default None.

  • fixed_params_dict (dict, optional) – mass, dist, and the black-hole offsets. orb_cov is passed here when the column exists. mass and dist fall back to the defaults. By default None.

Returns:

  • x, y (ndarray) – FlyStar frame. x = -east, y = +north.

  • xe, ye (ndarray) – Returned only when fit_param_errs is given. 0 when no fit was run. Jacobian times orb_cov when that matrix is finite. inf when a fit has no finite covariance.

Notes

An all-NaN covariance is “never written”, same as a missing column, and returns zero errors. A failed fit stores inf, not NaN, and returns inf errors.

run_fit(t, x, y, xe, ye, valid, fixed_params_dict=None, params_init_guess_dict=None, weighting='var', absolute_sigma=True, fill_value=np.nan, verbose=True)[source]

Per-star least_squares, started from the current orb_*.

On failure, return those initial parameters and flag non-convergence. Do not return fill_value. Frozen stars never reach this method.

Parameters:
  • t (array-like, shape (n_stars, n_epochs)) – Astrometry. Invalid epochs are marked by valid.

  • x (array-like, shape (n_stars, n_epochs)) – Astrometry. Invalid epochs are marked by valid.

  • y (array-like, shape (n_stars, n_epochs)) – Astrometry. Invalid epochs are marked by valid.

  • xe (array-like, shape (n_stars, n_epochs)) – Astrometry. Invalid epochs are marked by valid.

  • ye (array-like, shape (n_stars, n_epochs)) – Astrometry. Invalid epochs are marked by valid.

  • valid (ndarray of bool, shape (n_stars, n_epochs)) – Epochs that enter the fit.

  • fixed_params_dict (dict, optional) – mass and dist fall back to the class defaults. By default None.

  • params_init_guess_dict (dict, optional) – Initial parameters: the six elements, keyed orb_P … orb_omega, each a scalar or one value per star. The table fitter copies the current columns in. By default None.

  • weighting ({'var', 'std'}, optional) – Same meaning as Linear.run_fit, by default ‘var’.

  • absolute_sigma (bool, optional) – When False, scale the covariance by the reduced chi-squared. By default True.

  • fill_value (float, optional) – Unused for the elements. A failed fit keeps its initial parameters. By default np.nan.

  • verbose (bool, optional) – Warn when a star is skipped or does not converge. By default True.

Returns:

  • params, param_errs (ndarray, shape (n_stars, 6)) – Updated elements, or the initial parameters if not solved. Uncertainties are the square root of the covariance diagonal, or inf when not solved.

  • chi2x, chi2y (ndarray, shape (n_stars,)) – Weighted squared residuals in each coordinate.

  • diagnostics (dict) – orb_fit_converged (bool, shape (n_stars,)), orb_fit_n_iter (int, shape (n_stars,)), and orb_cov with shape (n_stars, 6, 6). orb_fit_n_iter counts residual evaluations from least_squares.

Notes

The initial parameters have to travel in params_init_guess_dict because run_fit otherwise only sees the measurements. The table fitter copies the current orb_* columns into that dict before the call. Missing initial parameters are non-finite, so the elements already in the table are what a failed fit returns only when those columns were copied in.

demote = 'on-missing-init'[source]
fit_param_names = ['orb_P', 'orb_t0', 'orb_e', 'orb_i', 'orb_Omega', 'orb_omega'][source]
fixed_param_names = ['mass', 'dist', 'x_bh', 'y_bh', 'vx_bh', 'vy_bh', 't_bh'][source]
n_fit_params = 6[source]
n_params = 6[source]
name = 'Orbit'[source]
optional_fixed_params[source]
prediction_columns = ['orb_cov', 'orb_fit_status'][source]
required_fixed_param_names = [][source]
class flystar.motion_model.Parallax[source]

Bases: MotionModel

Motion model for linear proper motion + parallax

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’.

Make a Parallax motion model with an empty parallax-vector cache.

Return type:

None

Notes

_pvec_cache holds the last parallax vectors computed by calc_parallax_vector, as a dict with keys t_mjd (sorted, shape (N_times,)), dirs (ra, dec, pa rows, shape (N_dirs, 3)), obsLocation, and pvec (shape (N_dirs, 2, N_times)).

calc_parallax_vector(t_mjd, ra, dec, pa=0.0, obsLocation='earth')[source]

Calculate parallax vector of shape (N_stars, 2, N_times)

Parameters:
  • t_mjd (array-like) – Time array in MJD, in the TDB scale. parallax_in_direction declares its input TDB without converting, so a UTC MJD would be read as TDB and shift every epoch by ~69 s. Callers converting from decimal years should use Time(t, format='decimalyear', scale='utc').tdb.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, where 2 corresponds to (x, y) components. N_stars is the broadcast length of ra, dec, and pa. Read-only: it may be a view of the cache.

Return type:

ndarray, shape (N_stars, 2, N_times)

Notes

Results are cached on the instance, keyed on the times, the (ra, dec, pa) of every star, and obsLocation. A call is served from the cache when its directions and obsLocation match exactly and its times are a subset of the cached times – e.g. the bootstrap draws of a star, or the next star in a per-star loop over one field.

When every star shares one direction (ra/dec/pa from table metadata), that direction is stored once, so fits with different star counts in the same field share the cache. On a miss in the same directions, the cache grows to the union of the old and new times, so stars observed in different subsets of the epochs stop missing after a few calls.

get_predicted_positions(t, fit_params, fit_param_errs=None, fixed_params_dict=None)[source]

Model positions (and uncertainties, if fit_param_errs is provided) at time t of Parallax model.

Parameters:
  • t (scalar or array-like) – Time(s) in decimal years. Shape rules are in MotionModel.get_predicted_positions() / broadcast_times().

  • fit_params (array-like) – x0, vx, y0, vy, pi in shape (N_fit_params,) or (N_stars, N_fit_params)

  • fit_param_errs (array-like, optional) – Uncertainties in fit parameters, by default None

  • fixed_params_dict (dict, optional) –

    Falls back to the fixed parameters stored by the last single-star fit, by default None. Keys:

    • 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:

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

Return type:

x, y (, xe, ye)

run_fit(t, x, y, xe, ye, valid, fixed_params_dict=None, params_init_guess_dict=None, weighting='var', absolute_sigma=True, fill_value=np.nan, verbose=True)[source]

Batch fit for many stars at once. Parallax’s model (x0 + vx*dt + pi*Px(t), y0 + vy*dt + pi*Py(t)) is linear in its fit parameters once the parallax factors Px, Py are precomputed from each star’s fixed ra/dec – so, like Linear/Acceleration, it has a closed-form weighted least-squares solution. Unlike those two, x and y are NOT independent here: pi is shared between both directions (all 5 params are fit jointly from the stacked [x, y] data), so this is one coupled 5x5 normal-equations system per star – the x0/vx block and y0/vy block only interact with each other through the shared pi row/column – solved via a batched np.linalg.inv.

Parameters:
  • t (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs). All stars must share the same observation times (parallax_in_direction only supports one shared time axis for the whole batch, and ref_table’s 2D ‘t’ column is populated the same way for every star at a given epoch) – t[0] is taken as that shared grid.

  • x (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs). All stars must share the same observation times (parallax_in_direction only supports one shared time axis for the whole batch, and ref_table’s 2D ‘t’ column is populated the same way for every star at a given epoch) – t[0] is taken as that shared grid.

  • y (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs). All stars must share the same observation times (parallax_in_direction only supports one shared time axis for the whole batch, and ref_table’s 2D ‘t’ column is populated the same way for every star at a given epoch) – t[0] is taken as that shared grid.

  • xe (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs). All stars must share the same observation times (parallax_in_direction only supports one shared time axis for the whole batch, and ref_table’s 2D ‘t’ column is populated the same way for every star at a given epoch) – t[0] is taken as that shared grid.

  • ye (array-like, shape (n_stars, n_epochs)) – Per-star, per-epoch data. Entries where valid is False are ignored – their content does not matter (e.g. they can be NaN placeholders for undetected epochs). All stars must share the same observation times (parallax_in_direction only supports one shared time axis for the whole batch, and ref_table’s 2D ‘t’ column is populated the same way for every star at a given epoch) – t[0] is taken as that shared grid.

  • valid (array-like of bool, shape (n_stars, n_epochs)) – Which entries are usable for each star.

  • fixed_params_dict (dict, optional) – Must contain ‘t0’, ‘ra’, ‘dec’ (each scalar or shape (n_stars,)), and optionally ‘pa’, ‘obsLocation’, by default None.

  • weighting (str, optional) – ‘var’ (w=1/xe**2, 1/ye**2) or ‘std’ (w=1/xe, 1/ye), by default ‘var’

  • absolute_sigma (bool, optional) – If False, parameter errors are rescaled by the reduced chi^2, by default True

  • fill_value (float, optional) – Fill value for parameters when not enough data points to fit model, by default np.nan

  • verbose (bool, optional) – Print warning messages, by default True

Returns:

  • params (ndarray, shape (n_stars, 5) – [x0, vx, y0, vy, pi])

  • param_errs (ndarray, shape (n_stars, 5))

  • chi2_x, chi2_y (ndarray, shape (n_stars,))

fit_param_names = ['x0', 'vx', 'y0', 'vy', 'pi'][source]
fixed_param_names = ['t0', 'ra', 'dec', 'pa', 'obsLocation'][source]
n_fit_params = 5[source]
n_params = 0[source]
name = 'Parallax'[source]
optional_fixed_params[source]
required_fixed_param_names = ['t0', 'ra', 'dec'][source]
flystar.motion_model.all_motion_model_param_names(with_errors=True, with_fixed=True)[source]

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

Returns:

List of all unique parameter names across all motion models

Return type:

list

flystar.motion_model.broadcast_times(t, n_stars, caller='get_predicted_positions')[source]

Normalize a time argument into an explicit (n_stars, n_times) grid.

The SHAPE of t alone decides whether the times are shared across stars or are per-star. There is deliberately no inference from len(t) == n_stars: that used to be read as “one time per star”, so the very same 1D array changed meaning depending on how many stars the table happened to contain, and a table whose star count coincided with its epoch count silently took the wrong branch.

t

meaning

scalar

one time, every star

(n_times,)

one shared grid, every star – always, even when n_times == n_stars

(1, n_times)

the same, written explicitly

(n_stars, n_times)

each star has its own times

To evaluate every star at its own single time, pass a column vector – t[:, np.newaxis], of shape (n_stars, 1) – not a bare 1D array. Note that propagating a whole table to one new epoch does NOT need this: pass the scalar epoch and a per-star t0 fixed parameter, and each star’s dt = t - t0[star] already differs.

Parameters:
  • t (scalar or array-like) – Times, in one of the shapes above.

  • n_stars (int) – Number of stars the times are being broadcast against.

  • caller (str, optional) – Name used in the error message, by default ‘get_predicted_positions’.

Returns:

May be a read-only broadcast view – do not write into it.

Return type:

ndarray, shape (n_stars, n_times)

flystar.motion_model.determine_motion_models(startable, motion_models=None, fixed_params_dict=None)[source]

Determine, per star, which motion model to use.

Precedence:

  1. A motion_model_input column – the caller’s explicit per-star request – wherever that model can actually be evaluated for that star (every parameter it needs present and finite). This is the same priority fit_motion_models gives the column.

  2. Otherwise the most complex model in motion_models whose parameters are all present and finite for that star.

  3. motion_models=None means “any model”, so step 2 becomes “the most complex model this star’s parameters support”.

The distinction between a restricted list and None is what separates the two questions this answers. Which model a star was FIT with is confined to the models that were requested, so callers pass their list. How far a star must move to reach some other epoch is a property of the star, not of what you chose to fit – a reference imported from an external catalog can carry vx/vy/t0 that were never fit here and still has to move with Linear – so propagation passes None.

Parameters:
  • startable (startable) – Startable with motion model parameter columns

  • motion_models (list of MotionModel or str, optional) – List of motion model classes or their names to select from. If None, all available motion models will be considered, by default None

  • fixed_params_dict (dict, optional) – Dictionary of fixed parameters, by default None

Returns:

  • motion_model_used (list) – List of motion model used for each star

  • n_params (list) – List of n parameters per direction for each star

flystar.motion_model.frozen_motion_mask(table)[source]

Stars that must not be refit.

Parameters:

table (astropy.table.Table) – Catalog. Reads update_ref_motion when present.

Returns:

frozen – True where the star is held fixed (update_ref_motion is False). Stars without an update_ref_motion column are never frozen.

Return type:

ndarray of bool, shape (n_stars,)

flystar.motion_model.motion_model_map()[source]

Get a dictionary mapping motion model names to MotionModel classes.

Returns:

mm_map – Dictionary mapping motion model names to MotionModel classes.

Return type:

dict

Raises:

ValueError – If a model’s demote is not one of DEMOTE_OPTIONS.

flystar.motion_model.motion_model_param_names(motion_models, with_errors=True, with_fixed=True)[source]

Get the motion model parameter names from a list of MotionModels.

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

Returns:

List of all unique parameter names across all motion models

Return type:

list

flystar.motion_model.organize_motion_models(motion_models)[source]

Organize a list of motion models of type str or MotionModel into a list of MotionModel classes, sorted by increasing number of required parameters. Empty and Fixed are always added if not already present. To be used in align and StarTable.fit_motion_models.

Parameters:

motion_models (MotionModel, str, or list of MotionModels/strings.) – Motion model(s) to organize. Names are matched case-insensitively – ‘linear’ and ‘Linear’ are the same model – and only the canonical spelling propagates, so the caller’s casing never reaches the output.

Returns:

List of MotionModel classes sorted by increasing number of required parameters.

Return type:

list

flystar.motion_model.sigma_from_error(xe, ye, weighting='var')[source]

Convert x/y position errors into the sigma values a weighted fit should use, based on the requested weighting scheme.

weightingstr, optional

‘var’: sigma = abs(xe), abs(ye), so a later 1/sigma**2 gives true inverse-variance weighting (w=1/xe**2, 1/ye**2). ‘std’: sigma = sqrt(abs(xe)), sqrt(abs(ye)), so the same later 1/sigma**2 instead gives standard-error weighting (w=1/xe, 1/ye). By default ‘var’.

flystar.motion_model.weight_from_sigma(sigma, valid=None)[source]

Convert an uncertainty (sigma) array into a safe inverse-variance weight (1/sigma**2), for use in a weighted sum/average.

A point with no real uncertainty information should contribute nothing to a weighted sum – but naively computing 1/sigma**2 can instead produce an infinite or NaN weight (sigma is NaN/inf/exactly zero, or so small that squaring it underflows to zero), which would corrupt rather than exclude that point. This handles all of those cases uniformly: any sigma that doesn’t produce a finite weight, or any point explicitly marked invalid via valid, gets a weight of exactly 0.

This does NOT handle the “every point has weight 0” case for you – a weighted average built from these weights still needs its own explicit fallback for that (see combine_lists/fit_motion_models), since there’s no single value this function could return that fixes an otherwise-undefined 0/0 average.

Parameters:
  • sigma (array-like) – Uncertainty values (any invalid/zero/overflow-inducing value is safely handled).

  • valid (array-like of bool, optional) – If given, points where this is False also get weight 0, regardless of sigma, by default None.

Returns:

weight – Same shape as sigma.

Return type:

ndarray

flystar.motion_model.DEMOTE_OPTIONS = ('always', 'never', 'on-missing-init')[source]