Estimte offset field using PyCuAmpcor.
    Parameters: reference - str, path of the reference SLC file
                secondary - str, path of the secondary SLC file
                inps      - Namespace, input configuration
    Returns:    objOffset - PyCuAmpcor object
                geomDict  - dict, geometry location info of the offset field


Generate multilooked geometry datasets in the same grid as the estimated offset field
    from the full resolution geometry datasets.
    Parameters: full_dir    - str, path of input  geometry directory in full resolution
                out_dir     - str, path of output geometry directory
                x/y_start   - int, starting column/row number
                x/y_step    - int, output pixel step in column/row direction
                x/y_win_num - int, number of columns/rows


Set parameters manually and run ampcor


    Output the message displayed by the setup script
    to LOGFILE and to the standard output


Read config file passed with option -c


Read setup_config file where urls are given


Check arguments passed to this python file


    Generate ISCE xml file from gdal supported file

    Example: import isce
             from applications.gdal2isce_xml import gdal2isce_xml
             xml_file = gdal2isce_xml(fname+'.vrt')


Write out the RSC files for Raw data.


Create rsc files for all the interferograms generated by ISCE.


update these parameters in case users set them in the middle of processing


for keeping the option of the old wbd.py


Check that output directory exists and instantiate logger.


Converts sky coordinates in (RA,Dec,redshift) to standard form, including comoving
        Cartesian coordinate information


Convert from Cartesian coordinates in observers ref. frame to ZOBOV box coords

        :param positions: Nx3 array of position coordinates to be converted

        :return: array of new coordinates


Convert from Cartesian coordinates in ZOBOV box coords to observers ref. frame

        :param positions: Nx3 array of position coordinates to be converted

        :return: array of new coordinates


Generates an approximate survey sky mask if none is provided, and saves to file

        :return: sky fraction covered by survey mask


        Finds pixels adjacent to but outside the survey mask

        :return: a healpy map instance with pixels set =1 if they are on the survey boundary, =0 if not


Method to generate buffer particles around the edges of survey volume to prevent and detect leakage of
        Voronoi cells outside survey region during the tessellation stage


        Measures the redshift-dependence of the galaxy number density in equal-volume redshift bins, and writes to file

        :param nbins: number of bins to use
        :return:


        Writes the tracer and mock position information to file in a ZOBOV-readable format
        :return:


removes the tracer information if no longer required, to save memory


re-reads tracer information from Zobov-formatted file if required after previous deletion


method to write configuration information for the ZOBOV run to file for later lookup


method to read configuration file for information about previous ZOBOV run


        Wrapper function to call C-based ZOBOV codes
        :return: 1 if tessellation successfully completed


        Method to post-process raw ZOBOV output to obtain discrete set of non-overlapping voids. This method
        is hard-coded to NOT allow any void merging, since no objective (non-arbitrary) criteria can be defined
        to control merging, if allowed.


Method that checks a list of processed voids, finds the void minimum density centres and writes
        the void catalogue file.

        Arguments:
            num_struct: integer number of voids after pruning
            wtd_avg_dens: float array of shape (num_struct,), weighted average void densities from post-processing
            edge_flag: integer array of shape (num_struct,), edge contamination flags


Method that checks a list of processed voids, finds the void barycentres and writes
        the void catalogue file.

        Arguments:
            num_struct: integer number of voids after pruning
            edge_flag: integer array of shape (num_struct,), edge contamination flags
            use_stripping: bool,optional (default is False, don't change unless you know what you're doing!)
            strip_density_threshold: float, optional (default 1.0, not required unless use_stripping is True)


        Method to post-process raw ZOBOV output to obtain discrete set of non-overlapping 'superclusters'. This method
        is hard-coded to NOT allow any supercluster merging, since no objective (non-arbitrary) criteria can be defined
        to control merging anyway.


Trim catalog columns using a boolean array


        Subtract RSD to get the estimated real-space positions of randoms
        (no need to do this for galaxies, since it already happens during the iteration loop)


        Uses the estimated displacement field to shift the positions of galaxies (and randoms).
        This method subtracts full displacement field as in standard BAO reconstruction


method to write the shifted positions to file


    Performs a granule search with token authentication for restricted results

    :search_parameters: dictionary of CMR search parameters
    :token: CMR token needed for restricted search
    :geojson: filepath to GeoJSON file for spatial search
    :output_format: select format for results https://cmr.earthdata.nasa.gov/search/site/docs/search/api.html#supported-result-formats

    :returns: if hits is greater than 0, search results are returned in chosen output_format, otherwise returns None.


    Performs a granule search with token authentication for restricted results

    :search_parameters: dictionary of CMR search parameters
    :token: CMR token needed for restricted search
    :output_format: select format for results https://cmr.earthdata.nasa.gov/search/site/docs/search/api.html#supported-result-formats

    :returns: if hits is greater than 0, search results are returned in chosen output_format, otherwise returns None.


    Performs a data customization and access request from NSIDC's API/
    Creates an output folder in the working directory if one does not already exist.

    :API_request: NSIDC API endpoint; see https://nsidc.org/support/how/how-do-i-programmatically-request-data-services for more info
    on how to configure the API request.


    Performs a data customization and access request from Harmony.

    :search_parameters: dictionary of CMR search parameters
    :token: CMR token needed for restricted search


    Performs a granule search

    :search_parameters: dictionary of CMR search parameters
    :geojson: filepath to GeoJSON file for spatial search
    :output_format: select format for results https://cmr.earthdata.nasa.gov/search/site/docs/search/api.html#supported-result-formats

    :returns: if hits is greater than 0, search results are returned in chosen output_format, otherwise returns None.


    Extracts urls for each granule

    :response: json structure returned by search_granules

    :returns: list of urls or empty list if no entries


    Print list of href urls for granules from response

    :response: JSON structure from search_granules


    Returns a list of dictionaries containing time_start, time_end and extent polygons for granules

    :search_results: dictionary object returned by search_granules

    :returns: list of dictionaries or empty list of no entries or keys do not exist


    Converts spatiotemporal fields from results to geopandas DataFrame

    :search_results: returned by search_granules
    :crs: coordinate reference system: default is WGS84 (EPSG:4326)

    :returns: geopandas dataframe with polygons field as geometry


    Read Auriga snapshot and write true cumulative mass profile

    Parameters:
    ----------
    halonum: str
        Auriga halo number of mock to write ("06", "16", "21", "23", "24", "27")

    Auriga halos downloaded from:
    https://wwwmpa.mpa-garching.mpg.de/auriga/data.html


    From Adrian Price-Whelan (Astropy)
    Transform a barycentric radial velocity to the Galactic Standard of Rest
    (GSR).
    The input radial velocity must be passed in as a
    Parameters
    ----------
    c : `~astropy.coordinates.BaseCoordinateFrame` subclass instance
        The radial velocity, associated with a sky coordinates, to be
        transformed.
    v_sun : `~astropy.units.Quantity`, optional
        The 3D velocity of the solar system barycenter in the GSR frame.
        Defaults to the same solar motion as in the
        `~astropy.coordinates.Galactocentric` frame.
    Returns
    -------
    v_gsr : `~astropy.units.Quantity`
        The input radial velocity transformed to a GSR frame.


    Calculates rho(r)

    S(log r) is log of tracer count
        (intended to be used with agama.splineLogDensity and weights=1)
    r is point or array of points where rho should be evaluated


    Calcualtes dlnrho / dlnr

    S(log r) is log of tracer count
        (intended to be used with agama.splineLogDensity and weights=1)
    r is point or array of points where rho should be evaluated


    Calculate spherical velocities and radii from cartesian kinematics
    gal_data formatted as x,y,z,vx,vy,vz


 Calculates the spatial correlation between im1 and im2 using the HOG method and its confidence interval using Montecarlo sampling

   Parameters
   ----------
   ima1 : array corresponding to the first image to be compared
   ima2 : array corresponding to the second image to be compared
   s_ima1 :
   s_ima2 :
   pxsz :
   ksz : Size of the derivative kernel in the pixel size units

   Returns
   -------
    hogcorr :
    corrframe :

   Examples
   --------


 Calculates the spatial correlation between im1 and im2 using the HOG method

   Parameters
   ----------
   ima1 : array corresponding to the first image to be compared
   ima2 : array corresponding to the second image to be compared
   s_ima1 :
   s_ima2 :
   pxsz :
   ksz : Size of the derivative kernel in the pixel size units
   mode: Specify how the input array is extended when the kernel overlaps the border of the map.
         Default: 'nearest'; The input is extended by replicating the last pixel.

   Returns
   -------
    circstats:  Statistics describing the correlation between the input images.
                RVL      - Resulting vector lenght.
                Z        - Rayleigh statistic.
                V        - Projected Ratleigh statistic.
                pearsonr - Pearson correlation coefficient.
                ngood    - Number of pixels used for the correlation

    corrframe : array containing the angles between the image gradients
    sima1     : ima1 smoothed with a 2D Gaussian with the size of the derivative kernel
    sima2     : ima2 smoothed with a 2D Gaussian with the size of the derivative kernel

   Examples
   --------


 Calculates the spatial correlation between im1 and im2 using the HOG method

   Parameters
   ----------
   ima1 : array corresponding to the first image to be compared
   cube2 : array corresponding to the second image to be compared
   pxsz :
   ksz : Size of the derivative kernel in the pixel size units
   mode: Specify how the input array is extended when the kernel overlaps the border of the map.
         Default: 'nearest'; The input is extended by replicating the last pixel.

   Returns
   -------
    circstats:  Statistics describing the correlation between the input images.
                RVL      - Resulting vector lenght.
                Z        - Rayleigh statistic.
                V        - Projected Ratleigh statistic.
                pearsonr - Pearson correlation coefficient.
                ngood    - Number of pixels used for the correlation

    corrframe : array containing the angles between the image gradients

    Examples
   --------


 Calculates the spatial correlation between cube1 and cube2 using the HOG method

   Parameters
   ----------
   cube1 : array corresponding to the first  cube to be compared
   cube2 : array corresponding to the second cube to be compared
   pxsz :  pixel size
   ksz :   size of the derivative kernel in the pixel size units

   Returns
   -------
    hogcorr :
    corrframe :

   Examples
   --------


 Calculates the correlation relative orientation between cube1 and the vector field

   Parameters
   ----------
   cube1 : array corresponding to the scale field cube
   vec :   array corresponding to the vector field [v_0,v_1,v_2], where v_i (i=0,1,2) corresponds to the i-th index of cube1
   pxsz :  pixel size
   ksz :   size of the derivative kernel in the pixel size units

   Returns
   -------
    hogcorr :
    corrframe :

   Examples
   --------


