obstools.utils module

Utility Module

LDTObserverTools contains python ports of the various DeVeny IDL routines

Lowell Discovery Telescope (Lowell Observatory: Flagstaff, AZ) https://lowell.edu

This file contains various utility functions needed by other routines in this package.

class obstools.utils.ScriptBase[source]

Bases: object

Provides a base class for all scripts.

Implements base classes for use with PypeIt scripts.

static _fill_parser_cwd(parser)[source]

Replace the default of any action that is exactly 'current working directory' with the value of os.getcwd().

The parser is edited in place.

Parameters:

parser (ArgumentParser) – The argument parsing object to edit.

classmethod entry_point()[source]

Defines the main script entry point.

classmethod get_parser(description=None, width=None, formatter=<class 'argparse.ArgumentDefaultsHelpFormatter'>)[source]

Construct the command-line argument parser.

Derived classes should override this. Ideally they should use this base-class method to instantiate the ArgumentParser object and then fill in the relevant parser arguments

Warning

Any argument that defaults to the string 'current working directory' will be replaced by the result of os.getcwd() when the script is executed. This means help dialogs will include this replacement, and parsing of the command line will use os.getcwd() as the default. This functionality is largely to allow for PypeIt’s automated documentation of script help dialogs without the “current working” directory being that of the developer that most recently compiled the docs.

Parameters:
  • description (str, optional) – A short description of the purpose of the script.

  • width (int, optional) – Restrict the width of the formatted help output to be no longer than this number of characters, if possible given the help formatter. If None, the width is the same as the terminal width.

  • formatter (HelpFormatter) – Class used to format the help output.

Returns:

ArgumentParser – Command-line interpreter.

static main(args)[source]

Execute the script.

class property name

Provide the name of the script. By default, this is the name of the module.

classmethod parse_args(options=None)[source]

Parse the command-line arguments.

class obstools.utils.SmartFormatter(prog, indent_increment=2, max_help_position=24, width=None)[source]

Bases: HelpFormatter

Enable a combination of both fixed-format and wrappable lines to be formatted for the help statements for command-line arguments used with ArgumentParser.

Borrows from https://stackoverflow.com/questions/3853722/python-argparse-how-to-insert-newline-in-the-help-text

Help strings that use this formatter must begin with “R|”. If not, the help string is parsed by the base class.

When parsed by this formatter, the leading “R|” characters are stripped and the lines to be printed are parsed using splitlines(). Each resulting line is wrapped using wrap(), unless it begins with the characters “F|”, which forces the line to remain unaltered (except for stripping the leading characters).

For example, if you add an argument like this:

parser.add_argument('-t', '--tell_file', type=str,
                    help='R|Configuration file to change default telluric parameters.  '
                         'Note that the parameters in this file will be overwritten if '
                         'you set argument in your terminal.  The --tell_file option '
                         'requires a .tell file with the following format:\n'
                         '\n'
                         'F|    [tellfit]\n'
                         'F|         objmodel = qso\n'
                         'F|         redshift = 7.6\n'
                         'F|         bal_wv_min_max = 10825,12060\n'
                         'OR\n'
                         'F|    [tellfit]\n'
                         'F|         objmodel = star\n'
                         'F|         star_type = A0\n'
                         'F|         star_mag = 8.\n'
                         'OR\n'
                         'F|    [tellfit]\n'
                         'F|         objmodel = poly\n'
                         'F|         polyorder = 3\n'
                         'F|         fit_wv_min_max = 9000.,9500.\n'
                         '\n')

The result will be (depending on the width of your console):

-t TELL_FILE, --tell_file TELL_FILE
                  Configuration file to change default telluric
                  parameters.  Note that the parameters in this file
                  will be overwritten if you set argument in your
                  terminal.  The --tell_file option requires a .tell
                  file with the following format:

                      [tellfit]
                           objmodel = qso
                           redshift = 7.6
                           bal_wv_min_max = 10825,12060
                  OR
                      [tellfit]
                           objmodel = star
                           star_type = A0
                           star_mag = 8.
                  OR
                      [tellfit]
                           objmodel = poly
                           polyorder = 3
                           fit_wv_min_max = 9000.,9500.
_split_lines(text, width)[source]

Split the provided text into width constrained lines.

See the class description for formatting instructions.

obstools.utils.all_subclasses(cls)[source]

Collect all the subclasses of the provided class.

Note

This function borrowed from PypeIt

The search follows the inheritance to the highest-level class. Intermediate base classes are included in the returned set, but not the base class itself.

Thanks to: https://stackoverflow.com/questions/3862310/how-to-find-all-the-subclasses-of-a-class-given-its-name

Parameters:

cls (object) – The base class

Returns:

set – The unique set of derived classes, including any intermediate base classes in the inheritance thread.

obstools.utils.check_float(potential_float) bool[source]

Simple funtion to check whether something is a float

Parameters:

potential_float (Any) – Value to check for float

Returns:

bool – Whether it am or it ain’t a float.

obstools.utils.first_moment_1d(line)[source]

Returns the 1st moment of line

Parameters:

line (ndarray) – 1-dimensional array to find the 1st moment of

Returns:

float – The first moment of the input array relative to element #

obstools.utils.flatten_comprehension(nested_list: list) list[source]

Flatten a single-depth nested list via list comprehension

https://realpython.com/python-flatten-list/

Parameters:

nested_list (list) – The single-depth nested list to flatten

