tools package

Submodules

tools.detector module

tools.detector.averageDetectorReadout(par, filelist, detectorFolderOut, suffix='detector', offaxis=None, averageDivide=False, factor=1.0, zodi=None, forced_inttime=None, forced_tottime=None)[source]

Process a list of files and creates individual detector readouts If we want only one file, we can just make a list of 1

tools.detector.averageDetectorReadoutParallel(par, filelist, detectorFolderOut, suffix='detector', offaxis=None, averageDivide=False, factor=1.0, zodi=None, forced_inttime=None, forced_tottime=None)[source]

Process a list of files and creates individual detector readouts If we want only one file, we can just make a list of 1

tools.detector.calculateDark(par, filelist)[source]

Process a series of dark frames to get an estimate of the dark current frame that matches the exposures.

tools.detector.multipleReadouts(par, filename, detectorFolderOut, suffix='detector', offaxis=None, averageDivide=False, factor=1.0, zodi=None, forced_inttime=None, forced_tottime=None)[source]
tools.detector.photonCounting(average, EMGain=1.0, RN=0.0, PCbias=0.0, threshold=6, poisson=True, EMStats=True, PCmode=True)[source]
tools.detector.readDetector(par, IFSimage, inttime=100)[source]

Read noise, CIC, dark current; NO TRAPS Input is IFSimage in average photons per second Quantum efficiency considerations are already taken care of when generating IFSimage images

tools.detector.readoutPhotonFluxMapWFIRST(fluxMap, tottime, inttime=None, QE=1.0, darkBOL=0.00014, darkEOL=0.00028, CIC=0.01, eff=1.0, EMGain=2500.0, RN=100.0, PCbias=1000.0, threshold=6.0, lifefraction=0.0, dqeKnee=0.858, dqeFluxSlope=3.24, dqeKneeFlux=0.089, nonoise=False, poisson=True, EMStats=True, PCmode=True, PCcorrect=False, normalize=False, verbose=False)[source]
tools.detector.rebinDetector(par, finalFrame, clip=False)[source]

Rebins the dense detector map with the correct scaling while conserving flux. This also works with non-integer ratios.

Parameters:

par : Parameter instance

Contains all IFS parameters

finalFrame : 2D ndarray

Dense detector map to be rebinned.

Returns:

detectorFrame : 2D array

Return the detector frame with correct pixel scale.

tools.detutils module

tools.detutils.frebin(array, shape, total=True)[source]

Function that performs flux-conservative rebinning of an array. Found at https://github.com/benjaminpope/pysco/blob/master/frebin.py

Parameters:

array: ndarray

Numpy array to be rebinned

shape: tuple

(x,y) of new array size total: Boolean

when True flux is conserved

Returns

——-

new_array: new rebinned array with dimensions: shape

tools.detutils.rebin(a, shape)[source]

Resizes a 2d array by averaging or repeating elements, new dimensions must be integral factors of original dimensions

Parameters:

a : array_like

Input array.

new_shape : tuple of int

Shape of the output array (y, x)

Returns:

rebinned_array : ndarray

If the new shape is smaller of the input array, the data are averaged, if the new shape is bigger array elements are repeated

tools.image module

class tools.image.Image(filename='', data=None, ivar=None, header=None, extraheader=None)[source]

Image is the basic class for images

self.data, self.ivar, and self.header should be numpy ndarrays, which can be read from and written to a fits file with the load and write methods. If not ndarrays, they should be None.

Image may be initialized with the name of the raw file to read, through a call to Image.load().

load(outfilename)[source]

Read the first HDU with data from filename into self.data, and HDU[0].header into self.header. If there is more than one HDU with data, attempt to read the second HDU with data into self.ivar.

write(outfilename, clobber=True)[source]

Creates a primary HDU using self.data and self.header, and attempts to write to outfilename. If self.ivar is not None, append self.ivar as a second HDU before writing to a file. clobber is provided as a keyword to fits.HDUList.writeto.

tools.image.log = <tools.initLogger.crispyLogger object>

most of this code is due to Tim Brandt

tools.imgtools module

tools.imgtools.bowtie(image, xc, yc, openingAngle, clocking, IWApix, OWApix, export='bowtie', twomasks=False)[source]

Creates one or two binary mask for a shaped pupil bowtie mask

Parameters:

image: 2D ndarray

Image to which the mask needs to be applied

xc: int

X coordinate of center of bowtie

yc: int

Y coordinate of center of bowtie

openingAngle: float

Angle in degrees representing the opening angle of the bowtie mask

clocking: float

Angle of rotation of the mask in degrees

IWApix: float

Radius in pixels corresponding to the inner working angle of the mask

OWApix: float

Radius in pixels corresponding to the outer working angle of the mask

export: boolean

Whether to export the bowtie or not

twomasks: boolean

If True, returns two masks, one for each side of the bowtie If False, returns one single mask

Returns:

mask: 2D ndarrays of int

Bowtie mask with 1 inside the mask, zero everywhere else.

mask2: 2D ndarrays of int

If twomasks is True, mask and mask2 are the two sides of the bowtie.

tools.imgtools.circularMask(image, radius)[source]
tools.imgtools.gen_bad_pix_mask(image, filsize=3, threshold=5.0, return_smoothed_image=False)[source]

Identify and mask bad pixels using median filter

Parameters:

image: 2D ndarray

Image to clean

filsize: int

Size of median filter in pixels

threshold: float

Threshold in terms of standard deviations

return_smoothed_image: boolean

Returns:

goodpix: 2D int ndarray

Good pixel mask. 1 where pixel is good

image_sm: 2D ndarray, if return_smoothed_image

tools.imgtools.gen_lenslet_flat(BBcube, nsig=5)[source]
tools.imgtools.scale2imgs(target, ref, bowtie_mask, returndiff=True, returnest=False)[source]

Finds the slice-by-slice best-fit scale factor between two images. Optionally returns the difference between the two. Images can be cubes.

Parameters:

bowtie_mask: 2D ndarray

Bowtie mask

Returns

——-

coefs: float array

Coefficient(s) of the best fit between the two images or cubes

diff: ndarray

Same shape as input, residual difference img1*scale-img2.

tools.imgtools.subtract_mean(cube)[source]

subtract the mean of the cube slice by slice

tools.initLogger module

tools.initLogger.addFileHandler(log, lvl=1)[source]

This function will add a file handler to a log with the provided level.

Args:
log (crispyLogger object): A crispyLogger object that was freshly
instantiated.
lvl (int): The severity level of messages printed to the file with
the file handler, default = 1.
tools.initLogger.addFitsStyleHandler(log)[source]

This function will add a file handler with a string format ideal for directly loading into a FITS header.

Args:
log (crispyLogger object): A crispyLogger object that was freshly
instantiated.
tools.initLogger.addStreamHandler(log, lvl=20)[source]

This function will add a stream handler to a log with the provided level.