Arbitrary resampling of source array to new dimension sizes.
    Currently only supports maintaining the same number of dimensions.
    To use 1-D arrays, first promote them to shape (x,1).

    Uses the same parameters and creates the same co-ordinate lookup points
    as IDL''s congrid routine, which apparently originally came from a VAX/VMS
    routine of the same name.

    method:
    neighbour - closest value from original data
    nearest and linear - uses n x 1-D interpolations using
                         scipy.interpolate.interp1d
    (see Numerical Recipes for validity of use of n 1-D interpolations)
    spline - uses ndimage.map_coordinates

    centre:
    True - interpolation points are at the centres of the bins
    False - points are at the front edge of the bin

    minusone:
    For example- inarray.shape = (i,j) & new dimensions = (x,y)
    False - inarray is resampled by factors of (i/x) * (j/y)
    True - inarray is resampled by(i-1)/(x-1) * (j-1)/(y-1)
    This prevents extrapolation one element beyond bounds of input array.


 Compares two healpix maps using the gradient orientation

   Parameters
   ----------
   ima1 : array corresponding to the first image to be compared
   ima2 : array corresponding to the second image to be compared
   s_ima1 :
   s_ima2 :
   pxsz :
   ksz : Size of the derivative kernel in the pixel size units

   Returns
   -------
    hogcorr :
    corrframe :

   Examples
   --------


Reproject data cube in a distorsion-less WCS.

        .. warning:: The amount of available RAM must be larger than
          the cube size on disk.


General wrapper around get_spectrum* methods for backward
        compatibility


Return a spectrum extracted at x, y and integrated
        over a circular aperture or radius r.

        :param x: x position

        :param y: y position

        :param r: (Optional) If r > 0, vector is integrated over a
          circular aperture of radius r. In this case the number of
          pixels is returned as a parameter: pixels

        :param median: If True, a median is used instead of a mean to
          combine spectra. As the resulting spectrum is integrated,
          the median value of the combined spectra is then scaled to
          the number of integrated pixels.

        :param mean_flux: If True, the mean spectrum (ie per pixel
          flux) is returned.

        :param subtract_spectrum: Subtract given spectrum. Must be a
          vector of the same size as the extracted spectrum.

        :return: axis, spectrum


Return a spectrum extracted at x, y and integrated
        over a binned region.

        :param x: X position of the bottom-left pixel

        :param y: Y position of the bottom-left pixel

        :param b: Binning. If 1, only the central pixel is extracted

        :param median: If True, a median is used instead of a mean to
          combine spectra. As the resulting spectrum is integrated,
          the median value of the combined spectra is then scaled to
          the number of integrated pixels.

        :param mean_flux: If True, the mean spectrum (ie per pixel
          flux) is returned.

        :return: axis, spectrum


Return a. orb.fft.RealSpectrum extracted at x, y and integrated
        over a circular annulus of min radius rmin and max radius rmax.

        :param x: x position

        :param y: y position

        :param rmin: rmin of the annulus

        :param rmax: rmax of the annulus

        :param median: If True, a median is used instead of a mean to
          combine spectra. As the resulting spectrum is integrated,
          the median value of the combined spectra is then scaled to
          the number of integrated pixels.

        :param mean_flux: If True, the mean spectrum (ie per pixel
          flux) is returned.


        :param region: A ds9-like region file or a list of pixels
          having the same format as the list returned by np.nonzero(),
          i.e. (x_positions_1d_array, y_positions_1d_array).

        :param median: If True, a median is used instead of a mean to
          combine spectra. As the resulting spectrum is integrated,
          the median value of the combined spectra is then scaled to
          the number of integrated pixels.

        :param mean_flux: If True, the mean spectrum (ie per pixel
          flux) is returned.

        .. note:: the region must not have a size greater than 400x400
          pixels. If you really need a larger region, you can split
          you region into smaller ones and combines the resulting
          spectra.


Parallelize a function applied to a list of integrated
        regions extracted from the spectral cube.

        the function must be defined as func(spectrum_bundle, *args)

        theta_orig is the mean original incident angle in the integrated region.


Parallelize a function taking binned spectra of the cube as
        an input. All pixels are gone through unless a mask is passed
        which indicates the pixels that must be processed. The typical
        results returned are maps.

        :param func: The parallelized function. Must be func(spectrum,
          *args, kwargs_dict) which returns a dict of floating values
          (e.g. {a:1.9, b:5.6, ...}) or a 1d array of floats. If it
          returns a dict out must be set to dict(), its default
          value. If a 1d array of size N is returned, the out param must
          be set to a 3d array of shape (cube.dimx, cube.dimy, N). If
          supplied, kwargs are passed to the function as the last
          argument in a dict object.  Note also that velocity will not
          be corrected on the fly at data extraction so that the called
          function must handle it.

        :param args: List of arguments passed to the
          function. arguments can be a function in which case the
          function must be f(x,y), x and y being the pixel
          coordinates. Note that x and y can also be lists of
          coordinates in which case the function must return a list of
          data.

        :param modules: Modules to import to run the function.

        :param out: depends on the returned values of func. See param
          func.

        :param kwargs: kwargs of the function func. If supplied,
          kwargs are passed to the function as the last argument in a
          dict object.

        :param mask: a 2d array of bool. Ones giving the pixels on
          which the function must be applied.

        :param binning: On-the-fly data binning.

        .. note:: Any argument with a shape equal to the x,y shape of
          the cube (or the binned x,y shape) will be mapped, i.e., the
          argument passed to the vector function will be the value
          corresponding to the position of the extracted
          spectrum. (works also for 3d shaped arguments, the 3rd
          dimension can have any size)


Basic row processing for a vector function


Return the path to the hdf5 bundle


Return the path to a map of one gaussian fit parameter for
        one given emission line.

        :param line_name: Name of the emission line

        :param param: Parameter name

        :param binning: (Optional) Binning of the map. If not given
          instance binning is used (default None).


save class as an HDF5 file


Write all maps to disk in fits format.


Return the path to an integrated spectrum fit

        :param region_name: Name of the region


Return the path to an integrated spectrum

        :param region_name: Name of the region


Return path to the estimated parameter frame


        Fit integrated spectra and their emission lines parameters.

        :param regions_file_path: Path to a ds9 reg file giving the
          positions of the regions. Each region is considered as a
          different region.

        :param subtract: Spectrum to subtract (must be a spline)

        :param plot: (Optional) If True, plot each intergrated spectrum along
          with the its fit (default True).

        :param verbose: (Optional) If True print the fit results
          (default True).

        :param max_iter: (Optional) Maximum number of iterations
          (default None)


Fit lines of a spectrum extracted from a circular region of a
        given radius.

        :param x: X position of the center

        :param y: Y position of the center

        :param r: Radius. If 0, only the central pixel is extracted.

        :param lines: Emission lines to fit (must be in cm-1 if the
          cube is in wavenumber. must be in nm otherwise).

        :param nofilter: (Optional) If True, Filter model is not added
          and the fit is made with a single range set to the filter
          bandpass.

        :param subtract_spectrum: (Optional) Remove the given spectrum
          from the extracted spectrum before fitting
          parameters. Useful to remove sky spectrum. Both spectra must
          have the same size.

        :param max_iter: (Optional) Maximum number of iterations
          (default None)

        :param mean_flux: (Optional) If True the flux of the spectrum
          is the mean flux of the extracted region (default False).

        :param kwargs: Keyword arguments of the function
          :py:meth:`~SpectralCube._fit_lines_in_spectrum`.

        :returns: a tuple (axis, spectrum, fit_dict). fit_dict is a
          dictionary containing the fit results (same output as
          :py:meth:`orb.fit.fit_lines_in_spectrum`)


Fit lines of a spectrum extracted from a squared region of a
        given size.

        :param x: X position of the bottom-left pixel

        :param y: Y position of the bottom-left pixel

        :param b: Binning. If 0, only the central pixel is extracted.

        :param lines: Emission lines to fit (must be in cm-1 if the
          cube is in wavenumber. must be in nm otherwise).

        :param nofilter: (Optional) If True, Filter model is not added
          and the fit is made with a single range set to the filter
          bandpass.

        :param subtract_spectrum: (Optional) Remove the given spectrum
          from the extracted spectrum before fitting
          parameters. Useful to remove sky spectrum. Both spectra must
          have the same size.

        :param max_iter: (Optional) Maximum number of iterations
          (default None)

        :param mean_flux: (Optional) If True the flux of the spectrum
          is the mean flux of the extracted region (default False).

        :param kwargs: Keyword arguments of the function
          :py:meth:`orb.fit.fit_lines_in_spectrum`.

        :returns: a tuple (axis, spectrum, fit_dict). fit_dict is a
          dictionary containing the fit results (same output as
          :py:meth:`orb.fit.fit_lines_in_spectrum`)


Fit lines of a spectrum integrated over a given region (can
        be a list of pixels as returned by the function
        :py:meth:`numpy.nonzero` or a ds9 region file).

        :param region: Region to integrate (can be a list of pixel
          coordinates as returned by the function
          :py:meth:`numpy.nonzero` or the path to a ds9 region
          file). If it is a ds9 region file, multiple regions can be
          defined and all will be integrated into one spectrum.

        :param lines: Emission lines to fit (must be in cm-1 if the
          cube is in wavenumber. must be in nm otherwise).

        :param nofilter: (Optional) If True, Filter model is not added
          and the fit is made with a single range set to the filter
          bandpass.

        :param subtract_spectrum: (Optional) Remove the given spectrum
          from the extracted spectrum before fitting
          parameters. Useful to remove sky spectrum. Both spectra must
          have the same size.

        :param max_iter: (Optional) Maximum number of iterations
          (default None)

        :param mean_flux: (Optional) If True the flux of the spectrum
          is the mean flux of the extracted region (default False).

        :param kwargs: Keyword arguments of the function
          :py:meth:`~SpectralCube._fit_lines_in_spectrum`.

        :returns: a tuple (axis, spectrum, fit_dict). fit_dict is a
          dictionary containing the fit results (same output as
          :py:meth:`~SpectralCube._fit_lines_in_spectrum`)