Returns:

list – The flattened list

obstools.utils.gaussfit(x, y, nterms: int = 3, estimates=None, bounds=None, debug: bool = False)[source]

Function similar to IDL’s GAUSSFIT

Big caveat: as implemented, can only estimate the initial parameters for POSITIVE gaussians (emission), and cannot correctly estimate parameters for negative (absorption) gaussians. The function will still happily fit a negative gaussian if given the proper estimates.

Utilizes scipy.optimize.curve_fit() and the helper function gaussian_function() below.

Parameters:
  • x (ndarray) – Input abscissa values for the fitting

  • y (ndarray) – Input ordinate values for the fitting

  • nterms (int, optional) – Number of terms to use in the Gaussian fit (Default: 3)

  • estimates (ndarray, optional) – Estimated values for the nterms parameters (see curve_fit(); Default: None)

  • bounds (ndarray, optional) – Bounds on the nterms parameters (see curve_fit(); Default: None)

  • debug (bool, optional) – Print debugging statements. (Defualt: False)

Returns:

obstools.utils.gaussian_function(x: ndarray, a0: float, a1: float, a2: float, a3: float = 0.0, a4: float = 0.0, a5: float = 0.0)[source]

Gaussian Function

Construct a basic Gaussian using at least 3, but up to 6 parameters.

Parameters:
  • x (ndarray) – X values over which to compute the gaussian

  • a0 (float) – Gaussian amplitude

  • a1 (float) – Gaussian mean (mu)

  • a2 (float) – Gaussian width (sigma)

  • a3 (float, optional) – Baseline atop which the Gaussian sits. (Default: 0)

  • a4 (float, optional) – Slope of the baseline atop which the Gaussian sits. (Default: 0)

  • a5 (float, optional) – Quadratic term of the baseline atop which the Gaussian sits. (Default: 0)

Returns:

ndarray – The Y values of the Gaussian corresponding to X

obstools.utils.good_poly(x, y, order, thresh, return_full=False)[source]

Robust fitting of a polynomial to data

This is a python port of an IDL routine written years ago by M. Buie.

This is a multi-pass fitting routine that fits a fixed order polynomial to the input data. After each pass, the scatter of the fit relative to the fitted line is computed. Each point is examined to see if it falls beyond THRESH sigma from the line. If is does, it is removed from the data and the fit is tried again. This will make up to two attempts to remove bad data.

Written in IDL 1991-1998, Marc W. Buie, Lowell Observatory

Parameters:
  • x (ndarray) – Input dataset, independant values.

  • y (ndarray) – Input dataset, dependant values.

  • order (int) – Order of the polynomial fit (linear = 1).

  • thresh (float) – Sigma threshold for removing outliers.

  • return_full (bool, optional) –

    If True, also return:

    yfit : Fitted values for y that match the input vector. newx : X values from input that were considered good. newy : Y values from input that were considered good.

Returns:

obstools.utils.nearest_odd(x: float) int[source]

Find the nearest odd integer

https://www.mathworks.com/matlabcentral/answers/45932-round-to-nearest-odd-integer#accepted_answer_56149

Parameters:

x (float) – Input number

Returns:

int – The nearest odd integer

obstools.utils.set_std_tickparams(axis: axis, tsz: int | float)[source]

Set standard tick parameters for a plot

These are my own “standards”, based on plots I used to make in IDL.

Parameters:
  • axis (axis) – PyPlot axis for whom the tick parameters must be set

  • tsz (int or float) – TypeSiZe

obstools.utils.sinusoid(x: ndarray, a: float, lam: float, phi: float, y0: float = 0, lin: float = 0, quad: float = 0, cube: float = 0, quar: float = 0) ndarray[source]

Return a basic sinusoid (for use with scipy.optimize.curve_fit())

_extended_summary_

Parameters:
  • x (ndarray) – The abscissa values for which to return the ordinate

  • a (float) – The amplitude of the sinusoid (in units of ordinate)

  • lam (float) – The wavelength of the sinusoid (in units of abscissa), equivalent to 2π/k (where k is the wavenumber).

  • phi (float) – The phase shift of the sinusoid (in units of phase, nominally 0-1)

  • y0 (float, optional) – The vertical offset of the sinusoid from zero (in units of ordinate) (Default: 0)

  • lin (float, optional) – The linear term added to the fit (in units of ordinate/abscissa) (Default: 0)

  • quad (float, optional) – The quadratic term added to the fit (in units of ordinate/abscissa**2) (Default: 0)

  • cube (float, optional) – The cubic term added to the fit (in units of ordinate/abscissa**3) (Default: 0)

  • quar (float, optional) – The quartic term added to the fit (in units of ordinate/abscissa**4) (Default: 0)

Returns:

ndarray – The sinusoid ordinate

obstools.utils.warn_and_return_zeros(return_full: bool, x, xx, yy, order, raise_warn=False)[source]

Set warning and return zeroes from good_poly()

This function is a DRY. Since this block is used several times in good_poly(), separate out as a function.

Parameters:
  • return_full (bool) – Return a bunch of stuff

  • x (ndarray) – [description]

  • xx (ndarray) – [description]

  • yy (ndarray) – [description]

  • order (int) – The order of the polynomial fit

  • raise_warn (bool, optional) – Actually raise the warning this function is meant to [Default: False]

Returns:

ndarray – An array of zeros of the proper length