Args:
log (crispyLogger object): A crispyLogger object that was freshly
instantiated.
lvl (int): The severity level of messages printed to the screen with
the stream handler, default = 20.
class tools.initLogger.crispyLogger(name, level=0)[source]

Bases: logging.Logger

This is the advanced logging object used for crispy. It is almost a carbon copy of the CHARIS DRP logger routine. It inherits from the standard Python library ‘logging’ and provides added features. The default log level for the output file will be 1, ie ALL messages; while the default for the screen will be INFO, and can be changed easily using the setStreamLevel(lvl) member function.

Initialize the logger with a name and an optional level.

MAINCRITICAL = 80
MAINDEBUG = 60
MAINERROR = 75
MAININFO = 65
MAINWARNING = 70
PRIMCRITICAL = 55
PRIMDEBUG = 35
PRIMERROR = 49
PRIMINFO = 39
PRIMWARNING = 45
SUMMARY = 5
TOOLCRITICAL = 29
TOOLDEBUG = 9
TOOLERROR = 25
TOOLINFO = 15
TOOLWARNING = 19
maincritical(msg, lvl=80, *args, **kws)[source]
maindebug(msg, lvl=60, *args, **kws)[source]
mainerror(msg, lvl=75, *args, **kws)[source]
maininfo(msg, lvl=65, *args, **kws)[source]
mainwarning(msg, lvl=70, *args, **kws)[source]
primcritical(msg, lvl=55, *args, **kws)[source]
primdebug(msg, lvl=35, *args, **kws)[source]
primerror(msg, lvl=49, *args, **kws)[source]
priminfo(msg, lvl=39, *args, **kws)[source]
primwarning(msg, lvl=45, *args, **kws)[source]
setStreamLevel(lvl=20)[source]

Set/change the level for the stream handler for a logging object. Any file handlers will be left alone. All messages of a higher severity level than ‘lvl’ will be printed to the screen.

Args:
lvl (int): The severity level of messages printed to the screen with
the stream handler, default = 20.
Standard Levels New Levels
Name Level Name Level
CRITICAL 50 MAINCRITICAL 80
ERROR 40 MAINERROR 75
WARNING 30 MAINWARNING 70
INFO 20 MAININFO 65
DEBUG 10 MAINDEBUG 60
NOTSET 0 PRIMCRITICAL 55
    PRIMERROR 49
PRIMWARNING 45
PRIMINFO 39
PRIMDEBUG 35
TOOLCRITICAL 29
TOOLERROR 25
TOOLWARNING 19
TOOLINFO 15
TOOLDEBUG 9
SUMMARY 5
summary(msg, lvl=5, *args, **kws)[source]
toolcritical(msg, lvl=29, *args, **kws)[source]
tooldebug(msg, lvl=9, *args, **kws)[source]
toolerror(msg, lvl=25, *args, **kws)[source]
toolinfo(msg, lvl=15, *args, **kws)[source]
toolwarning(msg, lvl=19, *args, **kws)[source]
tools.initLogger.getLogger(name='generalLoggerName', lvl=20, addFH=True, addSH=True)[source]

This will either return the logging object already instantiated, or instantiate a new one and return it. Use this function to both create and return any logger to avoid accidentally adding additional handlers by using the setUpLogger function instead.

Args:
name (str): The name for the logging object and
name.log will be the output file written to disk.
lvl (int): The severity level of messages printed to the screen with
the stream handler, default = 20.
addFH (boolean): Add a file handler to this logger? Default severity
level for it will be 1, and it will be named following name+’.log’. Default = True.
addSH (boolean): Add a stream handler to this logger? Severity set with
the lvl argument. Default = True.
Returns:
log (CharisLogger object): A CharisLogger object that was either
freshly instantiated or determined to already exist, then returned.
tools.initLogger.setUpLogger(name='generalLoggerName', lvl=20, addFH=True, addSH=True)[source]

This function is utilized by getLogger to set up a new logging object. It will have the default name ‘generalLoggerName’ and stream handler level of 20 unless redefined in the function call. NOTE: If a file handler is added, it will have the lowest severity level by default (Currently no need for changing this setting, so it will stay this way for now). Remember that any messages will be passed up to any parent loggers, so children do not always need their own file handler.

Args:
name (str): The name for the logging object and
name.log will be the output file written to disk.
lvl (int): The severity level of messages printed to the screen with
the stream handler, default = 20.
addFH (boolean): Add a file handler to this logger? Default severity
level for it will be 1, and it will be named following name+’.log’. Default = True.
addSH (boolean): Add a stream handler to this logger? Severity set with
the lvl argument. Default = True.
Returns:
log (crispyLogger object): A crispyLogger object that was freshly
instantiated.

tools.inputScene module

tools.inputScene.Jy_to_photons(cube_Jy, wavlist)[source]
Parameters:

cube_Jy: 3D datacube in Jy

wavlist: 1D array with wavelengths in microns

Returns

——-

hc: 3D haystacks cube in photons/m2/um/s

tools.inputScene.adjust_krist_header(cube, lamc, pixsize=None)[source]

Force a different central wavelength, assuming that everything is wavelength-independent

Parameters:

cube: 3D float array

Input cube from J. Krist

lamc: float

Central wavelength to override in nm

pixsize: float

Pixel scale at central wavelength to override (in lambda/D)

tools.inputScene.calc_contrast(wavelist, distance, radius, filename, albedo=None)[source]

Function calcContrast

Returns the flux ratio Fplanet/Fstar at given wavelengths.

Parameters:

wavelist : 1D array, list

Array of wavelengths in nm at which the contrast is computed.

distance : float

Distance in AU between the planet and the star

radius: float

Radius of planet in units of Jupiter radii

filename: string

Two-column file with first column as the wavelength in microns, second column is the geometrical albedo

albedo: float

If None, then the albedo is given by the contents of the text file. If not None, the geometrical albedo given in the text file is normalized to have its maximum within the wavelist range to be albedo.

Returns:

vals : 1D array

Array of flux ratio at the desired wavelengths.

tools.inputScene.calc_contrast_Bijan(wavelist, albedo=0.28, radius=1.27, dist=3.6, planet_type='Jupiter', abundance=1, distance=5, phase=90, folder='/Users/mrizzo/Science/Haystacks/Cahoy_Spectra/albedo_spectra/')[source]

Function calc_contrast_Bijan (obsolete)

tools.inputScene.convert_krist_cube(cubeshape, lamlist, star_T, star_Vmag, tel_area)[source]

Function convert_krist_cube

This function calculates the number of photons per second entering the WFIRST obscured aperture, given the star Vmag and its temperature for each slice of the input cube This was only tested with John Krist’s cubes and his normalization.

Parameters:

cubeshape: tuple

Indicates the shape of the cube that needs to be multiplied

lamlist: 1D array

Wavelength array in nm corresponding to the cube slices

star_T: float

Stellar temperature in K

star_Vmag: float

Stellar magnitude in V band

tel_area: units.m**2

Area of telescope in units of units.m**2

Returns:

newcube: 3D array