Fit lines in a given region of the cube. All the pixels in
        the defined region are fitted one by one and a set of maps
        containing the fitted paramaters are written. Note that the
        pixels can be binned.

        :param region: Region to fit. Can be a path to a ds9 file, a
          string defining the region in ds9 format or a boolean map
          (i.e. a mask) of the same dimension as the cube field of
          view where 1s stand for pixels that should be fitted. If a
          ds9 file, multiple regions can be used to define the fitted
          region. They do not need to be contiguous.

        :param lines: Emission lines to fit (must be in cm-1 if the
          cube is in wavenumber. must be in nm otherwise).

        :param binning: Binning of the extracted spectra.

        :param nofilter: (Optional) If True, Filter model is not added
          and the fit is made with a single range set to the filter
          bandpass (default True).

        :param subtract_spectrum: (Optional) Remove the given spectrum
          from the extracted spectrum before fitting
          parameters. Useful to remove sky spectrum. Both spectra must
          have the same size.

        :param max_iter: (Optional) Maximum number of iterations
          (default None)

        :timeout: (Optional) max processing time per pixel. If reached, the given
          pixel is passed (default None).

        :param kwargs: Keyword arguments of the function
          :py:meth:`~SpectralCube._fit_lines_in_spectrum`.

        .. note:: You can pass the fitting parameters (e.g. pos_cov,
          sigma_cov etc.) as maps (a 2d numpy.ndarray instance or a
          path to a map). But you have to append the suffix '_map' to
          the parameter you want to map. Nans will generate
          errors. This mode is best used once the velocity parameter
          has been estimated with estimate_parameters_in_region().


Fit the lines in a region given the velocity estimates
        computed with estimate_velocity_in_region(). All common
        fitting parameters are automatically set but they can also be
        set by the user using the same arguments as
        fit_lines_in_region().

        :param: ncomp, the number of components to fit. Only the
          pixels with this exact number of components will be
          fitted. If the velocity estimate was made with more than one
          component, the user must run this method for every number of
          detected components (see example in the documentation for a
          script which does the entire fit automatically for a large
          number of components).

        :param lines: Set the lines to fit (for one velocity
          component). If None, common emission lines in the filter are
          automatically choosen.

        :param folder: Path to the folder containing the
          estimate_velocity maps if they are in a different folder
          than the default one.

        :param mask: Additional mask to apply on the fitted
          region. Useful to fit only on a small part of the cube if
          the estimate was done on a much larger area. Can be a path
          to a ds9 file, a string defining the region in ds9 format or
          a boolean map (i.e. a mask) of the same dimension as the
          cube field of view where 1s stand for pixels that should be
          fitted. If a ds9 file, multiple regions can be used to
          define the fitted region. They do not need to be contiguous.

        .. note:: Other parameters are the same as in
          fit_lines_in_region().


Detect and estimate the most probable velocities and
        fluxes of a set of emission lines in an entire region of the
        cube. Multiple components (same set of emission lines,
        different velocities) can be detected

        :param lines: Emission lines to fit (must be in cm-1 if the
          cube is in wavenumber. must be in nm otherwise).

        :param region: Region to fit. Multiple regions can be used to
          define the fitted region. Can be a path to a ds9 file, a
          string defining the region in ds9 format or a boolean map
          (i.e. a mask) of the same dimension as the cube field of
          view where 1s stand for pixels that should be fitted. If a
          ds9 file, multiple regions can be used to define the fitted
          region. They do not need to be contiguous.

        :param vel_range: A tuple (vel_min, vel_max) of the range of
          velocities to try.

        :param max_comps: Maximum number of components to detect. The
          number of detected components can be lower.

        :param threshold: Detection threshold as a factor of the std
          of the calculated score.


Return path to the sky map file containing the results of
        the fit.


Return path to the sky map file containing the interpolated
        sky velocity map.


Return path to the generated deep frame with the reocmputed
        WCS.


Return path to the calibration map computed when fitting
        sky lines. Can be used instead of the original calibration
        map.


Return path to the wavefront map computed when fitting the
        calibration laser map with a different calibration laser
        wavelength. Can be used instead of the original wavefront map
        during a reduction


Map the sky velocity on a rectangular grid and interpolate it
        to return a map of the velocity zero point that can be
        subtracted to the returned velocity map of the cube fit.

        :param mean_sky_vel: (Optional) Mean sky velocity (in km/s).

        :param div_nb: (Optional) Number of division on one axis of
          the rectangular grid. The total number of points is div_nb^2
          (default 15).

        :param plot: (Optional) If True, output plots are shown
          (default True).

        :param x_range: (Optional) Range of pixels along the X axis
          where the velocity is measured (default None).

        :param y_range: (Optional) Range of pixels along the Y axis
          where the velocity is measured (default None).

        :param exclude_reg_file_path: (Optional) Region to exclude
          from the computation (must be a ds9 reg file)

        :param no_fit: (Optional) Do not repeat the fitting
          process. Only recompute the velocity map model.

        :param threshold: (Optional) If not None, this threshold on
          the velocity uncertainty is used in place of an automatic
          threshold.


Detect emission line sources in the spectral cube

        :param fast: (Optional) Fast detection algorithm (with FFT
          convolution). Borders of the frame are wrong but process is
          much faster (default True).


Make a new registration of the cube.

        :param distortion_map: A path to a FITS image containing an
          SIP distortion model. It can be a registered image of a
          calibration field containing a lot of stars and taken during
          the same run as the science cube.


Fit a model of the spectral calibration error based on a simplified
    optical model of the interferometer.

    :param x: Positions of the velocities along x axis

    :param y: Positions of the velocities along y axis

    :param vel: Measured velocity errors at (x, y)

    :param vel_err: Uncertainty on the measured velocity errors.

    :param nm_laser: Calibration laser wavelength in nm

    :param calibration_laser_map: Calibration laser map

    :param pixel_size: Pixel size in um

    param binning: (Optional) Binning during computation (process is faster with
      marginal precision loss) (default 6)


converts conserved variables to primitives (and de-scales to cgs)


    Plot a single cadence from a TPF data cube

    Inputs:
    ---------
    singleImage
        (np 2d array) Image to plot

    Optional Inputs:
    ----------------
    hdr
        Header from fits file
    axis
        ('relative' of 'fixed'). If set to fixed, and hdr is set,
        the axis labels are in units of pixels. If relative,
        the bottom left of the image is labeled as pixel 0,0

    Additional arguments passed to mp.imshow


Confirm that a load() function in octave will hang in parallel
    mode.

    Simple test case. Run a task that includes an octave load()
    call.


See if code works when mat loading is done by scipy


Extract a lightcurve from a TPF cube.

    Inputs:
    cube    (3d numpy array) As returned by getTargetPixelArrayFromFits()
    mask    (2d numpy array) Which pixels to use in extraction. Default
            is all finite pixels

    Returns
    A 1d numpy array

    Notes:
    Pixels marked Nan (i.e outside the aperture) are ignored regardless
    of the mask value.

    Default mask includes all finite pixels.

    To extract only the optimal aperture use
    mask = np.where(mask == 3, 1, 0)
    lightCurveFromTpfCube(cube, mask)


Extract the detrended flux for PDC data


Extract the detrended flux for Suzanne Aigrain's K2SC data


Compute the indices of time1 that correspond closest to values of time2

    Some K2 detrended lightcurves (like PDC) contain elements for every
    cadence, others (like sff) only contain elements for good data.
    This function enables you to figure out which rows of time1 correspond
    to the same times in time2, so you can place place the first and second
    data sets in contiguous arrays

    Typical Usage:
    ----------------
    A typical usage would look like
    ::
        idx = mapTime2ToIndexOfTime1(data1[:, 'TIME'], data2[:, 'TIME'])
        data1[idx, 'FLUX2'] = data2[:, 'FLUX']
        data1[~idx, 'FLUX2'] = BAD_VALUE

    Inputs:
    ------------
    time1:
        (1d np array) Array of times to map into
    time2
        (1d np array) Array of times to map from. Typically ``len(time2) < len(time1)``

    Returns:
    -----------
    A boolean array of length ``time1``


Loads many quarters of PDC and stitches them together

        Input:
        archive:        A mastio.KeplerArchive object
        kepid           (int) kepid of target of interest
        quarterList     (int list), which quarters to download

        Optional Inputs
        lcType                  Either PA or PDC. Case insensitive
        nCadencesForSmooth      If applying median filtering, how
                                wide should the filter be. Default is
                                to not smooth.
        fitCubic                Should a cubic polynomial be removed
                                from each quarter before merging.
                                Only useful for PDC.
        removeEarthPoint        Remove a number of cadences after
                                every cadence marked as Earthpoint.
        doMedianZero            Convert to fractional amplitude

        Returns:
        A two-d numpy array of all available data for the target for the
        requested quarter. Flagged cadences are removed. The PDC column
        is median zeroed and a cubic polynomial is removed from each
        quarter before stitching.

        Note:
        Fitting cubic is broken, and trying to use it will raise
        an exception (until I get around to fixing it)


Remove trends from data

    Simplest possible lightcurve cleaning algorithm to clean data
    by subtracting off the median. Tested on single quarter data only,
    and enjoys only limited success.

    Inputs:
    data:    (2d numpy array) Data to be smoothed, as loaded from loadData()
    nPoints: How many adjacent points to be used in calculating the median
    fCol:    Which column of data contains the flux.

    Returns:
    data, with data[:,fCol] detrended


Quick and dirty median smooth function.
    Not designed to be at all effecient


    Inputs:
    order   (int) order of fit. A good value for PDC of 3 (which fits
            cubic, i.e 4 parameters)


