DynamicSpectrumModel

class screens.modeling.DynamicSpectrumModel(ds, d_eff=None, mu_eff=None, theta=None, magnification=None)[source] [edit on github]

Bases: object

Model a dynamic spectrum.

Parameters:
dsDynamicSpectrum

Intensities as a function of time and frequency, with some noise.

d_effQuantity

Assumed effective distance. This is used throughout and not fit, but can be treated as a scaling parameters.

mu_effQuantity, optional

Initial guess for the effective proper motion, v_eff/d_eff.

thetaQuantity, optional

Grid of theta angles to use for modelling the dynamic spectrum. Probably more usefully calculated later using theta_grid.

magnificationQuantity, optional

Magnifications at each theta. More typically inferred by fitting the dynamic spectrum.

Methods Summary

cleanup_fit([max_abs_err, max_rel_err, verbose])

Remove highly degenerate configurations from the fit.

dynamic_bases([mu_eff])

Calculate the amplitude infererence patterns for current fit.

fit([guess, verbose])

Fit the dynamic spectrum directly.

fromfile(filename[, d_eff, mu_eff, noise])

Read a dynamic spectrum from an HDF5 file.

jacobian(magnification, mu_eff)

Derivatives of the model dynamic spectrum to all parameters.

locate_mu_eff([mu_eff_trials, verbose, use])

Try reproducing the dynamic spectrum for a range of proper motion.

model([magnification, mu_eff])

Calculate a model dynamic spectrum.

residuals([magnification, mu_eff])

Residuals compared to the model.

theta_grid([oversample_tau, oversample_fd])

Calculate a grid of theta for modelling the dynamic spectrum.

theta_theta([mu_eff, theta_grid])

Create a theta-theta array from the dynamic spectrum.

Methods Documentation

cleanup_fit(max_abs_err=0.1, max_rel_err=1000.0, verbose=True)[source] [edit on github]

Remove highly degenerate configurations from the fit.

Works by doing an singular value decomposition on the fit and removing very small values, those that are either smaller than max_abs_err or max_rel_err times the largest value.

dynamic_bases(mu_eff=None)[source] [edit on github]

Calculate the amplitude infererence patterns for current fit.

The power of the sum of these amplitudes is a dynamic spectrum.

Explicitly assumes that time and frequency are the last two axes of the dynamic spectrum. (TODO: lift this restriction.)

Parameters:
mu_effQuantity, optional

Effective proper motion to use. Defaults to that stored on the instance. Will not update the instance.

Notes

The calculated dynamic bases are cached for a given mu_eff.

fit(guess=None, verbose=2, **kwargs)[source] [edit on github]

Fit the dynamic spectrum directly.

This needs good guesses, such as can be gotten from screens.modeling.DynamicSpectrumModel.locate_mu_eff().

Parameters:
guessinitial guesses, optional

If None, use the current magnification and mu_eff on the instance. If curvature, select the best value from the curvature table on the instance (created by locate_mu_eff). If a tuple, guesses for magnification and mu_eff. If a single number, treat it as a guess for mu_eff and determine initial guesses for the magnification using eigen-value decomposition.

verboseint

How much information to print during fitting. A value of 3 forces the class itself to print a reduced chi2 any time mu_eff is updated.

**kwargs

Any further keyword arguments to pass on to scipy.optimize.curve_fit().

Notes

This uses the model and jacobian methods on the instance.

classmethod fromfile(filename, d_eff=None, mu_eff=None, noise=None)[source] [edit on github]

Read a dynamic spectrum from an HDF5 file.

This includes its time and frequency axes.

Note: this needs the baseband-tasks package for HDF5 file access.

jacobian(magnification, mu_eff)[source] [edit on github]

Derivatives of the model dynamic spectrum to all parameters.

The model dynamic spectrum is

\[\begin{split}w(f, t) &= \sum_k \mu_k \exp[j\phi(\theta_i, \mu_{\rm eff}, f, t)] &\equiv \sum_k \mu_k \Phi_k \\ DS(f,t) &= |w(f, t)|^2 = w \bar{w}\end{split}\]

It is easiest to use Wirtinger derivatives:

\[\begin{split}\frac{\partial}{\partial x} &= \left(\frac{\partial}{\partial z} + \frac{\partial}{\partial\bar{z}}\right) \\ \frac{\partial}{\partial y} &= j \left(\frac{\partial}{\partial z} - \frac{\partial}{\partial\bar{z}}\right)\end{split}\]

Using this for the magnifications:

\[\begin{split}\frac{\partial DS}{\partial\mu} &= \bar{w}\frac{\partial w}{\partial\mu} = \bar{w}\Phi \\ \frac{\partial DS}{\partial\bar{\mu}} &= w \frac{\partial\bar{w}}{\partial\bar{\mu}} = w \bar{\Phi} \\ \frac{\partial DS}{\partial x} &= \left(\bar{w} \Phi + w \bar{\Phi}\right) = 2\Re(w\bar{\Phi}) \\ \frac{\partial DS}{\partial y} &= j\left(\bar{w} \Phi - w \bar{\Phi}\right) = 2\Im(w\bar{\Phi})\end{split}\]

And for \(\mu_{\rm eff}\):

\[\begin{split}\frac{\partial w}{\partial\mu_{\rm eff}} &= \sum_k\mu_k\Phi_k \frac{\partial j\phi_k}{\partial\mu_{\rm eff}} \\ \frac{\partial\bar{w}}{\partial\mu_{\rm eff}} &= \sum_k\bar{\mu}_k\bar{\Phi}_k \frac{\partial -j\phi_k}{\partial\mu_{\rm eff}} \\ \frac{\partial DS}{\partial\mu_{\rm eff}} &= \bar{w} \frac{\partial w}{\partial\mu_{\rm eff}} + w \frac{\partial\bar{w}}{\partial\mu_{\rm eff}} = 2j\sum_k\mu_k \Phi_k \frac{\partial\phi}{\partial\mu_{\rm eff}}\end{split}\]
locate_mu_eff(mu_eff_trials=None, verbose=True, use=True, **kwargs)[source] [edit on github]

Try reproducing the dynamic spectrum for a range of proper motion.

For each proper motion, construct a theta-theta array, calculte the largest eigenvalue and use the corresponding eigenvector as the model one-dimensional screen.

Parameters:
mu_eff_trialsQuantity

Proper motions to try.

verbosebool

Whether or not to give summary statistics for each trial.

usebool

Whether to store the best-fit proper motion and corresponding theta grid and magnifications on the instance.

**kwargs

Further parameters to use in calculating the theta grid for each proper motion.

Returns:
curvatureQTable

Table with the following columns: - mu_eff : Input proper motions. - theta : grid in theta used. - w : Largest eigenvalue. - recovered : corresponding eigenvector, i.e., magnifications. - th_ms : Mean-square residual in theta-theta space. - ndof : degrees of freedom n_dynspec - n_theta - 2. - redchi2 : reduced chi2 ((dynspec - model)/noise)**2/ndof.

Notes

The resulting table is also stored on the instance, as curvature.

model(magnification=None, mu_eff=None)[source] [edit on github]

Calculate a model dynamic spectrum.

Uses parameters on the instance if not otherwise specified.

Parameters:
magnificationarray-like, optional

Complex magnification for each theta value.

mu_effQuantity, optional

Effective proper motion.

residuals(magnification=None, mu_eff=None)[source] [edit on github]

Residuals compared to the model.

Parameters as for model():

theta_grid(oversample_tau=1.3, oversample_fd=1.69, **kwargs)[source] [edit on github]

Calculate a grid of theta for modelling the dynamic spectrum.

Wraps screens.fields.theta_grid with defaults from the class. See that function for details.

Note that this does not set the angles on the class, so typical usage is ds.theta = ds.theta_grid().

theta_theta(mu_eff=None, theta_grid=None, **kwargs)[source] [edit on github]

Create a theta-theta array from the dynamic spectrum.

For a given grid in theta (possibly calculated) and a set of pairs found using screens.fields.theta_theta_indices, this brute-force estimates the amplitudes at each pair by cross-multiplying their expected signature in the dynamic spectrum.

Parameters:
mu_effQuantity, optional

Effective proper motion to use. Defaults to that stored on the instance. Will update the instance if given.

theta_gridbool, optional

Whether to calculate a new theta grid, or use the one stored on the instance. By default, calculate it only if mu_eff is passed in. If True, this will update the grid stored on the instance.

**kwargs

Any further arguments are passed on to theta_grid