Cube that multiplies an input normalized cube from John Krist to turn it into units of photons/s/nm/pixel. Each slice from the product cube subsequently needs to be multiplied by the bandwidth of each slice to determine the photons/s/pixel incident on the telescope

tools.inputScene.haystacks_to_photons(haystacks_hdu)[source]

Function haystacks_to_photons

This function converts a Haystacks hdu in Jy/pixels to photons/s/nm/m^2/pixel and returns a full cube

Parameters:

cube: haystacks_hdu

Haystacks HDU

Returns:

hc: ndarray

Converted cube in ph/s/um/m2

lamlist: wavelength array

tools.inputScene.zodi_cube(krist_cube, area_per_pixel, absmag, Vstarmag, zodi_surfmag, exozodi_surfmag, distAU, t_zodi)[source]

(obsolete)

tools.lenslet module

tools.lenslet.processImagePlane(par, imagePlane, noRot=False)[source]

Function processImagePlane

Rotates an image or slice, and rebins in a flux-conservative way on an array of lenslets, using the plate scale provided in par.pixperlenslet. Each pixel represents the flux within a lenslet. Starts by padding the original image to avoid cropping edges when rotating. This step necessarily involves an interpolation, so one needs to be cautious.

Parameters:

par : Parameters instance

Contains all IFS parameters

imagePlane : 2D array

Input slice to IFS sim, first dimension of data is wavelength

Returns:

imagePlaneRot : 2D array

Rotated image plane on same sampling as original.

tools.lenslet.propagateLenslets(par, imageplane, lam1, lam2, hires_arrs=None, lam_arr=None, upsample=3, nlam=10, npix=13, order=3, x0=0.3)[source]

Function propagateLenslets

This is the main propagation function. It puts the PSFLets where they belong on the detector. It uses template PSFLets given in hires_arrs, and can use also a pre-determined wavelength solution through the allcoef argument.

Parameters:

par: Params instance

Parameters instance for crispy

imageplane: 2D array

Flux map where each pixel corresponds to one lenslet

lam1: float

Minimum wavelength in IFS band

lam2: float

Maximum wavelength in IFS band

hires_arr: 4D ndarray

For each wavelength, for each location on the detector, a 2D array of the oversampled PSFLet

lam_arr: 1D array

Wavelength array corresponding to the hires_arr array

upsample: int

Factor by which the PSFLets are oversampled

nlam: int

Number of wavelengths to oversample a given wavelength bin

npix: int

PSFLet will be put on npix*npix detector pixels, models will be (npix*upsample)^2

order: int

Order used in the polynomial fit of the wavelength solution

x0: float

Offset from the center of the detector in the vertical direction (x)

tools.locate_psflets module

class tools.locate_psflets.PSFLets(load=False, infile=None, infiledir='.')[source]

Helper class to deal with the PSFLets on the detector. Does most of the heavy lifting during the wavelength calibration step.

Initialize the class

Parameters:

load: Boolean

Whether to load an already-existing wavelength calibration file

infile: String

If load is True, this is the name of the file

infiledir: String

If load is True, this is the directory in which the file resides

geninterparray(lam, allcoef, order=3)[source]

Set up array to solve for best-fit polynomial fits to the coefficients of the wavelength solution. These will be used to smooth/interpolate the wavelength solution, and ultimately to compute its inverse.

Parameters:

lam: float

Wavelength in nm

allcoef: list of lists floats

Polynomial coefficients of wavelength solution

order: int

Order of polynomial wavelength solution

Notes

Populates the attribute interp_arr in PSFLet class

genpixsol(par, lam, allcoef, order=3, lam1=None, lam2=None, borderpix=4)[source]

Calculates the wavelength at the center of each pixel within a microspectrum

Parameters:

lam: float

Wavelength in nm

allcoef: list of floats

List describing the polynomial coefficients that best fit the lenslets, for all wavelengths

order: int

Order of the polynomical fit

lam1: float

Lowest wavelength in nm

lam2: float

Highest wavelength in nm

Notes

This functions fills in most of the fields of the PSFLet class: the array of xindx, yindx, nlam, lam_indx and nlam_max

loadpixsol(infile=None, infiledir='./calibrations')[source]

Loads existing wavelength calibration file

Parameters:

infile: String

Name of the file

infiledir: String

Directory in which the file resides

monochrome_coef(lam, alllam=None, allcoef=None, order=3)[source]
return_locations(lam, allcoef, xindx, yindx, order=3)[source]

Calculates the detector coordinates of lenslet located at xindx, yindx for desired wavelength lam

Parameters:

lam: float

Wavelength in nm

allcoef: list of lists floats

Polynomial coefficients of wavelength solution

xindx: int

X index of lenslet in lenslet array

yindx: int

Y index of lenslet in lenslet array

order: int

Order of polynomial wavelength solution

Returns:

interp_x: float

X coordinate on the detector

interp_y: float

Y coordinate on the detector

return_locations_short(coef, xindx, yindx)[source]

Returns the x,y detector location of a given lenslet for a given polynomial fit

Parameters:

coef: lists floats

Polynomial coefficients of fit for a single wavelength

xindx: int

X index of lenslet in lenslet array

yindx: int

Y index of lenslet in lenslet array

Returns:

interp_x: float

X coordinate on the detector

interp_y: float

Y coordinate on the detector

return_res(lam, allcoef, xindx, yindx, order=3, lam1=None, lam2=None)[source]

Returns the spectral resolution and interpolated wavelength array

Parameters:

lam: float

Wavelength in nm

allcoef: list of lists floats

Polynomial coefficients of wavelength solution

xindx: int

X index of lenslet in lenslet array

yindx: int

Y index of lenslet in lenslet array

order: int

Order of polynomial wavelength solution

lam1: float

Shortest wavelength in nm

lam2: float

Longest wavelength in nm

Returns:

interp_lam: array

Array of wavelengths

R: float

Effective spectral resolution

savepixsol(outdir='calibrations/')[source]

Saves wavelength calibration file

Parameters:

outdir: String

Directory in which to put the file. The file is name PSFloc.fits and is a multi-extension FITS file, each extension corresponding to: 0. the list of wavelengths at which the calibration is done 1. a 2D ndarray with the X position of all lenslets 2. a 2D ndarray with the Y position of all lenslets 3. a 2D ndarray with the number of valid wavelengths for a given lenslet (some wavelengths fall outside of the detector area)

tools.locate_psflets.corrval(coef, x, y, filtered, order, trimfrac=0.1)[source]

Return the negative of the sum of the middle XX% of the PSFlet spot fluxes (disregarding those with the most and the least flux to limit the impact of outliers). Analogous to the trimmed mean.

Parameters:

coef: list of floats

coefficients for polynomial transformation

x: ndarray

coordinates of lenslets

y: ndarray

coordinates of lenslets

filtered: ndarray

image convolved with gaussian PSFlet

order: int

order of the polynomial fit

trimfrac: float