If x= data[:,col], set x = (x/median(x) - 1

        Note:
        This function is preferable to meanZero when the data has outliers.


Create a logical array indicating which cadences are
    affected by a transit

    Input:
    -------------
    time:
        (numpy 1d array) array of cadence times
    period_days:
        Transit period
    epoch_bkjd:
        Transit epoch
    duration_days:
        Duration of transit (start to finish). If you
        select a duration from first to last contact,
        all cadences affected by transit are selected.
        If you only select 2 to 3 contact, only the
        interior region of the transit is selected
    numberOfDurations
        How much of the lightcurve either side of
        the transit to mark. Default means to mark
        1/2 the transit duration either side of
        transit center.

    Optional Inputs:
    flags:
        If set, must be an array of booleans of length ``time``.
        Cadences where this array is true are ignored in the
        calculation. This is useful if some of the entries of time
        are Nan.

    Returns:
    -------------
    Array of length len(time) of booleans. Element set to true
    are affected by transits


Take Kepler multi quarter data and insert zeros where no data is present.
    This results in regularly spaced data.

    Inputs:
    data    Numpy array as returned by kplrfits.loadMultiQuarter()

    Optional Inputs:
    missingValue    (float) What value to enter for cadences where there is
                    no data


Input arg **quarter** is not used in this function


Override MastArchive.parse()

        Mast data is usually stored as fits files, but Vanderburg lightcurves
        are plain text.


Download data from MAST archive for a given filename and a
        given quarter.

        Inputs:
        clobber:    If true, allow locally existing files to be overwritten
        verbose:    If true, print the file meta-information


Load data using favourite IO class

        Assumes that localUrl exists on disk. Default file format
        for MAST is FITS, but sub-classes can override this method
        for other file types as necessary


Figure out the URL where the desired file is stored.

        Returns a string, typically similar to
        http://archive.stsci.edu/$remotePath/.../$filename


    Vet the centroid time series produced by measureDiffOffset()

    Measure the probablity that the observed difference image centroid-
    offsets indicate that the transit happened off target.

    Inputs:
    --------
    offsets
        (Nca) The return value from measureDiffOffset

    Optional Inputs:
    ------------------
    minNumPoints
        (int) Minimum number of points needed before computing result.
        Currently set to the minimum needed by covar (==2)

    Returns:
    -----------
    A tuple with 2 values

    prob
        Probability the transit happened off target
    chi2
        The chi-squared corresponding to that probability

    Notes:
    ---------
    For highly significant offsets, the probability flatlines at zero for
    values below ~1e-40. The chi-squared value then can be used to indicate
    the significance of the offset.


Measure Centroid shift between intransit and difference image
    for every in-transit cadence

    Inputs:
    -----------
    period_days, epoch_bkjd, duration_hrs
        (floats) Properties of transit

    time_bkjd
        Array of times per cadence for the given campaign

    prfObj
        An object of the class prf.KeplerPrf()

    ccdMod, ccdOut
        (int) CCD module and output of image. Needed to
        create the correct PRF model

    cube
        (3d np array) A data cube created from a TPF file.
        See fileio.tpf.getTargetPixelArrayFromFits()

    bbox
        [c1, c2, r1, r2]. Define the range of columns (c1..c2)
        and rows (r1..r2)  defined by the image.
        An exception raised if the following equality not true
        img.shape = (c2-c1), (r2-r1)

    rollPhase
        (1d np array) An array of roll phases for each row
        of cube. len(rollPhase) == len(cube). Units of this
        array don't matter, so long as cadences with similar
        roll angles have similar values of rollPhase. Roll phases
        for bad cadences should be set to a bad value

    flags
        (1d array) flag values indicating bad cadences.
        Currently a non-zero value of flags indicates a bad
        cadence.

    qFlags
        (1d array) SAP Quality flags from lightcurve files

    Returns:
    -------------
    A array with 5 columns, and as many rows as there are
    in transit cadences. The columns are

    0: Relative cadence number
    1: In transit centroid column
    2: In transit centroid row
    3: Diff img centroid column
    4: Diff img centroid row

    If there is a statisically significant difference between the intransit
    and difference image centroids then the transit is most likely not
    on the target.


Measure image centroid of in-transit and difference images

    Inputs:
    -----------
    prfObj
        An object of the class prf.KeplerPrf()

    ccdMod, ccdOut
        (int) CCD module and output of image. Needed to
        create the correct PRF model

    cube
        (3d np array) A TPF data cube as returned by
        dave.fileio.getTargetPixelArrayFromFits()

    rin
        (int) Which image to process. rin should be in the range 0..len(cube)

    bbox
        [c1, c2, r1, r2]. Define the range of columns (c1..c2)
        and rows (r1..r2)  defined by the image.
        An exception raised if the following equality not true
        img.shape = (c2-c1), (r2-r1)

    rollPhase
        (1d np array) An array of roll phases for each row
        of cube. len(rollPhase) == len(cube). Units of this
        array don't matter, so long as cadences with similar
        roll angles have similar values of rollPhase

    flags
        (1d array) flag values indicating bad cadences.
        Currently a non-zero value of flags indicates a bad
        cadence.

    Optional Inputs:
    ---------------
    hdr
        Fits header object for TPF file. Useful if you want to plot

    plot
        (bool) Request plots.

    Returns:
    -------------
    A two element tuple

    A 4 element numpy array
    ic  In transit centroid column
    ir  In transit centroid row
    dc  Difference image centroid column
    dr  Difference image centroid row

    A dictionary containing some diagnostics describing the cadences used
    then creating the difference image.


Fit a PRF model to a TPF image and measure star centroid

    Given a cadence image from a TPF file, find the best fitting
    PRF model for that image. The best fit column and row of the
    PRF model can be treated as the photometric centroid of the
    light distribution from a single isolated star.

    Inputs:
    ---------
    img
        (np 2d array) Image of star to be fit. Image is in the
        format img[row, col]. img should not contain Nans

    ccdMod, ccdOut
        (int) CCD module and output of image. Needed to
        create the correct PRF model

    bbox
        [c1, c2, r1, r2]. Define the range of columns (c1..c2)
        and rows (r1..r2)  defined by the image.
        An exception raised if the following equality not true
        img.shape = (c2-c1), (r2-r1)

    prfObj
        An object of the class prf.KeplerPrf()

    Returns:
    ------------
    A scipy.optimise.OptimizeResult object. The best fit
    params are stored in OptimizeResult.x

    Notes:
    ----------
    The return object will frequently set success=False. I've seen no
    evidence that a failed fit give worse results than a successful fit.
    It appears that the fit likes to fall over when it gets very close
    to the minimum.

    In tests, the fitter often returns a best fit at a subpixel position
    adjacent to the true best fit position (i.e .02 pixels away in either
    column and/or row). This is a smaller distance than I'm concerned
    about for my use case, but if you need really accurate positions
    (say for PSF photometry), you may want to explore around the returned
    best fit position for the optimal fit.

    See example() in this module for an example of use


Some diagnostic plots showing the performance of fitPrfCentroid()

    Inputs:
    -------------
    img
        (np 2d array) Image of star to be fit. Image is in the
        format img[row, col]. img should not contain Nans

    hdr
        (Fits header object) header associated with the TPF file the
        image was drawn from

    ccdMod, ccdOut
        (int) CCD module and output of image. Needed to
        create the correct PRF model

    prfObj
        An object of the class prf.KeplerPrf()

    Returns:
    -------------
    **None**

    Output:
    ----------
    A three panel subplot is created


Measure goodness of fit (chi-square) for a PRF
    with a given col, row and scale (i.e brightness)


Debugging function.

    Does the same as costFunc, but col and row are constants,
    and only the brightness of the prf can be changed.


Fit a PRF to an image

    Inputs
    --------
    img
        (2d numpy array) Image to fit
    prfFunc
        (function) Model to fit. See module level documentation for more details.
    guess
        (tuple or array) Arguments prfFunc

    Returns
    ------------
    A scipy.optiminze.ResultsObject. The .x attribute contains the best fit parameters

    Example
    ----------
    To fit a model with the signature (col, row, flux, width), the guess array would be of
    length 2.


A complicated piece of code used by numba to compile the PSF.

    This one works for `gaussianWithConstantSkyPsf()`


A model PSF of a 2d symettric gaussian with a constant background

    Inputs
    ---------
    col, row
        (floats) Which location to compute PSF for
    col0, row0
        (floats) Centre of psf
    sigma
        (float) Width of the Gaussian
    flux0
        (float) Height of the gaussian (sort of)
    sky
        (float) Background level

    Returns
    --------
    (float)


Compute difference between image and its model for given model params

    Inputs
    ----------
    arglist
        (tuple or array) Tunable parameters of model
    func
        (function) Model to fit
    img
        (2d np array) Image to fit

    Optional Inputs
    ----------------
    mask
        (2d np array) Zero elements of mask indicate bad data which should not be
        included in the fit

    Returns
    ----------
    float


Compute model flux for an image with size (numCols, numRows)

    Inputs
    -------
    numCols, numRows
        (ints) Shape of the image to compute the model PRF for
    func
        (function) Model PRF
    arglist
        (tuple or array) Tunable parameters of the model

    Returns
    ----------
    A 2d numpy array representing the model PRF image.


Compute arclength along the main eigenvector for each centroid point

    Inspired by similar approach by Vanderburg  & Johnson (2014)

    This is done slightly differently to V&J. I don't bother computing
    arclength along the fit, I just say how far along the eigenvector
    each centroid point lies. This is noisier than their approach, but
    simpler to implement.

    Inputs:
    -------------
    cent
        (2d numpy array) Array of centroid positions. Zeroth col is column
        position, and 1st col is row position. Bad values should be stripped
        out of this array before calling compute arclenght.

    Returns:
    A numpy array of shape cent. The zeroth column is the value of arclength
    for each input row.


getPrfAtColRow() should return same value whether input is int or float


Test that changing column fraction moves flux around


Function to help measure timings


Fit some Kepler data as an example


Map sector of observation to PRF sector file number.

        At the start of the mission, the same PRFs apply to all sectors. In the future,
        a second PRF file may be released. If that happens, encode the logic of mapping
        sector to file number in this method.

        And remember to update the docstring when you do.


Interpolate between 4 images to find the best PRF at col, row

        This is a private function of the class.

        TODO: Make sure this is right.


Fit a Symmetric Gaussian PSF to an image, really quickly

    Inputs
    --------
    img
        (2d numpy array) Image to fit
    prfFunc
        (function) Model to fit. See module level documentation for more details.
    guess
        (tuple or array) Elements are
        * col0, row0
            Location of PSF centroid
        * sigma
            Width of gaussian
        * flux
            Height of gaussian. Beware this is not normalized
        * sky
            Background level

    Returns
    ------------
    A scipy.optiminze.ResultsObject. The .x attribute contains the best fit parameters


Compute integral of gaussian function in the range (-Inf, z],

    `z` is defined as (x - x0) / sigma, where x0 is the central value of the Gaussian.

    See `scipy.special.erf` for details


First TCE on TIC 307210830 in second sector


Generate a difference image.

    Also generates an image for each the $n$ cadedences before and after the transit,
    where $n$ is the number of cadences of the transit itself

    Inputs
    ------------
    cube
        (np 3 array) Datacube of postage stamps
    transits
        (2-tuples) Indices of the first and last cadence

    Optional Inputs
    -----------------
    plot
        (Bool) If true, generate a diagnostic plot

    Returns
    -------------
    Three 2d images,

    before
        The sum of the n cadences before transit (where n is the number of in-transit cadences
    after
        The sum of the n cadences after transit
    diff
        The difference between the flux in-transit and the average of the flux before and after

    Notes
    ---------
    When there is image motion, the before and after images won't be identical, and the difference
    image will show distinct departures from the ideal prf.


Wrapper function for difference image centroid diagnostic plots

    Call this function from the exporter.

    Inputs:
    -----------
    clip
        A clipboard object. Should have the following keys: serve, detrend, diffImg, rollPhase, trapFit

    Returns:
    -----------
    Two figure handles. The zeroth figure handle shows the flux and rollPhase
    plot, the first shows the centroid offset plot

    Outputs:
    ------------
    Two figures are produced.


Plot the row and column of the intranst centroids and the difference
    image centroids


Plot the centroid offsets in column and row

    Inputs:
    ----------
    centroids:
        (Nca) As stored in ``clip['diffImg.centroid_timeseries']``

    Returns:
    ----------
    A string containing the probability the measured centroids are consistent
    with no offset

    Output:
    ------------
    A plot is added to the current figure.


Plot the flux and roll phase time series.

    A multi panel plot with three panels for the flux time series,
    and three for the roll phase time series. Cadences in transit are marked
    with blue or red squares. Blue indicates a difference image was successfully
    created, red indicatese no difference image.

    Each time series is spread over three panels to better show the details.
    Panels showing common sections of the timeseries are highlighted
    with the same background colour.

    Inputs:
    ----------
    time
        (1d numpy array) X axis for plot

    flux
        (1d numpy array) Flux time series

    flags
        (1d numpy boolean array) Cadences where flags is set are considered
        bad and not plotted.

    rollPhase
        (1d numpy array) Roll phase time series

    inTransitIndices
        (1d numpy boolean array) Which cadences are in transit

    goodCentroidIndices
        (1d numpy boolean array) Which cadences have centroids measured.

    Returns:
    ----------
    **None**

    Output:
    ------------
    A plot is added to the current figure.


Plot a time series

    Also marks cadences with thruster firings with vertical lines on the plot,
    and the location of cadences in transit, and cadences with measured centroids


Mark cadences with thruster firings

    Inputs:
    ----------
    qualityFlags
        (1d numpy array) Quality flags as found in lightcurves and TPF
        files. This is not a boolean array, but an array of flag masks.
        Must include a bit for thruster firings.

    Optional Inputs:
    -----------------
    xval
        (1d array) Values of x axis to plot (eg the time, or cadence number)
        Defeault is 1.. len(qualityFlags)

    All other optional arguments passed to matplotlibs axvline

    Returns:
    ----------
    **None**

    Output:
    ----------
    A series of vertical lines are added to the current plotx


Construct a difference image for a single K2 cadence

    K2's roll motion makes constructing difference images harder
    than it was in Classic Kepler. The star can not be assumed
    to be in a similar location on the focal plane in any other
    cadence. To construct difference images, this function
    interpolates between cadences of similar roll angles to
    construct an "out-of-transit" image

    Inputs:
    -------------
    cube
        (3d np array) A data cube created from a TPF file.
        See fileio.tpf.getTargetPixelArrayFromFits()
    indexOfCadenceInTransit
        (int) Specify which row of cube to construct a difference
        image for

    rollPhase
        (1d np array) An array of roll phases for each row
        of cube. len(rollPhase) == len(cube). Units of this
        array don't matter, so long as cadences with similar
        roll angles have similar values of rollPhase

    flags
        (1d array) flag values indicating bad cadences.
        Currently a non-zero value of flags indicates a bad
        cadence.

    Returns:
    ------------
    A 3 element list, [diff, oot, diagnostics]
    diff is a 2d np array corresponding to the difference image
    oot is a 2d np array corresponds to the reconstructed image
    subtracted from cube[indexOfCadence] in transit.

    diff = cube[indexOfCadenceInTransit] - oot

    diagnostics is a dictionary of details of how the image was
    constructed.

    Notes:
    ---------
    In keeping with the Classic Kepler convention, a flux decrement
    in a cadence (e.g a transit) appears as a positive feature in
    the difference image.

    Todo:
    ---------
    I should do a better job picking which cadences are bad.
    Not all flags indicate a cadence is untrustworthy.


Only works on my machine


Get the prf for an image described by a bounding box

        This function requires as input a function to look up the PRF for a given col row
        (getPrfFunc). This function is not implemented in the base class, as it will be
        specific to each mission. The design intent is that you override getPrfForBbox()
        in the daughter class where
        you define the lookup function, then calls the parent class method.
        See KeplerPrf() for an example

        Input:
        -----------
        col, row
            (floats) Centroid for which to generate prf
        bboxIn
            (int array). Size of image to return. bbox
            is a 4 elt array of [col0, col1, row0, row1]
        getPrfFunc
            (function) Function that returns a PRF object
            This function must have the signature
            ``(np 2d array = getPrfFunc(col, row, *args)``

        Optional Inputs
        -----------------
        Any optional inputs get passed to getPrfFunc

        Returns:
        ----------
        A 2d numpy array of the computed prf at the
        given position.

        Notes:
        ------------
        If bbox is larger than the prf postage stamp returned,
        the missing values will be filled with zeros. If
        the bbox is smaller than the postage stamp, only the
        requestd pixels will be returned


Compute arclength along the main eigenvector for each centroid point

    Arclength is a number which describes how much the spacecraft has
    rolled from some nominal position. The nominal position is the
    mean roll angle.

    Inspired by similar approach by Vanderburg  & Johnson (2014)

    This is done slightly differently to V&J. I don't bother computing
    arclength along the fit, I just say how far along the eigenvector
    each centroid point lies. This is noisier than their approach, but
    simpler to implement.

    Inputs:
    -------------
    cent_colrow
        (2d numpy array) Array of centroid positions. Zeroth col is column
        position, and 1st col is row position. Bad values should be stripped
        out of this array before calling compute arclenght.

    flag
        (1d np array) Array of flags showing which cadences are flagged
        as bad.

    Returns:
    ----------
    A numpy array of shape cent. The zeroth column is the value of arclength
    for each input row.


Place a rectangular apeture over the prf

        Note this will fail if the image aperture doesn't wholly
        overlap with bestRegPrf


A bare bones main program


Load the default pipeline configuration and adjust as necessary


Run func over every element on iterable in parallel.

    Inputs:
    ----------
    func
	(A function) The top level function, e.g runOne(), below

    iterable
	(list, array, etc.) A list of values to operate on.

    config
	(Clipboard) A configuration clipboard.


Run the pipeline on a single target.

    Inputs:
    ------------
    k2id
        (int) Epic id of target to run on.

    config
        (dict) Dictionary of configuration parameters as created by, e.g
        loadMyConfiguration()

    Returns:
    ---------
    A clipboard containing the results.

    Notes:
    ---------
    Don't edit this function. The pipeline can recover gracefully from
    errors in any individual task, but an error in this function will crash
    the pipeline


Replace Nans in a lightcurve with interpolated values

    Algorithm distinguishes between short gaps and long gaps.
    Short gaps are replaced with the average of nearby values.
    Long gaps are replaced with the fit of a cubic polynomial
    to the data near the gap.

    Gapped data is assumed to have the value of nan.

    Inputs:
    --------------
    yInput:
        (1d np array) Input flux to be filled. Assumed to be
        equally spaced.

    Optional Inputs:
    ------------------
    shortGapSize
        (int) Maximum size of a short gap. Must be at least 2.

    Returns:
    ------------
    (gapFilledFlux, indexOfGappedCadences)
    A tuple of 2 1d arrays. The first array is the gap filled
    flux, the second is a boolean array of the modified elements
    in the first array.


Find plateaus in an array, i.e continuous regions that exceed threshold

    Given an array of numbers, return a 2d array such that
    out[:,0] marks the indices where the array crosses threshold from
    below, and out[:,1] marks the next time the array crosses that
    same threshold from below.

    Inputs:
    array       (1d numpy array)
    threshold   (float or array) If threshold is a single number, any point
                above that value is above threshold. If it's an array,
                it must have the same length as the first argument, and
                an array[i] > threshold[i] to be included as a plateau

    Returns:
    Numpy 2d array with 2 columns.

    Notes:
    To find the length of the plateaus, use
    out[:,1] - out[:,0]

    To find the length of the largest plateau, use
    np.max(out[:,1] - out[:,0])

    The algorithm fails if a value is exactly equal to the threshold.
    To guard against this, we add a very small amount to threshold
    to ensure floating point arithmetic prevents two numbers being
    exactly equal.


Takes out NaNs from a pixel time series

    Takes out NaNs in each pixel's time series and replaces them by filling in
    the gaps using interpolation methods.

    If a single pixel's time series is made up of all NaNs, replace all of the
    NaNs with 0

    Notes:
    -----------
    For more information, see gapfill.py

    Inputs:
    ----------
    pixSeries
        (2d numpy array) Size: (number of pixels in cadence, number of time
        points)
        The 3d data cube reshaped to a 2d array to make it easy to iterate over

    Returns:
    ------------
    newPixSeries
        (2d numpy array) Size: (number of pixels in cadence, number of time
        points)
        The input array with all of the NaNs taken out


Checks if any NaNs are present in the pixel time series

    Iterates through a list of single pixel time series and takes the sum of
    the series. If the sum is NaN, we know there is a NaN present in the series

    Inputs:
    ----------
    pixSeries
        (2d numpy array) Size: (number of pixels in cadence, number of time
        points) The 3d data cube reshaped to a 2d array to make it easy to
        iterate over.

    Returns:
    ----------
    A boolean. True if there are NaNs, false if there are no NaNs


Normalizes the pixel time series by the standard deviation method

    Normalizes by taking the pixel time series, subtracting the mean, and
    dividing by the standard deviation of the series

    Inputs:
    ----------
    pixSeries
        (2d numpy array) Size: (number of pixels in cadence, number of time
        points) The 3d data cube reshaped to a 2d array to make it easy to
        iterate over.
        Note: This series should have the NaNs taken out of it first

    Returns:
    ------------
    pixSeriesNorm
        (2d numpy array) Size: (number of pixels in cadence, number of time
        points)
        The normalized input array


Obtains the principal components of the pixel time series

    Uses the numpy.linalg.svd function to compute the principal components of
    the single pixel time series which are non-zero. The svd function returns
    a tuple of values, the second index being a 2d numpy array of the principal
    components with size (number of components, time steps).

    Notes:
    -----------
    More information on the numpy svd function can be found
    `here <http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.svd.html>`_

    Inputs:
    ----------
    pixSeriesNorm
        (2d numpy array) Size: (number of pixels in cadence, number of time
        points)
        The 3d data cube reshaped to a 2d array to make it easy to iterate over
        Note: The time series should be normalized first using the normalize()
        function

    Returns:
    ------------
    prinComps
        (2d numpy array) Size: (number of components, time steps)
        Numpy array of the principal components, ranked from most influential
        to least (i.e. prinComps[0] is the most dominant component in the light
        curve)


Fits the desired number of principal components to the raw light curve

    Uses the numpy.linalg.lstsq function to get a vector of coefficients which
    is then used to generate the best fit for the desired number of principal
    components by multilying the matrix of principal components by the vector
    of coefficients. The resulting vector is the best fit light curve.

    Notes:
    -----------
    More information on the numpy lstsq function can be found
    `here <http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.lstsq.html>`_

    Inputs:
    ----------
    prinCompsToFit
        (2d numpy array) Size: (number of principal components to fit, time
        steps)
        This is a 2d matrix of the principal components to use in generating
        the best fit to the total raw light curve.
    totLightcurve
        (1d numpy array) Array of summed raw light curve generated by summing
        each cadence, the length of which should be equal to the number of time
        steps for this particular data set.

    Returns:
    ------------
    fittedCurve
        (1d numpy array) This array is the best fit to the raw light curve
        using the specified principal components, the length of which is equal
        to the number of time steps for this particular data set.


Chooses the number of principal components to use in the final best fit

    This function expects a list of values generated by using Jeff Van Cleve's
    Savitzy-Golay technique. Each of these values correspond to using a
    different number of principal components in the fit and correction of the
    light curve. This function then chooses the optimal number of principal
    components by determining at what value in this list the values become
    close enough to one another to effectively treat it as a flat line. At this
    point, it is futile and even detrimental to continue adding principal
    components to the fit calculation.

    This is achieved by implementing a threshold, i.e. if the difference
    between two values becomes less than a certain threshold, the number of
    principal components used in the fit corresponding to that sgcdpp value is
    the optimal number of principal components to use.

    Notes:
    -----------
    More information on the Savitzy-Golay technique can be found in
    dave.misc.noise

    Inputs:
    ----------
    sgcdppList
        (1d array) A list of values obtained by the Savitzy-Golay technique.
        Each value corresponds to the calculation done with a fit using a
        different number of principal components.

    Optional Inputs:
    -------------------
    thresh
        (float) Threshold to use in determining where in the list of sgcdpp
        values it starts to become effectively flat

    Returns:
    ------------
    optimalNumPC
        (int) The optimal number of principal components to use in the fit and
        correction to the raw light curve


 Prepares the data for SVD calculation and gets principal components

    Prepares the data for SVD calculation by reshaping the data cube into a 2d
    numpy array, taking out thruster firing indeces, taking out NaNs,
    generating the total raw light curve, and normalizing the pixel time series

    Ultimately gets the principal components by doing an SVD calculation

    Inputs:
    ----------
    dataCube
        (3d numpy array) Size: (timesteps, num rows, num cols) the raw data
        cube obtained from Kepler
    thrusterFireInds
        (1d boolean numpy array) True where there are known bad indeces due to
        thruster firings

    Returns:
    ----------
    prinComps
        (2d numpy array) Size: (number of components, time steps)
        Numpy array of the principal components, ranked from most influential
        to least (i.e. prinComps[0] is the most dominant component in the light
        curve)
    totLightcurve
        (1d numpy array) Array of summed raw light curve generated by summing
        each cadence, the length of which should be equal to the number of time
        steps for this particular data set.
    t
        (1d numpy array) the time steps
    numPixels
        (int) the number of pixels per cadence


Place to specify what star to get data for

    Gets the pixel time series data cube and indeces of known thruster firings
    for the star

    Inputs:
    ----------
    None

    Returns:
    ----------
    dataCube
        (3d numpy array)


Chooses the optimal # of principal components to use in the final fit

    Generates a list of sgcdpp values by doing an sgcdpp calculation (see
    noise.computeSgCdpp_ppm)

    Iterates through the list of sgcdpp values and determines where the slope
    between two values starts to "flatten out" based on a certain threshold

    Inputs:
    ----------
    prinComps
        (2d numpy array) Size: (number of components, time steps)
        Numpy array of the principal components, ranked from most influential
        to least (i.e. prinComps[0] is the most dominant component in the light
        curve)
    totLightcurve
        (1d numpy array) Array of summed raw light curve generated by summing
        each cadence, the length of which should be equal to the number of time
        steps for this particular data set.

    numPixels
        (int) the number of pixels per cadence

    Returns:
    ----------
    optimalNumPC
        (int) the optimal number of principal components to use in the best fit
        and correction to the raw light curve


Code checks to see if certain directories or files exist.


Produce a cotrended lightcurve in units of fractional amplitude


    TODO:
    This code could be considerably simplified if we set flux[singleOutlierIndices]
    ==0. Would this produce the same results?


Debugging code. Returns the ephemeris of the largest event in
    K2Id 206103150


Decide whether an event is a planet candidate or not

    TODO:
    Much of this should be parcelled off into a function


Note this is not a task, because it should run even if
    an exception is raised


input: 1d light curve array
        output: 1d array scaled so the mean is zero


    Take a clip and return an array of flags
    That give the ingress and egress times.


    return number of flags between the start and stop times.
    flags should be true false for flags you care about.


    Run just the vetting and return an output.
    Inputs:
    -------------
    k2id
        (int) Epic id of the target to run on.
    period
        (float) period of the target
    epoch
        (float) Time in days
    config
        (dict) Dictionary of configuration parameters


    Plot the data and some info from the clipboard
    output is a clipboard.


Plot individual transits
    only plot the first six if that many exist.
    Plot ndur around the center of the epochs
    ndur = 2 is typical.


Plot the bls spectrum and info about the BLS search


Take a fourier transform using nufft


Equivalent to:
       func = func_item_args[0]
       item = func_item_args[1]
       args = func_item_args[2:]
       return func(item,args[0],args[1],...)


Equivalent to:
       func = func_item_args[0]
       items = func_item_args[1]
       args = func_item_args[2:]
       return func(items[0],items[1],...,args[0],args[1],...)


    Equivalent to:
    return [function(x, args[0], args[1],...) for x in iterable]

    Keyword arguments:
       - parallel=True/False: Force parallelization on/off
       - chunksize=int: see multiprocessing.Pool().map
       - pool=multiprocessing.Pool() Pass an existing pool.
       - processes=int: see multiprocessing.Pool() processes argument


 Equivalent to:
        return [function(x1,x2,x3,..., args[0], args[1],...) for \
(x1,x2,x3...) in iterable]

    Keyword arguments:
       - parallel=True/False: Force parallelization on/off
       - chunksize=int: see multiprocessing.Pool().map
       - pool=multiprocessing.Pool() Pass an existing pool.
       - processes=int: see multiprocessing.Pool() processes argument


A decorator for a task function

    The k2phot model is that you write wrapper code around your pipeline functions
    that extract values from a clipboard to pass as input arguments,
    and store the return values back in the clipboard. This wrapper code
    is called a "task".

    This decorator watches for any exceptions thrown by the task (or
    underlying code) and decides whether to fire up the debugger to
    figure out what's going on, or to fail gracefully by merely storing
    the raised exception for later debugging. This decorator considerably reduces
    the code duplication between different tasks.

    To use this code in your function, use the following import statement
    from task import task
    then simply write the text "@text" above your task. For example

    from task import task

    @task
    def exampleTask(clip):
        pass

    See an example down below.


Decorator for a k2phot task

        Catches exceptions and either stores them or passes them to the debugger


Run func over every element on iterable in parallel.

    Not yet run or tested.

    Inputs:
    ----------
    func
	(A function) The top level function, e.g runOne(), below

    iterable
	(list, array, etc.) A list of values to operate on.

    config
	(Clipboard) A configuration clipboard.


A sample top level function to run a single instance of a pipeline

    Not yet run or tested.

    Inputs:
    ----------
    value
	(undefined)  The input value that is unique to this run, eg the name of
	the file to process, or the value to perform some computation on.

    config
	(Clipboard) A configuration clipboard. Must contain the key 'taskList'. See below

    Returns:
    -----------
    A clipboard, containing the results of the processing.

    Notes:
    ----------
    The config clipboard must contain the key taskList. taskList is
    a list of strings, each listing the function name of a task to
    run in the pipeline, in the order they should be run. The
    first task should look of the unique value in clip['value']

    The tasks as passed as strings because functions can't bepa
    ssed to parallel processes.This means that your tasks must
    be defined in scope of this file. The easiest way
    to do this looks like

    import task
    import stuff

    task.func1 = stuff.func1
    task.func2 = stuff.func2

    config['taskList'] = ["func1", "func2"]


Create a wedge plot by plotting period and epoch of all events.

    Based on similar diagnostic plot used by SOC pipeline.

    Inputs:
    -----------
    clipList
        (list) list of filenames of clips to process

    Returns:
    -----------
    A figure handle for the plot created.

    Notes:
    ----------
    Each target is represented by a semi-transparent grey dot
    indicating the period and epoch of that target. Those targets
    with the value of disposition.isCandidate are marked in red.


A plot of which cadences contribute to the most transits

    Based on similar plot created by Jessie Christiansen for the
    SOC pipeline.

    Inputs:
    -----------
    clipList
        (list) list of filenames of clips to process


Doesn't work yet


Reproducing Issue #7. Adding a tuple made asString() fail


Plot pa and pdc lightcurves


Plot the folded binned LPP light curve


    Plot individual transits
    only plot the first six if that many exist.
    Plot ndur around the center of the epochs
    ndur = 2 is typical.


Create a line of text for the exporter

    Inputs:
    ------------
    clip
        A clipboard object

    Optional Inputs:
    -----------------
    delimiter:
        (string) The character, or set of characters to separate elements

    badValue
        (string) String to be output when a value isn't present
    Returns:
    -----------
    Two strings. The first is the text to be exported. The second is the
    list of keys that were exported


    Read in a clip and create outputs.
    and appends results to a table (logTableFile)


    Given a clipboard shelf write out the detrended light curve and the time
    to the first extension.
    The resulting FITS file mimics the Kepler DV time series files.


Load a previously saved clipboard


Return a shallow copy of a clipboard


Pretty print the contents of a clip

        Optional Inputs:
        ----------------
        prefix
            Don't change this value, it's used to track the
            level of recursion

        Returns:
        ---------
        **None**

        Output:
        ---------
        Prints text to stdout.


Pretty print the contents of a clip

        Optional Inputs:
        ----------------
        prefix
            Don't change this value, it's used to track the
            level of recursion

        maxLevel
            Only descend this many levels into the clipboard
        Returns:
        ---------
        A string


Create a line of text for the exporter

    Inputs:
    ------------
    outfile
        A name for the pdf file to be written to
    clip
        A clipboard object
    intext
        A string containing information to be put on the first page.

    Takes a clipboard, clip, and create plots
    put these plots all into one multi paged document
    specifieed by outfile


Retreive a value from a list of saved clipboard files

    Inputs:
    -----------
    clipList
        A list of filenames of clipboards to read
    key
        (str) The key to search

    Returns:
    ----------
    A tuple of two lists.
    * A list of epics for the clipboards for which values were retreived
    * A list of the values of the input key for each clip

    Notes:
    ---------
    This is a thin wrapper for sweepFunction()


Retreive a value from a list of saved clipboard files

    Inputs:
    -----------
    clipList
        A list of filenames of clipboards to read

    func
        The function to apply to each clipboard. The function should
        have the signature func(clip). It must accept one and only one
        argument.

    Optional Inputs:
    -----------------
    applyFilter
        If True, remove from output any clips for which a value was not
        computed (e.g because the clipboard couldn't be loaded). If False,
        failed results are represented by **None**

    Returns:
    ----------
    A tuple of two lists.

    * A list of epics for the clipboards for which values were retreived
    * A list of the return values of the input function for each clipboard

    Notes:
    -----------
    KeyErrors in func() are caught and handled. All other errors
    raise an exception. I may be more tolerant of other errors in future,
    but right now I want to stop computation if func crashes.


Load a clipboard and apply a function to it

    Inputs:
    ----------
    clipFilename
        (string) Name of clipboard to load
    func
        (function) Function to apply. func must take one argument, a clipboard

    Returns:
    ------------
    (value, result). Value is clip['value'], result = func(clip)
    result is set to None for some errors, other errors in func() raise
    an exception


Compute probability that p is consistent with mean of distribution.

    For a 2 dimensional distribution of points, given by ``x`` and ``y``,
    compute the probability that the mean of the distribution is consistent
    with the input point ``p``

    Inputs:
    -------------
    x, y
        (float) Input values. Require that ``len(x) == len(y)``

    Optional Inputs:
    -----------------
    p
        (array of length 2) Point to test. Default is [0,0]

    Returns:
    -----------
    probOffset
        (float) Probability that input point is consistent with mean
        of distribution.
    chiSquare
        (float) The chi squared of the point. For highly inconsistent points
        the computed probability of offset flatlines at zero. The chisquare
        value can then be used to estimate the relative consistencies of
        different points.

    Notes:
    ---------
    See ``plotErrorEllipse`` for a description of the algorithm


Compute and plot error ellipses around the mean of a 2d distribution.

    Given two arrays, ``x`` and ``y`` where the values of each are drawn
    from a Gaussian distribution, but the values of ``y`` are correlated with
    the values of ``x``, compute and plot both the mean of the distribution
    and the uncertainty ellipses around that mean.

    Inputs:
    -------------
    x, y
        (float) Input values. Require that ``len(x) == len(y)``

    Optional Inputs:
    -----------------
    prob
        (list or array) List of probability contours to draw. The defaults
        are 68%, 95% and 99.7%. Each value must be in the range (0,1)

    marker
        (string) Marker type to plot the location of the mean. Default: 'o'
    mfc
        (string) Colour of above marker. Default is 'r', can be any legal
        matplotlib colour specification.
    ms
        (int) Marker size. Default 12

    Any other optional inputs are passed to matplotlib.patches.Ellipse

    Returns:
    ----------
    **None**

    Notes:
    ---------
    Adapted from `www.visiondummy.com  <http://www.visiondummy.com/2014/04/draw-error-ellipse-representing-covariance-matrix/#Source_Code>`_

    The general idea is as follows:

    * Compute the covariance matrix for x and y.
    * Compute the eigen vectors of the covariance matrix, corresponding
      to vectors parallel to the major and minor axes.
    * The eigen values correspond to the variances of the distribution
      along the major and minor axes.
    * To compute the lengths of the major and minor axes for a given confidence
      interval, compute the chi^2 value that corresponds to that confidence
      interval. The length of the semi major axis is then
      :math:`\sqrt{ \chi^2 \sigma^2}`, where :math:`\sigma^2` is
      the variance.

    The above proceedure will give you confidence intervals for the
    distribution (e.g the p=.95 ellipse will contain 95% of the points in the
    distribution. To get the confidence interval on the mean, divde the
    covariance matrix in the first step by :math:`\sqrt{N}` where N is the
    number of input points.


Compute inverse chi square function.

    For a given value of ``p``, computed the chi-square value
    corresponding to that probability.

    For example, the probability of getting a chi square value greater
    than 2.996 with two degrees of freedom is <0.05. So
    ``inverseChiSquare(.05, 2) == 2.996``

    Inputs:
    ------------
    p
        (float) Desired probability

    Optional Inputs
    ----------------
    dof
        (int) Degrees of freedom.

    Returns:
    -------------
    The chi-squared value corresponding to the input probability

    Notes:
    ---------
    I would expect scipy to support this, but it doesn't. The easiest
    way to compute it seems to be to interpolate over the availble
    chi-square distribution function.


Identify indices of outlier points in a timeseries

    Inputs:
    a   (1d np array)   Input data. a is assumed to represent
                        equally spaced data

    Optional Inputs:
    threshold_sigma     How many sigma away from mean must a point
                        be to be considered an outlier
    normFreq            Input arg to sincfilter, defines how agressively
                        to smooth.

    Returns:
    1d array of booleans of length a. Value set to true if
    element is an outlier

    Description
    Data is heavily high pass filtered, with the assumption that
    residuals are mostly gaussian with a few outlying points.
    These points are id'd, and their indices returns


Compute strength of roll tweak artifact in K2 data with an FT approach.

    Compute FT of lightcurve

    Optional Inputs:
    -----------------
    plot
        Show a diagnostic plot

    Returns:
    --------
    float indicating strength of correction. A value of 1 means the
    amplitude of the tweak is approx equal to the strength of all other
    signals in the FT.


Estimates 6hr CDPP using Jeff Van Cleve's Savitzy-Golay technique

    An interesting estimate of the noise in a lightcurve is the scatter
    after all long term trends have been removed. This is the kernel of
    the idea behind the Combined Differential Photometric Precision (CDPP)
    metric used in classic Kepler. Jeff van Cleve devised a much simpler
    algorithm for computing CDPP using a Savitzy-Golay detrending, which
    he called Savitzy-Golay CDPP, or SG-CDPP. We implement his algorithm
    here.

    Inputs:
    ----------
    y
        (1d numpy array) normalised flux to calculate noise from. Flux
        should have a mean of zero and be in units of fractional amplitude.
        Note: Bad data in input will skew result. Some filtering of
        outliers is performed, but Nan's or Infs will not be caught.

    Optional Inputs:
    -----------------
    transitDuration_cadences
        (int) Adjust the assumed transit width, in cadences. Default is
        13, which corresponds to a 6.5 hour transit in K2
    plot
        Show a diagnostic plot

    Returns:
    ------------
    Estimated noise in parts per million.

    Notes:
    -------------
    Taken from
    svn+ssh://murzim/repo/so/trunk/Develop/jvc/common/compute_SG_noise.m
    by Jeff van Cleve


Estimate the typical scatter in a lightcurve.

    Uses the same method as Marshall (Mullally et al 2016 submitted)

    Inputs:
    ----------
    flux
        (np 1d array). Flux to measure scatter of. Need not have
        zero mean.

    Optional Inputs:
    -----------------
    plot
        Show a diagnostic plot

    Returns:
    ------------
    (float) scatter of data in the same units as in the input ``flux``

    Notes:
    ----------
    Algorithm is reasonably sensitive to outliers. For best results
    uses outlier rejection on your lightcurve before computing scatter.
    Nan's and infs in lightcurve will propegate to the return value.


Iteratively find and remove outliers in first derivative

    If a dataset can be modeled as a constant offset + noise + outliers,
    those outliers can be found and rejected with a sigma-clipping approach.

    If the data contains some time-varying signal, this signal must be removed
    before applying a sigma clip. This function removes the signal by applying
    a single point difference.

    The function computes a[i+1] - a[i], and sigma clips the result. Slowly
    varying trends will have single point differences that are dominated by noise,
    but outliers have strong first derivatives and will show up strongly in this
    metric.

    Inputs:
    ----------
    y
        (1d numpy array) Array to be cleaned
    nSigma
        (float) Threshold to cut at. 5 is typically a good value for
        most arrays found in practice.

    Optional Inputs:
    -------------------
    maxIter
        (int) Maximum number of iterations

    initialClip
        (1d boolean array) If an element of initialClip is set to True,
        that value is treated as a bad value in the first iteration, and
        not included in the computation of the mean and std.

    Returns:
    ------------
    1d numpy array. Where set to True, the corresponding element of y
    is an outlier.


Iteratively find and remove outliers

    Find outliers by identifiny all points more than **nSigma** from
    the mean value. The recalculate the mean and std and repeat until
    no more outliers found.

    Inputs:
    ----------
    y
        (1d numpy array) Array to be cleaned
    nSigma
        (float) Threshold to cut at. 5 is typically a good value for
        most arrays found in practice.

    Optional Inputs:
    -------------------
    maxIter
        (int) Maximum number of iterations

    initialClip
        (1d boolean array) If an element of initialClip is set to True,
        that value is treated as a bad value in the first iteration, and
        not included in the computation of the mean and std.

    Returns:
    ------------
    1d numpy array. Where set to True, the corresponding element of y
    is an outlier.


Compute the mean of the percent.. 100-percent percentile points

    A fast, and typically good enough estimate of the mean in the presence
    of outliers.


Compute a robust standard deviation with JVC's technique

    A fast, and typically good enough estimate of the mean in the presence
    of outliers.Cuts out 1st and 99th percentile values and computes std
    of the rest. Used by computeSgCdpp() to match the behaviour of
    Jeff van Cleve's original algorithm

    Taken from
    svn+ssh://murzim/repo/so/trunk/Develop/jvc/common/robust_std.m


Convert a frequency in the units of the data into normalised frequency.

    Useful for computing input arguments in {high|low}Pass()

    Inputs:
    f           (float) Frequency in, e.g, Hz
    timespace   (float) Range of data in , eg, seconds. This is the time
                interval between the last and first data points in your
                set.


Generate the Blackman apodisation.

    Taken from "The Scientist and Engineers' Guide to Digital Signal
    Processing" by Steven Smith. Ch 16, Eqn 16.4. This book is available
    online  at www.dspguide.com/ch16/2.html

    This function is used to apodise a sinc filter to improve it's
    stopband attentuation.

    sysSize:    (int) Number of points being used in the filter. Smith
                calls this M

    Returns:
    A 1d array, blackman[i]. The sinc filter is apodised by computing
    apodisedFilter[i] = sinc[i] * blackman[i]


Apply a high pass filter to evenly spaced data

    Based on sincFilter in this module. See that function for more
    detailed info on who Smith is.

    Inputs:
    y   (1d float array)    Array of evenly spaced data points to filter
    normalisedCutOffFreq    (float) Frequency at which 50% attentuation
                            occurs. This input must have a value between
                            [0,.5). Smith names this value f_c
    numPointsInFilter       (int)   Half the number of points included
                            in the filter. Smith refers to this value as M.
                            The number of points used is (2M+1)

    apodise                 (func) What apodisation function to use. The
                            default is usually the best choice. If you
                            don't want apodisation for some reason, set
                            this argument to rectangle

    Returns:
    A 1d array high pass filtered.


Apply a low pass filter to evenly spaced data

    Based on sincFilter in this module. See that function for more
    detailed info on who Smith is.

    Inputs:
    y   (1d float array)    Array of evenly spaced data points to filter
    normalisedCutOffFreq    (float) Frequency at which 50% attentuation
                            occurs. This input must have a value between
                            [0,.5). Smith names this value f_c
    numPointsInFilter       (int)   Half the number of points included
                            in the filter. Smith refers to this value as M.
                            The number of points used is (2M+1)

    apodise                 (func) What apodisation function to use. The
                            default is usually the best choice. If you
                            don't want apodisation for some reason, set
                            this argument to rectangle

    Returns:
    A 1d array low pass filtered.


    Compute a sincFilter with numPointsInFilter points

    Taken from "The Scientist and Engineers' Guide to Digital Signal
    Processing" by Steven Smith. Ch 16, Eqn 16.4. This book is available
    online  at www.dspguide.com/ch16/2.html

    A sinc filter is a low pass filter with a sharp cutoff. The larger
    the value of numPointsInFilter, the sharper the cutoff.

    Sinc functions suffer from ringing on either side of the cutoff which
    can be dramatically reduced by apodising the filter with, e.g., a
    blackman filter.

    The
    Inputs:
    normalisedCutOffFreq    (float) Frequency at which 50% attentuation
                            occurs. This input must have a value between
                            [0,.5). Smith names this value f_c
    numPointsInFilter       (int)   Half the number of points included
                            in the filter. Smith refers to this value as M.
                            The number of points used is (2M+1)

    Returns:
    A 1d array of length numPointsInFilter.

    Notes:
    If your have a desired cutoff frequency in Hz, the normalised value
    can be computed as f/T, where f is the cutoff in Hz, and T is the
    timespan of the data in seconds.


Won't work if img is plotted  in ra/dec space


Plot a pixel time series for every pixel in a cube

    Similar, static plots, used to be included in the DV report
    but were removed for some reason.

    Inputs:
    --------
    cube    (np 3d array)
        A TPF data cube as produced by tpf.getTargetPixelArrayFromFits
    hdr     (FITS header)
        The header of the TPF file

    Optional Inputs:
    --------------
    detrend     (boolean)
        Whether to apply a Savitzy-Golay filter to the data
        Note, transits are not protected, so this will distort
        your lightcurve in funny ways. Default: False

    big (boolean)
        Force plotting of really big masks (greater than 49 pixels)
        Default: False

    All other optional arguments are passed to mp.plot()

    Returns:
    ----------
    **None**

    Todo:
    --------
    * Optional argument to set the time axis
    * Show axis ticks on the bottom and left plots
    * Ability to highlight certain time intervals (e.g times
      of transits
    * Ability to specify detrending algorithm.


Compute the overresolved FFT of input data and scale the amplitude

    Inputs:
    y           (1d np array)   Input data. Treated as equally spaced data
    expTime_Sec (float) Spacing between input points

    Optional Inputs:
    overres     (int) How many times to overresolve the FT. Values below
                3 cause FTs that are difficult to interpret, above 10
                yields no better information.

    Returns:
    A 2d numpy array. The zeroth column is frequency in microHz. The
    second column is fractional amplitude at that frequency

    Notes:
    Calls numpy's rfft function, which is based on fftw


Compute number of points needed to input to an fft algorithm to ensure
    a) The data is overesolved by at least a factor of overres
    b) The number of poitns is an integer power of 2


Compute the frequencies corresponding to the output of fft.

    Inputs:
    numPoints:  (int) Number of points in input data.
    overes      (int) How much the data was overresolved.
    expTime_sec (float) Spacing between points in seconds.

    Returns:
    1d numpy array

    Notes
    numPoints is the number of points in the input data before the input
    is padded to account for overresolution and ensuring the length is a power
    of two.


Run the Model-Shift test

    Inputs:
    -------------
    modshift
        The dictionary returned by ModShift.runModshift

    Returns:
    -------------
    A dictionary containing the following keys:

    disp
      The disposition of the DOI --- either "candidate" or "false positive"
    not_tran_like
      A 1/0 flag indicating whether or not the DOI is transit-like. 0 means it is transit-like
    sig_sec
      A 1/0 flag indicating whether or not the DOI has a significant secondary.
    comments
      A string containing comments on individual tests

    Output:
    ----------
    None


Run the Model-Shift test

    Inputs:
    -------------
    time
        The array of time values days.
    flux
        The array of observed fluxes correspodnding to each time.
    model
        The array of model fluxes corresponding to each time.
    plotname
        The name for the output plot
    objectname
        The name of the object, to be displayed in the plot title
    period
        The period of the system in days.
    epoch
        The epoch of the system in days.
    modplotint
       If modplotint==1, then plot will be produced, else it won't

    Returns:
    -------------
    A dictionary containing the following keys:

    mod_sig_pri
      The significance of the primary event assuming white noise
    mod_sig_sec
      The significance of the secondary event assuming white noise
    mod_sig_ter
      The significance of the tertiary event assuming white noise
    mod_sig_pos
      The significance of the positive event assuming white noise
    mod_sig_oe
      The significance of the odd-even metric
    mod_dmm
      The ratio of the individual depths's median and mean values.
    mod_shape
      The shape metric.
    mod_sig_fa1
      The False Alarm threshold assuming 20,000 objects evaluated
    mod_sig_fa2
      The False Alarm threshold for two events within the phased light curve
    mod_Fred
      The ratio of the red noise to the white noise in the phased light curve at the transit timescale
    mod_ph_pri
      The phase of the primary event
    mod_ph_sec
      The phase of the secondary event
    mod_ph_sec
      The phase of the tertiary event
    mod_ph_pos
      The phase of the primary event
    mod_secdepth
      The depth of the secondary event
    mod_secdeptherr
      The error in the depth of the secondary event

    Output:
    ----------
    The model-shift plot is also created as a PDF file if plot==1


 Model a transit light curve in the small planet approximation
        of Mandel & Agol using the nonlinear limb darkening law
        Works up to k=Rp/Rstar =0.5, but recommend much smaller values
        AUTHOR: Christopher J. Burke
            based upon the mathematical description of Mandel & Agol


 Model a transit light curve in the small planet approximation
        of Mandel & Agol using the quadratic limb darkening law
        Works up to k=Rp/Rstar =0.5, but recommend much smaller values
        AUTHOR: Christopher J. Burke
            based upon the mathematical description of Mandel & Agol


Phase the data at period per and centered at to
       INPUT:
         t - time of data
         per - period to phase time data period and t should
               be in same units
         to - epoch of phase zero
       OUTPUT:
         phi - data phased running from -0.5<phi<=0.5


Convert parameters to bounded versions that the minimzer will use
       INPUT:
         ioblk - [class] trp_ioblk class
       OUTPUT:
         ioblk - [class]
         err - [0 ok ; 1 not ok]


Convert bounded parameter values that the minimizer uses to physvals
       INPUT:
         ioblk - [class] trp_ioblk class
       OUTPUT:
         ioblk - [class]
         err - [0 ok ; 1 not ok]


Trapezoid shape for model
       INPUT:
       t -  [float] vector of independent values to evaluate
                    trapezoid model
       depth - [float] depth of trapezoid
       bigT - [float] full trapezoid duration
       littleT - [float] 'ingress/egress' duration
       OUTPUT:
       output - [float] vector of trapezoid model values