fraction of outliers (high & low combined) to trim Default 0.1 (5% trimmed on the high end, 5% on the low end)

Returns:

score: float

Negative sum of PSFlet fluxes, to be minimized

tools.locate_psflets.initcoef(order, scale=15.02, phi=2.0496941961364943, x0=0, y0=0)[source]

Create a set of coefficients including a rotation matrix plus zeros.

Parameters:

order: int

The polynomial order of the grid distortion

scale: float

The linear separation in pixels of the PSFlets. Default 13.88.

phi: float

The pitch angle of the lenslets. Default atan(2)

x0: float

x offset to apply to the central pixel. Default 0

y0: float

y offset to apply to the central pixel. Default 0

Returns:

coef: list of floats

A list of length (order+1)*(order+2) to be optimized.

Notes

The list of coefficients has space for a polynomial fit of the input order (i.e., for order 3, up to terms like x**3 and x**2*y, but not x**3*y). It is all zeros in the output apart from the rotation matrix given by scale and phi.

tools.locate_psflets.locatePSFlets(inImage, mask, polyorder=2, sig=0.7, coef=None, trimfrac=0.1, phi=2.0496941961364943, scale=15.02, nlens=108)[source]

function locatePSFlets takes an Image class, assumed to be a monochromatic grid of spots with read noise and shot noise, and returns the esimated positions of the spot centroids. This is designed to constrain the domain of the PSF-let fitting later in the pipeline.

Parameters:

imImage: Image class

Assumed to be a monochromatic grid of spots

polyorder: float

order of the polynomial coordinate transformation. Default 2.

sig: float

standard deviation of convolving Gaussian used for estimating the grid of centroids. Should be close to the true value for the PSF-let spots. Default 0.7.

coef: list

initial guess of the coefficients of polynomial coordinate transformation

trimfrac: float

fraction of lenslet outliers (high & low combined) to trim in the minimization. Default 0.1 (5% trimmed on the high end, 5% on the low end)

Returns:

x: 2D ndarray

Estimated spot centroids in x.

y: 2D ndarray

Estimated spot centroids in y.

good:2D boolean ndarray

True for lenslets with spots inside the detector footprint

coef: list of floats

List of best-fit polynomial coefficients

Notes

the coefficients, if not supplied, are initially set to the known pitch angle and scale. A loop then does a quick check to find reasonable offsets in x and y. With all of the first-order polynomial coefficients set, the optimizer refines these and the higher-order coefficients. This routine seems to be relatively robust down to per-lenslet signal-to-noise ratios of order unity (or even a little less).

tools.locate_psflets.transform(x, y, order, coef)[source]

Apply the coefficients given to transform the coordinates using a polynomial.

Parameters:

x: ndarray

Rectilinear grid

y: ndarray of floats

Rectilinear grid

order: int

Order of the polynomial fit

coef: list of floats

List of the coefficients. Must match the length required by order = (order+1)*(order+2)

Returns:

_x: ndarray

Transformed coordinates

_y: ndarray

Transformed coordinates

tools.par_utils module

class tools.par_utils.Consumer(task_queue, result_queue)[source]

Bases: multiprocessing.process.Process

run()[source]
class tools.par_utils.Task(index, func, args)[source]

Bases: object

tools.plotting module

tools.plotting.plotKernels(par, kernels, locations, plot=False)[source]

Make plots of all the kernels

tools.postprocessing module

tools.postprocessing.RDI_noise(par, xshift, yshift, order=3, rootname='mflib', outdir_time_series='OS5', outdir_detector='OS5/OS5_detector', outdir_average='OS5/OS5_average', process_cubes=True, process_offaxis_files=True, process_detector=True, take_averages=True, countershift=True, normalize_cubes=True, forced_inttime_ref=50, offaxis_reduced='OS5/OS5_average/offaxis.fits', psf_time_series_folder='/Users/mrizzo/IFS/OS5/with_lowfc', Nref=30, ref_only=True, offaxis_psf_filename='/Users/mrizzo/IFS/OS5/offaxis/spc_offaxis_psf.fits', ref_star_T=<Quantity 9377.0 K>, ref_star_Vmag=2.37, target_star_T=<Quantity 5887.0 K>, target_star_Vmag=5.03, IWA=3, OWA=9, lamc=660.0, BW=0.18, tel_pupil_area=<Quantity 3.650265060424805 m2>, mflib='/mflib.fits.gz')[source]

Determines the SNR map of a simulation using RDI. Here we assume the target PSF time series is already in hand, and already in outdir_time_series.

Parameters:

par: Parameters instance

Crispy parameter instance

xshift: float

The amount to shift the input in X (in final IFS cube pixels)

yshift: float

The amount to shift the input in Y (in final IFS cube pixels)

order: integer

The order of the spline transform used for shifting the cubes

rootname: string

The root name of the final SNR cube maps

outdir_time_series: string

Path to which we will export the IFS fluxes at the detector

outdir_detector: string

Path to the folder where we will put the detector maps

outdir_average: string

Path to the folder where we will put the final results and other byproducts of the function

process_cubes: Boolean

Whether or not to process the IFS cubes, or assume that they are already processed

countershift: Boolean

Whether to countershift the reference star or not

normalize_contrast: Boolean

Whether to normalize the SNR map to contrast units using off-axis PSF

offaxis_reduced: string

Path to the offaxis PSF that will be used for contrast normalization

psf_time_series_folder: string

Path to the folder where all the original files are located

Nref: integer

Out of the files in John Krist’s folder, how many correspond to observations of the reference star

ref_only: Boolean

Whether to only process the reference files or also target files

ref_star_T: ‘u.K’

Temperature of the reference star in u.K

target_star_T: ‘u.K’

Temperature of the target star in u.K

ref_star_Vmag: float

V Magnitude of the reference star

target_star_Vmag: float

V Magnitude of the target star

lamc: float

Central wavelength of the band, in nm

BW: float

Bandwidth

tel_pupil_area: ‘u.m**2’

Collecting area of the telescope, minus obscurations, in u.m**2

mflib: string

Name of the matched filter library file

Returns:

pixstd: array

List of slice-by-slice standard deviation of the RDI cube convolved with the matched filter

tools.postprocessing.SNR_spectrum(lam_midpts, signal, noise, filename='Jupiter_1x_5AU_90deg.dat', planet_radius=1.27, planet_AU=3.6, albedo=0.28, lam_contrast=None, plot=True, outname='SNR.png', outfolder='', title='Planet+star', edges=1, FWHM=2, FWHMdata=2.0, ymargin=0.05)[source]

Plot the outputs of process_SPC_IFS

tools.postprocessing.construct_mflib(par, planet_cube, threshold, lamc, BW, outdir, mask, trim=30, outname='mflib.fits.gz', order=3)[source]

Construct a library of matched filters for all points within the bowtie mask For now, this uses the reduced, ideal offaxis psf already in cube space. We could also build a function that offsets the original file, before IFS transformation.

This particular function saves memory and time by only recording the relevant pixels

Parameters:

par: Parameters instance

Crispy parameter instance

planet_cube: string

Path to the off-axis planet IFS cube

threshold: float

Value below which we zero out the matched filter pixels

lamc: float

Central wavelength in nm

BW: float

Spectral bandwidth

outdir: string

Export directory

mask: 2D ndarray

2D bowtie mask. If left to None, then the bowtie mask is calculated and IWA and OWA need to be specified

IWA: float

Inner working angle (in terms of lam/D

OWA: float

Outer working angle (in terms of lam/D

trim: integer

How much to trim the cubes on each side to save memory space (nominally 30)

outname: string

Name of the matched filter library file. Highly recommend to compress it to save space

order: int

Order at which we do the spline transformation to move offaxis PSF around.

tools.postprocessing.convolved_mf(incube, mflibname, trim=30)[source]

Generates a pseudo-convolution of the image by the matched filter library

Parameters:

incube: 3D ndarray

Cube to convolve. Make sure all NaNs have been converted to zeros

mflibname: string

Path to the Matched Filter library, that was pre-computed

trim: integer

How much to trim the cubes on each side to save memory space (nominally 30)

Returns:

convolvedmap: 3D ndarray

Input cube multiplied in each non-zero pixel by the matched filter corresponding to that pixel

tools.postprocessing.mf(cube, mask, threshold)[source]

Matched filter function

Parameters:

cube: 3D ndarray

An IFS cube representing the offaxis PSF, from which to compute the matched filter

mask: 2D ndarray

This is typically the coronagraphic mask

threshold: float

Fraction of max below which we crop the normalized PSF

Returns:

matched_filter: 3D ndarray

Matched filter with the same dimensions as input cube

tools.postprocessing.processReferenceCubes(par, xshift=0.0, yshift=0.0, order=3, outdir_time_series='OS5', ref_input_list=[], process_cubes=True, ref_star_T=<Quantity 9377.0 K>, ref_star_Vmag=2.37, lamc=660.0, BW=0.18, tel_pupil_area=<Quantity 3.650265060424805 m2>)[source]

Processes raw cubes from John Krist into IFS flux cubes just before the IFS. Doesn’t take into account the optical losses, but does take into account the detector QE.

Parameters:

par: Parameters instance

Crispy parameter instance

xshift: float

The amount to shift the input in X (in final IFS cube pixels)

yshift: float

The amount to shift the input in Y (in final IFS cube pixels)

order: integer

The order of the spline transform used for shifting the cubes

outdir_time_series: string

Path to which we will export the IFS fluxes at the detector

ref_input_list: string

List of filenames with the reference cubes

Nref: integer

Out of the files in John Krist’s folder, how many correspond to observations of the reference star

ref_only: Boolean

Whether to only process the reference files or also target files

ref_star_T: ‘u.K’

Temperature of the reference star in u.K

ref_star_Vmag: float

V Magnitude of the reference star

lamc: float

Central wavelength of the band, in nm

BW: float

Bandwidth

tel_pupil_area: ‘u.m**2’

Collecting area of the telescope, minus obscurations, in u.m**2

Returns:

ref_outlist: list of strings

List of the filenames corresponding the reference star

target_outlist: list of strings

List of the filenames corresponding the target star

fileshape: tuple

Size of the original John Krist cube

tools.postprocessing.processTargetCubes(par, target_file_list, outdir_time_series='OS5', process_cubes=True, target_star_T=<Quantity 5887.0 K>, target_star_Vmag=5.03, lamc=660.0, BW=0.18, tel_pupil_area=<Quantity 3.650265060424805 m2>)[source]

Processes raw cubes from John Krist into IFS flux cubes just before the IFS. Doesn’t take into account the optical losses, but does take into account the detector QE.

Parameters:

par: Parameters instance

Crispy parameter instance

target_file_list: string

List of files

outdir_time_series: string

Path to which we will export the IFS fluxes at the detector

target_star_T: ‘u.K’

Temperature of the target star in u.K

target_star_Vmag: float

V Magnitude of the target star

lamc: float

Central wavelength of the band, in nm

BW: float

Bandwidth

tel_pupil_area: ‘u.m**2’

Collecting area of the telescope, minus obscurations, in u.m**2

Returns:

target_outlist: list of strings

List of the filenames corresponding the target star

tools.postprocessing.process_SPC_IFS(par, psf_time_series_folder, offaxis_psf_filename, planet_radius=<Quantity 90794840.0 m>, planet_AU=3.6, planet_dist_pc=14.1, ref_star_T=<Quantity 9377.0 K>, ref_star_Vmag=2.37, target_star_T=<Quantity 5887.0 K>, target_star_Vmag=5.03, lamc=770.0, BW=0.18, n_ref_star_imgs=30, tel_pupil_area=<Quantity 3.650265060424805 m2>, IWA=3, OWA=9, xshift=0.0, yshift=0.0, pp_fact=0.05, t_zodi=0.09, useQE=True, subtract_ref_psf=True, outdir_time_series='OS5', outdir_detector='OS5/OS5_detector', outdir_average='OS5/OS5_average', process_cubes=True, process_offaxis=True, process_detector=True, process_noiseless=False, take_averages=True, parallel=True)[source]

Process SPC PSF cubes from J. Krist through the IFS

Parameters:

par: Params instance

Contains all the parameters of the IFS

psf_time_series_folder: string

Where the files from Krist are located

offaxis_psf_filename: string

Where the off-axis PSF is located

mean_contrast: float

Mean contrast of the planet spectrum

ref_star_T: `u.K` float

Reference star temperature, float multiplied by astropy.units.K

ref_star_Vmag: float

Vmag of the reference star

target_star_T: `u.K` float

Target star temperature, float multiplied by astropy.units.K

target_star_T_star_Vmag: float

Vmag of the target star

lamc: float

Band’s central wavelength in nm

BW: float

Bandwidth

n_ref_star_imgs: int

Number of reference star images in the list

tel_pupil_area: `u.m**2` float

Effective surface area of telescope, including all geometric losses. Float multiplied by astropy.units.m**2

IWA: float

Inner working angle defined at par.lenslet_wav

OWA: float

Outer working angle defined at par.lenslet_wav

pp_fact: float

Post-processing factor - multiplies the target star PSF

t_zodi = float

Zodi transmission

outdir_time_series: string

Where to store the noiseless IFS detector images

outdir_detector: string

Where to store the noisy IFS detector images

outdir_average: string

Where to store the averages of the time series

process_cubes: Boolean

Whether to process the raw images from Krist, or skip this step if it was already done

process_offaxis: Boolean

Whether to process the offaxis images and add it to the images

process_detector: Boolean

Whether to add detector QE, IFS losses and noise to the IFS images

process_noiseless: Boolean

Whether to add detector QE, IFS losses but no detector noise to the IFS images

take_averages: Boolean

Whether to average all IFS detector images in the time series to create averages

Returns:

signal: ndarray

Array with the matched-filtered flux at each of the final cube’s wavelengths; The background is already subtracted

noise: ndarray

Noise estimate using the pixel-to-pixel variance within the dark hole, multiplied by the number of effective pixels within the matched filter (sum of matched filter cube)

tools.postprocessing.process_SPC_IFS2(par, psf_time_series_folder, offaxis_psf_filename, xshift=0.0, yshift=0.0, order=3, albedo_filename='Jupiter_1x_5AU_90deg.dat', planet_radius=1.27, planet_AU=3.6, planet_dist_pc=14.1, albedo=0.28, ref_star_T=<Quantity 9377.0 K>, ref_star_Vmag=2.37, target_star_T=<Quantity 5887.0 K>, target_star_Vmag=5.03, lamc=770.0, BW=0.18, n_ref_star_imgs=30, tel_pupil_area=<Quantity 3.650265060424805 m2>, IWA=3, OWA=9, forced_inttime_ref=10.0, forced_tottime_ref=1000.0, pp_fact=1.0, RDI=True, subtract_dark=False, normalize_cubes=True, t_zodi=0.09, useQE=True, mflib='/mflib.fits.gz', outdir_time_series='OS5', outdir_detector='OS5/OS5_detector', outdir_average='OS5/OS5_average', process_cubes=True, process_offaxis_files=True, process_detector=True, take_averages=True, take_ref_average=True, nosource=True)[source]

Process SPC PSF cubes from J. Krist through the IFS

Parameters:

par: Params instance

Contains all the parameters of the IFS

psf_time_series_folder: string

Where the files from Krist are located

offaxis_psf_filename: string

Where the off-axis PSF is located

xshift: float

X-shift of the reference star with respect to the target star(pixels)

yshift: float

Y-shift of the reference star with respect to the target star(pixels)

order: int

Order of all interpolations (3 recommended)

albedo_filename: string

Name of file containing the geometric albedo of the planet, located in Inputs/ folder

planet_radius: float

Radius of planet in Jupiter radii

planet_AU: float

Distance of the planet from its star in AU

planet_dist_pc: float

Distance of the star system in pc

albedo: float

Overrides the albedo. If None, then the original albedo curve is used. If not None, then the maximum of the albedo curve is normalized to the new albedo, while keeping overall albedo shape

ref_star_T: `u.K` float

Reference star temperature, float multiplied by astropy.units.K

ref_star_Vmag: float

Vmag of the reference star

target_star_T: `u.K` float

Target star temperature, float multiplied by astropy.units.K

target_star_T_star_Vmag: float

Vmag of the target star

lamc: float

Band’s central wavelength in nm

BW: float

Bandwidth

n_ref_star_imgs: int

Number of reference star images in the list

tel_pupil_area: `u.m**2` float

Effective surface area of telescope, including all geometric losses. Float multiplied by astropy.units.m**2

IWA: float

Inner working angle defined at par.lenslet_wav

OWA: float

Outer working angle defined at par.lenslet_wav

forced_inttime_ref: float

Forced time of a single integration for the reference star. This should be smaller than the individual integration time for the target since the reference star is typically brighter

forced_tottime_ref: float

Forced time spent for a single input cube for the reference. Typically, this is the same as the time for a single input cube for the target

pp_fact: float

Post-processing factor - artificially multiplies the target star PSF. Note that this is NOT the same as Bijan’s f_pp

RDI: Boolean

If True, run an RDI function to clean up the raw cubes.

mflib: String

Path towards an already-existing matched filter library. If empty string is given, the software will construct the library each time

subtract_dark: Boolean

If True, estimate the mean dark region (bottom of the detector) and subtract from map. Default: True. For different kinds of input maps that might cover the entire defector, this might be more tricky.

normalize_cubes: Boolean

If True, all cubes are normalized to contrast units. Default is True.

t_zodi: float

Zodi transmission (not operational for now)

useQE: Boolean

If True, the QE is applied when constructing the IFS maps. Note that in this case the QE file should represent both the actual detector QE, and the wavelength-dependent optical losses

outdir_time_series: string

Where to store the noiseless IFS detector images

outdir_detector: string

Where to store the noisy IFS detector images

outdir_average: string

Where to store the averages of the time series

process_cubes: Boolean

Whether to process the raw images from Krist, or skip this step if it was already done

process_offaxis: Boolean

Whether to process the offaxis images and add it to the images

process_detector: Boolean

Whether to add detector QE, IFS losses and noise to the IFS images

process_noiseless: Boolean

Whether to add detector QE, IFS losses but no detector noise to the IFS images

take_averages: Boolean

Whether to average all IFS detector images in the time series to create averages

nosource: Boolean

Whether or not to process everything without actually adding the planet

Returns:

signal: ndarray

Array with the matched-filtered flux at each of the final cube’s wavelengths; The background is already subtracted

noise: ndarray

Noise estimate using the pixel-to-pixel variance within the dark hole, multiplied by the number of effective pixels within the matched filter (sum of matched filter cube)

tools.postprocessing.process_offaxis(par, offaxis_psf_filename, fileshape, lamlist, lamc, outdir_average, Nave=1, inttime=1, Nreads=1, filename='Jupiter_1x_5AU_90deg.dat', planet_radius=1.27, planet_AU=3.6, planet_dist_pc=14.1, albedo=0.28, target_star_T=<Quantity 5887.0 K>, target_star_Vmag=5.03, ref_star_T=<Quantity 9377.0 K>, ref_star_Vmag=2.37, tel_pupil_area=<Quantity 3.650265060424805 m2>, order=3, useQE=True, polychromeOut=True)[source]

Processes an off-axis PSF cube from John Krist. This is used to to construct an ideal cube of the planet

Parameters:

par: Parameters instance

Crispy parameter instance

offaxis_psf_filename: string

Path to the off-axis cube from J. Krist

fileshape: tuple

Size of the original John Krist cube

lamlist: list

List of wavelengths corresponding to each slice

lamc: float

Central wavelength

outdir_average: string

Path to which we will export the off-axis IFS flux maps at the detector

Nave: integer

Number of files to average. This needs to be the same number as the number of times the target is averaged (nominally 100)

target_star_T: ‘u.K’

Temperature of the target star in u.K

target_star_Vmag: float

V Magnitude of the target star

tel_pupil_area: ‘u.m**2’

Collecting area of the telescope, minus obscurations, in u.m**2

polychromeOut: Boolean

Whether or not to export a polychrome cube weighted by the PSF

Returns:

offaxis_reduced: 3D ndarray

Reduced cube

tools.postprocessing.recenter_offaxis(offaxis_file, threshold, outname='centered_offaxis.fits')[source]

Example: recenter_offaxis(‘/Users/mrizzo/IFS/OS5/offaxis/spc_offaxis_psf.fits’,0.01,par.exportDir+’/centered_offaxis.fits’)

Parameters:

offaxis_file: string

Path to off-axis file from John Krist

threshold: float

Threshold under which we don’t care about the values

outname: string

The path to the centered off axis cube

Returns:

outkey: HDUList

HDU list of the recentered cube

tools.reduction module

tools.reduction.RL(img, psflets, niter=10, guess=None, eps=1e-10, prior=0.0)[source]

Richardson-Lucy deconvolution

tools.reduction.calculateWaveList(par, lam_list=None, Nspec=None, method='lstsq')[source]

Computes the wavelength lists corresponding to the center and endpoints of each spectral bin. Wavelengths are separated by a constant value in log space. Number of wavelengths depends on spectral resolution.

Parameters:

par: Parameter instance

Contains all IFS parameters

lam_list: list of floats

Usually this is left to None. If so, we use the wavelengths used for wavelength calibration. Otherwise, we could decide to focus on a smaller/larger region of the spectrum to retrieve. The final processed cubes will have bins centered on lam_midpts

Nspec: int

If specified, forces the number of bins in the final cube (uses np.linspace)

Returns:

lam_midpts: list of floats

Wavelengths at the midpoint of each bin

lam_endpts: list of floats

Wavelengths at the edges of each bin

tools.reduction.fit_cutout(subim, psflets, mode='lstsq', niter=5, pixnoise=0.0)[source]

Fit a series of PSFlets to an image, recover the best-fit coefficients. This is currently little more than a wrapper for np.linalg.lstsq, but could be more complex if/when we regularize the problem or adopt some other approach.

Parameters:

subim: 2D nadarray

Microspectrum to fit

psflets: 3D ndarray

First dimension is wavelength. psflets[0]

must match the shape of subim.

mode: string

Method to use. Currently limited to lstsq (a

simple least-squares fit using linalg.lstsq), this can be expanded to include an arbitrary approach.

Returns:

coef: array

The best-fit coefficients (i.e. the microspectrum).

Notes

This routine may also return the covariance matrix in the future. It will depend on the performance of the algorithms and whether/how we implement regularization.

tools.reduction.fitspec_intpix(par, im, PSFlet_tool, lamlist, delt_y=6, flat=None, mode='gaussvar')[source]

Optimal extraction routine

Parameters:

par : Parameter instance

Contains all IFS parameters

im: Image instance

IFS image to be processed.

PSFlet_tool: PSFLet instance

Inverse wavelength solution that is constructed during wavelength calibration

lamlist: list of floats

List of wavelengths to which each microspectrum is interpolated.

delt_y: int

Width in pixels of each microspectrum in the cross-dispersion direction

flat:

Whether a lenslet flatfield is used (not implemented yet)

smoothandmask: Boolean

Whether to smooth and mask bad pixels

Returns:

image: Image instance

Reduced cube in the image.data field

tools.reduction.fitspec_intpix_np(par, im, PSFlet_tool, lamlist, smoothandmask=True, delt_y=5)[source]

Original optimal extraction routine in Numpy from T. Brand

Parameters:

par : Parameter instance

Contains all IFS parameters

im: Image instance

IFS image to be processed.

PSFlet_tool: PSFLet instance

Inverse wavelength solution that is constructed during wavelength calibration

lamlist: list of floats

List of wavelengths to which each microspectrum is interpolated.

delt_y: int

Width in pixels of each microspectrum in the cross-dispersion direction

Returns:

image: Image instance

Reduced cube in the image.data field

tools.reduction.fitspec_intpix_np_old(im, PSFlet_tool, lam, delt_x=7, header=SIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions EXTEND = T)[source]
tools.reduction.get_cutout(im, x, y, psflets, dy=3, normpsflets=False)[source]

Cut out a microspectrum for fitting. Return the inputs to linalg.lstsq or to whatever regularization scheme we adopt. Assumes that spectra are dispersed in the -y direction.

Parameters:

im: Image intance

Image containing data to be fit

x: float

List of x centroids for each microspectrum

y: float

List of y centroids for each microspectrum

psflets: PSFLet instance

Typically generated from polychrome step in wavelength calibration routine

dy: int

vertical length to cut out, default 3. This is the length to cut out in the +/-y direction; the lengths cut out in the +x direction (beyond the shortest and longest wavelengths) are also dy.

Returns:

subim: 2D array

A flattened subimage to be fit

psflet_subarr: 2D ndarray

first dimension is wavelength, second dimension is spatial, and is the same shape as the flattened subimage.

Notes

Both subim and psflet_subarr are scaled by the inverse standard deviation if it is given for the input Image. This will make the fit chi2 and properly handle bad/masked pixels.

tools.reduction.intOptimalExtract(par, name, IFSimage, smoothandmask=True)[source]

Calls the optimal extraction routine

Parameters:

par : Parameter instance

Contains all IFS parameters

name: string

Path & name of the output file

IFSimage: Image instance

Image instance of input image. Can have a .ivar field for a variance map.

Notes

A cube is also written at par.SimResults/name.fits

tools.reduction.lstsqExtract(par, name, ifsimage, smoothandmask=True, ivar=True, dy=2, refine=False, hires=False, upsample=3, fitbkgnd=False, specialPolychrome=None, returnall=False, mode='lstsq', niter=10, pixnoise=0.0, normpsflets=False)[source]

Least squares extraction, inspired by T. Brandt and making use of some of his code.

Parameters:

par: Parameter instance

Contains all IFS parameters

name: string

Name that will be given to final image, without fits extension

ifsimage: Image

Image instance of IFS detector map, with optional inverse variance

Returns:

cube : 3D array

Return the reduced cube from the original IFS image

tools.reduction.testReduction(par, name, ifsimage)[source]

Scratch routine to test various things.

Parameters:

par: Parameter instance

Contains all IFS parameters

name: string

Name that will be given to final image, without fits extension

ifsimage: Image instance of IFS detector map, with optional inverse variance

Returns:

cube : 3D array

Return the reduced cube from the original IFS image

tools.rotate module

tools.rotate.Rotate(image, phi, clip=True, order=3)[source]

Rotate the input image by phi about its center. Do not resize the image, but pad with zeros. Function originally from Tim Brandt

Parameters:

image : 2D square array

Image to rotate

phi : float

Rotation angle in radians

clip : boolean (optional)

Clip array by sqrt(2) to remove fill values? Default True.

order : integer (optional)

Order of interpolation when rotating. Default is 1.

Returns:

imageout: 2D array

Rotated image of the same shape as the input image, with zero-padding

tools.rotate.Shift(image, dx, dy, order=3)[source]

Shifts the input image by dx, dy.

Parameters:

image : 2D square array

Image to rotate

dx : float

Rotation angle in radians

dy : boolean (optional)

Clip array by sqrt(2) to remove fill values? Default True.

Returns:

imageout: 2D array

Shifted image of the same shape as the input image

Notes

The functions pads the edges with the nearest value, including NaNs.

tools.rotate.rotateCube(cube, phi, clip=True, order=1)[source]
tools.rotate.shiftCube(cube, dx, dy, order=3)[source]

tools.spectrograph module

tools.spectrograph.createAllWeightsArray(par, locations)[source]

Creates weights for bilinear interpolation

Parameters:

par : Parameter instance

Contains all IFS parameters

locations : 2D ndarray, Nx2

Array of normalized locations on the detector, .

Returns:

detectorFrame : 2D array

Return the detector frame with correct pixel scale.

tools.spectrograph.distort(fx, fy, lam)[source]

Apply the distortion and dispersion from pre-determined polynomial This was estimated from Zemax by Qian Gong and Jorge Llop and needs to be revisited

Parameters:

fx,fy : float

Distance between a lenslet and the center of the detector in millimeter.

lam : float

Wavelength in microns.

Returns:

x,y : float

Distance from center of detector at which image from a lenslet falls in mm.

tools.spectrograph.loadKernels(par, wavel)[source]

Loads the kernels that represent the PSFs at different locations on the detector

Parameters:

par : Parameter instance

Contains all IFS parameters

wavel : float

Wavelength at which the kernels are needed

Returns:

kernels: array of 2D arrays

Represents each 2D kernel at each location

locations: Nx2 ndarray

Location coordinates in detector position ratio (0,0) is bottom left, (1,1) is top right

tools.spectrograph.selectKernel(par, lam, refWaveList, kernelList)[source]

Select the correct kernel for the current wavlength

Parameters:

par : Parameter instance

Contains all IFS parameters

lam : float

Wavelength at which we want the get the kernel, in microns

refWaveList : list of floats

Wavelengths at which the kernels are defined

kernelList : list of 3D ndarrays

List of the kernels cubes at the wavelengths above

Returns:

kernels: array of 2D arrays

Represents each 2D kernel at each location for that wavlength

locations: Nx2 ndarray

Location coordinates in detector position ratio (0,0) is bottom left, (1,1) is top right

tools.wavecal module

tools.wavecal.buildcalibrations(par, filelist=None, lamlist=None, order=3, inspect=False, genwavelengthsol=False, makehiresPSFlets=False, makePolychrome=False, makehiresPolychrome=False, makePSFWidths=False, savehiresimages=True, borderpix=4, upsample=5, nsubarr=3, parallel=True, inspect_first=True, apodize=False, lamsol=None, threshold=0.0)[source]

Master wavelength calibration function

Parameters:

par : Parameter instance

Contains all IFS parameters

filelist: list of strings (optional)

List of the fits files that contain the monochromatic calibration files. If None (default), use the files in par.filelist

lamlist: list of floats (optional)

Wavelengths in nm at which the files are taken. If None (default), use the files in par.lamlist

order: int

Order of the polynomial used to fit the PSFLet positions across the detector

genwavelengthsol: Boolean

If True, generate the wavelength calibration. Creates a text file with all polynomial coefficients that best fit the PSFLet positions at each wavelength. If False, then load an already-generated file.

inspect: Boolean

Whether or not to create PNG files that overlay PSFLet fitted position on the monochromatic pictures, to visually inspect the fitting results

inspect_first: Boolean

Whether or not to create a PNG file that overlays PSFLet fitted position on the monochromatic picture of the first file, to visually inspect the fitting results

makehiresPSFlets: Boolean

Whether or not to do a high-resolution fitting of the PSFs, using the sampling diversity. This requires high-SNR monochromatic images.

makePolychrome: Boolean

Whether or not to build the polychrome cube used in the least squares extraction

makePSFWidths: Boolean

Whether or not to fit the PSFLet widths using the high-res PSFLets

makehiresPolychrome: Boolean

Whether or not to build a polychrome cube at a high spatial resolution for future subpixel interpolations

savehiresimages: Boolean

Whether to save fits files with the high-res PSFLets

borderpix: int

Number of pixels that are not taken into account towards the edges of the detector

upsample: int

Upsampling factor for each high-resolution PSFLet

nsubarr: int

Detector will be divided into nsubarr x nsubarr regions. A high-resolution PSFLet will be determined in each region from the average of all PSFLets within that region

parallel: Boolean

Whether or not to parallelize the computation for the high-resolution PSFLet and polychrome computation. The wavelength calibration step cannot be parallelized since each wavelength uses the previous wavelength solution as a guess input.

apodize: Boolean

Whether to fit the spots only using lenslets within a circle, ignoring the corners of the detector

lamsol: 2D array

Optional argument that, if not None and if genwavelengthsol==False, will take the argument and use it as the current wavelength calibration to build the polychrome.

threshold: float

Threshold under which to zero out the polychrome. This is only useful for reducing the file size of the polychrome, and has only very little impact on the extraction. To be safe, for science extractions threshold should be kept at its default value of 0.0

Notes

This function generates all the files required to process IFS cubes: lamsol.dat: contains a list of the wavelengths and the polynomial coefficients that

describe the X,Y positions of all lenslets on the detector as a function of lenslet position on the lenslet array.
polychromekeyRXX.fits: where XX is replaced by the spectral resolution defined in the
parameters file. This is a multi-extension fits file with: - a list of the central wavelengths at which the final cube will be reduced to - an array of the X positions of all lenslets - an array of the Y positions of all lenslets - an array of booleans indicating whether that lenslet is good or not (e.g. when it is outside of the detector area)
polychromeRXX.fits: 3D arrays of size Nspec x Npix x Npix with maps of the PSFLets put in their correct
positions for each wavelength bins that we want in the output cube. Each PSFLet in each wavelength slice is used for least-squares fitting.

hiresPolychromeRXX.fits: same as polychromeRXX.fits but this time using the high-resolution PSFLets PSFLoc.fits: nsubarr x nsubarr array of 2D high-resolution PSFLets at each location

in the detector.
tools.wavecal.do_inspection(par, image, xpos, ypos, lam)[source]
tools.wavecal.get_sim_hires(par, lam, upsample=10, nsubarr=1, npix=13, renorm=True)[source]

Build high resolution images of the undersampled PSF using the monochromatic frames. This version of the function uses the perfect knowledge of the Gaussian PSFLet. Only valid if par.gaussian=True. All PSFLets are the same across the entire FOV

tools.wavecal.gethires(x, y, good, image, upsample=5, nsubarr=5, npix=13, renorm=True)[source]

Build high resolution images of the undersampled PSF using the monochromatic frames.

Inputs: 1.

tools.wavecal.makeHires(par, xindx, yindx, lam, allcoef, psftool, imlist=None, parallel=True, savehiresimages=True, upsample=5, nsubarr=5)[source]

Construct high-resolution PSFLets

tools.wavecal.make_hires_polychrome(lam1, lam2, hires_arrs, lam_arr, psftool, allcoef, xindx, yindx, ydim, xdim, upsample=10, nlam=10)[source]
tools.wavecal.make_polychrome(lam1, lam2, hires_arrs, lam_arr, psftool, allcoef, xindx, yindx, ydim, xdim, upsample=10, nlam=10)[source]
tools.wavecal.monochromatic_update(par, inImage, inLam, order=3, apodize=False)[source]

TODO: also update polychrome when specified

Module contents