The desimodel package/API

desimodel

A package for providing machine-readable data about the DESI focal plane and other hardware designs to simulations.

class desimodel.fastfiberacceptance.FastFiberAcceptance(filename=None)[source]

This class reads an input fits file generated with specsim.fitgalsim ($DESIMODEL/data/throughput/galsim-fiber-acceptance.fits) and instanciates RegularGridInterpolator objects for 2D and 3D interpolation of the pre-computed galsim fiber acceptance as a function of sigma (atmosphere+telescope blur, in um on focal surface), fiber offset from source (in um on focal surface), and half light radius (in arcsec) from extended source. The average and rms interpolation function for POINT,DISK and BULGE profiles are loaded.

rms(source, sigmas, offsets=None, hlradii=None)[source]

returns fiber acceptance fraction rms for the given source,sigmas,offsets

Parameters:
  • source (string) – POINT, DISK or BULGE for point source, exponential profile or De Vaucouleurs profile

  • sigmas (np.array) – arbitrary shape, values of sigmas in um for the PSF due to atmosphere and telescope blur

Optional:

hlradii (np.array) : same shape as sigmas, half light radius in arcsec for source offsets (np.array) : same shape as sigmas, values of offsets on focal surface between fiber and source, in um

Returns np.array with same shape as input

value(source, sigmas, offsets=None, hlradii=None)[source]

returns the fiber acceptance for the given source,sigmas,offsets

Parameters:
  • source (string) – POINT, DISK or BULGE for point source, exponential profile or De Vaucouleurs profile

  • sigmas (np.array) – arbitrary shape, values of sigmas in um for the PSF due to atmosphere and telescope blur

  • offsets (np.array) – same shape as sigmas, values of offsets on focal surface between fiber and source, in um

Optional:

hlradii (np.array) : same shape as sigmas, half light radius in arcsec for source

Returns np.array with same shape as input

desimodel.focalplane.fieldrot

Routines to estimate the field rotation in the DESI focal plane. The rotation angle is defined in DESI-5190.

  1. The CS5 system is defined in DESI-481. It is a plane tangent to the focal plane surface, attached to the petals. It has the axis X pointing to the physical east (and thus due to the mirror, sees targets on the sky to the physical west = increasing HA, decreasing RA), Y to the physical south (and thus due to the mirror, sees targets on the sky to the physical north = increasing Dec), and Z towards the mirror.

  2. The ICRS is the sky coordinate system of the DESI target catalogs, the same as Gaia astrometry. RA Dec will always be in the ICRS system.

  3. The Field rotation angle ‘Theta’ measures the rotation of the star images in the CS5 plane (not a rotation of the instrument, opposite sign!), tangent to the focal plane, assumed for assigning fibers.

  4. Theta=0 corresponds to zero rotation after the coordinate transformation from the ICRS RA,Dec sky coordinates to the CS5, with Y pointing to the north (increasing Dec).

  5. Theta is increasing from North to East (or from X(West) to Y(North)).

The DESI field rotation is due to a combination of precession, aberration, and polar misalignement and general mount imperfections.

Here we will just consider the most important terms.

A good fraction of the code below if from Mike Lampton, imported in desimodel by Julien Guy.

desimodel.focalplane.fieldrot.field_rotation_angle(ra, dec, mjd, use_astropy=False)[source]

precessiom, etc: https://desi.lbl.gov/DocDB/cgi-bin/private/ShowDocument?docid=4957

Parameters:
  • ra (Right ascension of center of focal plane in ICRS, in degrees) –

  • dec (Declination of center of focal plane in ICRS, in degrees) –

  • mjd (Modified Julian Date, decimal number, of the observation) –

Return type:

Field rotation angle, in degrees

desimodel.focalplane.fieldrot.rotation_angle(x1, y1, x2, y2)[source]

returns the angle from (x1,y1) to (x2,y2), in deg

desimodel.focalplane.geometry

Dimensions and coordinate system transforms for the DESI focal plane.

class desimodel.focalplane.geometry.FocalPlane(ra=0.0, dec=0.0)[source]

A class for modeling the DESI focal plane and converting between focal plane coordinates (in mm) and RA, Dec on the sky (in degrees). Provides utility functions for mapping which positioners cover which (RA, Dec) or (x, y) locations and vice versa.

Parameters:
  • ra (float) – Initialize DESI focal plane model with the telescope pointing at (ra, dec) in degrees.

  • dec (float) – Initialize DESI focal plane model with the telescope pointing at (ra, dec) in degrees.

  • NOTE (this class is deprecated (or should be further expanded), but) –

  • that (I'm not removing it yet in order to not arbitrarily break code) –

  • it. (might be using) –

_check_radec(ra, dec)[source]

Raise ValueError if RA or dec are out of bounds.

radec2pos(ra, dec)[source]

Identify which positioners cover (ra, dec).

If ra, dec are floats, return an array of positioner IDs that cover it. The array could be empty if no positioner covers that location.

If ra, dec are numpy arrays, return a list of arrays. The ith element is an array of positioner IDs that cover (ra[i], dec[i]).

Warning

This method is not implemented!

radec2xy(ra, dec)[source]

Convert (RA, Dec) in degrees to (x, y) in mm on the focal plane given the current telescope pointing.

If RA and Dec are floats, returns a tuple (x, y) of floats If RA and Dec are numpy arrays, returns a tuple (x, y) of numpy arrays

Parameters:
Returns:

A tuple containing the (x, y) coordinates in mm.

Return type:

tuple()

set_tele_pointing(ra, dec)[source]

Set telescope pointing to (RA, Dec) in degrees.

Parameters:
  • ra

  • dec (float) – Telescope pointing in degrees.

xy2pos(x, y)[source]

Identify which positioners cover (x, y).

Warning

This method is not implemented!

xy2radec(x, y)[source]

Convert (x, y) in mm on the focal plane to (ra_object, dec_object) in degrees on the sky given the current telescope pointing towards (RA, Dec).

x, y must be floats. This function is vectorized in xy2radec(), which doesn’t appear to exist.

Parameters:
  • x (float) – Position on the focal plane in mm.

  • y (float) – Position on the focal plane in mm.

Returns:

Coordinates of object.

Return type:

tuple()

desimodel.focalplane.geometry._extrapolate_r_s(r, s)[source]

Utility function for xy2qs and qs2xy; returns new r, s with extrapolations to 0 and max(r)+10 mm.

desimodel.focalplane.geometry.fiber_area_arcsec2(x, y)[source]

Returns area of fibers at (x, y) in arcsec^2.

desimodel.focalplane.geometry.get_radius_deg(x, y)[source]

Returns the radius in degrees given x, y coordinates using the platescale data.

Parameters:
  • x (float) – The x coordinate in mm of a location on the focal plane

  • y (float) – The y coordinate in mm of a location on the focal plane

Returns:

Radius corresponding to x, y.

Return type:

float

desimodel.focalplane.geometry.get_radius_mm(theta)[source]

Returns an array of radii in mm given an array of radii in degrees using the platescale data relative to the center of the focal plane as (0,0). Supports scalar and vector inputs.

Parameters:

theta (float or array-like) – An array that represents the angle from the center of the focal plane.

Returns:

Radii in mm.

Return type:

float or array-like

desimodel.focalplane.geometry.get_tile_radius_deg()[source]

Returns maximum radius in degrees covered by the outermost positioner.

desimodel.focalplane.geometry.get_tile_radius_mm()[source]

Returns maximum radius in mm covered by the outermost positioner.

desimodel.focalplane.geometry.qs2xy(q, s)[source]

angular q,s on curved focal surface -> focal tangent plane x,y

Parameters:
  • q – angle in degrees

  • s – focal surface radial distance in mm

Returns (x, y) cartesian location on focal tangent plane in mm

Notes: (x,y) are in the “CS5” DESI coordinate system tangent plane to the curved focal surface. q is the radial angle measured counter-clockwise from the x-axis; s is the radial distance along the curved focal surface; it is not sqrt(x**2 + y**2). (q,s) are the preferred coordinates for the DESI focal plane hardware engineering team.

desimodel.focalplane.geometry.radec2xy(telra, teldec, ra, dec)[source]

Returns arrays of the x, y positions of given celestial objects on the focal plane given an arbitrary telescope pointing in RA and Dec and arrays of the ra and dec of celestial objects in the sky.

Parameters:
  • telra (float) – The telescope’s RA pointing in degrees.

  • teldec (float) – The telescope’s Dec pointing in degrees.

  • ra (array-like) – An array of RA values for locations in the sky.

  • dec (array-like) – An array of Dec values for locations in the sky.

Returns:

The x, y positions corrsponding to ra, dec.

Return type:

tuple

Notes

Implements the Haversine formula.

desimodel.focalplane.geometry.xy2qs(x, y)[source]

Focal tangent plane x,y -> angular q,s on curved focal surface

Parameters:
  • x – cartesian location on focal tangent plane in mm

  • y – cartesian location on focal tangent plane in mm

Returns (q, s) where q=angle in degrees; s=focal surface radial dist [mm]

Notes: (x,y) are in the “CS5” DESI coordinate system tangent plane to the curved focal surface. q is the radial angle measured counter-clockwise from the x-axis; s is the radial distance along the curved focal surface; it is not sqrt(x**2 + y**2). (q,s) are the preferred coordinates for the DESI focal plane hardware engineering team.

desimodel.focalplane.geometry.xy2radec(telra, teldec, x, y)[source]

Returns the new RA and Dec of an x, y position on the focal plane in the sky given an arbitrary telescope pointing in RA and Dec.

Parameters:
  • telra (float) – The telescope’s RA pointing in degrees.

  • teldec (float) – The telescope’s Dec pointing in degrees.

  • x (float) – The x coordinate in mm of a location on the focal plane

  • y (float) – The y coordinate in mm of a location on the focal plane

Returns:

The RA, Dec corresponding to x, y.

Return type:

tuple

desimodel.focalplane.gfa

Guide-Focus-Alignment location routines

desimodel.focalplane.gfa.get_gfa_targets(targets, rfluxlim=1000, tiles=None, scale=1.0)[source]

This function takes a table of targets, as well as optional parameters including a minimum flux in the r-band, a list of tiles, and a buffer in arcseconds and returns a table of targets on the GFA satisfying a minimum flux_r

Parameters:
  • targets (Table) – Table columns RA, DEC, FLUX_R.

  • rfluxlim (float, optional) – r-band flux limit; default 1000 = rmag 15.

  • tiles (Table, optional) – Table of tiles, default to desimodel.io.load_tiles().

  • scale (float, optional) – Scale factor for GFA size to allow slightly off the edge targets

Returns:

A subset of input targets with additional columns: TILEID: (integer) DESI tile ID; GFA_LOC: (integer) GFA location [0-9].

Return type:

Table

Notes

  • The same target could be repeated with different TILEID, GFA_LOC.

  • The function returns an empty Table if no targets are on any GFAs or of sufficient brightness.

desimodel.focalplane.gfa.on_gfa(telra, teldec, ra, dec, scale=1.0)[source]

Checks if a target is on any of the 10 GFAs given telra, teldec and an array of ra and dec pointings, as well as a parameter for degrees of tolerance one would like to allow.

Parameters:
  • telra (float) – The telescope’s arbitrary RA pointing.

  • teldec (float) – The telescope’s arbitrary Dec pointing.

  • ra (array-like) – An array of RA values for locations in the sky.

  • dec (array-like) – An array of Dec values for locations in the sky.

  • scale (float, optional) – Scale factor for GFA size to allow slightly off the edge targets

Returns:

An array of the same length as input ra, giving the GFA_LOC that each (ra, dec) is on. -1 means not on a GFA.

Return type:

array

desimodel.focalplane.gfa.on_tile_gfa(tileid, targets, scale=1.0)[source]

This function takes a tileid, a table of targets, and an optional buffer_arcsec parameter to return the indices of targets lying on the GFA as well as the GFA locations from 0-9.

Parameters:
  • tileid (int) – DESI tile ID, used to lookup telescope (RA, dec).

  • targets (Table) – Table with columns RA, DEC.

  • scale (float, optional) – Scale factor for GFA size to allow slightly off the edge targets

Returns:

Subset of input targets with new GFA_LOC column

Return type:

Table

desimodel.focalplane.sim

Tools for generating simulated random distortion fields.

desimodel.focalplane.sim.generate_random_centroid_offsets(rms_offset=8.0, seed=123)[source]

Generate random centroid offsets.

Calls generate_random_vector_field() to generate offsets with a power spectrum exponent of -1 in the expected format.

The arrays in the files $DESIMODEL/data/throughput/DESI-0347_static_offset_<n>.fits were generated by this method with seeds n=1,2,3.

The default RMS offset value is taken from cell B52 of the Throughput sheet from DESI-0347-v13, labeled “FVC corrector optics figure error”.

Parameters:
  • rms_offset (astropy.Quantity instance.) – RMS that the generated offsets should have, including units.

  • seed (int) – Random number seed to use. Generated offsets should be portable across python versions and platforms.

Returns:

Tuple dx, dy of centroid offset arrays with units.

Return type:

tuple

desimodel.focalplane.sim.generate_random_vector_field(rms, exponent, n, seed=None, smoothing=0.02)[source]

Generate a pair dx, dy of 2D Gaussian random field.

The random field is generated with a power spectrum P(k) ~ r ** exponent and normalized to the specified RMS value. Smoothing is applied to minimize grid artifacts.

Parameters:
  • rms (float or astropy quantity) – Desired RMS of the generated field values.

  • exponent (float) – Exponent of the power spectrum scaling with radius.

  • n (int) – Size of the generated array along each axis.

  • seed (int) – Random number seed to use. Generated fields should be portable across python versions and platforms.

  • smoothing (float) – Length scale for smoothing the generated field expressed as a fraction of the full width of the field. Implemented as a Gaussian convolution. No smoothing is applied when smoothing is zero.

Returns:

Tuple dx, dy of 2D arrays containing the generated Gaussian random field values. Arrays will have the same units as the rms parameter, if any.

Return type:

tuple

desimodel.footprint

Utility functions for working with the DESI footprint.

desimodel.footprint._embed_sphere(ra, dec)[source]

Embed ra, dec to a uniform sphere in three dimensions.

desimodel.footprint.find_points_in_tiles(tiles, ra, dec, radius=None)[source]

Return a list of indices of points that are within each provided tile(s).

This function is optimized to query a lot of points with relatively few tiles.

radius is in units of degrees. The return value is an array of lists that contains the index of points that are in each tile. The indices are not sorted in any particular order.

if tiles is a scalar, a single list is returned.

default radius is from desimodel.focalplane.get_tile_radius_deg()

desimodel.footprint.find_points_radec(telra, teldec, ra, dec, radius=None)[source]

Return a list of indices of points that are within a radius of an arbitrary telra, teldec.

This function is optimized to query a lot of points with a single telra and teldec.

radius is in units of degrees. The return value is a list that contains the index of points that are in each tile. The indices are not sorted in any particular order.

if tiles is a scalar, a single list is returned.

default radius is from desimodel.focalplane.get_tile_radius_deg()

Note: This is simply a modified version of find_points_in_tiles, but this function does not know about tiles.

desimodel.footprint.find_tiles_over_point(tiles, ra, dec, radius=None)[source]

Return a list of indices of tiles that covers the points.

This function is optimized to query a lot of points. radius is in units of degrees. The return value is an array of list objects that are the indices of tiles that cover each point.

The indices are not sorted in any particular order.

if ra, dec are scalars, a single list is returned.

default radius is from desimodel.focalplane.get_tile_radius_deg()

desimodel.footprint.get_tile_radec(tileid)[source]

Get the coordinates of a tile.

Parameters:

tileid (int) – ID of a tile.

Returns:

(ra, dec) in degrees for the requested tileid.

Return type:

tuple

Raises:

ValueError – If tileid is not in list of known tiles.

desimodel.footprint.is_point_in_desi(tiles, ra, dec, radius=None, return_tile_index=False)[source]

If a point (ra, dec) is within radius distance from center of any tile, it is in DESI.

Parameters:
  • tiles (Table-like) – The output of desimodel.io.load_tiles(), or a similar Table.

  • ra (scalar or array-like) – Right Ascension in degrees.

  • dec (scalar or array-like) – Declination in degrees. The size of dec must match the size of ra.

  • radius (float, optional) – Tile radius in degrees; if None use desimodel.focalplane.get_tile_radius_deg().

  • return_tile_index (bool, optional) – If True, return the index of the nearest tile in tiles array.

Returns:

Return True if points given by ra, dec lie in the set of tiles.

Notes

This function is optimized to query a lot of points.

desimodel.footprint.pass2program(tilepass, surveyops=False)[source]

Converts integer tile pass number to string program name.

Parameters:

tilepass (int or int array) – tiling pass number.

surveyops (bool): True to look for tiles in $DESI_SURVEYPOPS.

Returns:

Program name for each pass (str or list of str).

desimodel.footprint.pix2tiles(nside, pixels, tiles=None, radius=None)[source]

Returns subset of tiles that overlap the list of pixels.

Parameters:
  • nside (int) – HEALPix nside, 2**k where 0 < k < 30.

  • pixels (array-like) – Array of integer pixels using nested numbering scheme.

  • tiles (Table-like, optional) – Table-like with RA,DEC columns; or None to use all DESI tiles from desimodel.io.load_tiles().

  • radius (float, optional) – Tile radius in degrees; if None use desimodel.focalplane.get_tile_radius_deg().

Returns:

Table of tiles that cover these pixels.

TODO: add support for tiles as integers or list/array of integer TILEIDs.

desimodel.footprint.pixweight(nside, tiles=None, radius=None, precision=0.01, outfile=None, outplot=None)[source]

Create an array of the fraction of each pixel that overlaps the passed tiles.

Parameters:
  • nside (int) – HEALPix nside, 2**k where 0 < k < 30.

  • tiles (Table-like, optional) – Table-like with RA,DEC columns; or None to use all DESI tiles from desimodel.io.load_tiles().

  • radius (float, optional) – Tile radius in degrees; if None use desimodel.focalplane.get_tile_radius_deg().

  • precision (float, optional) – Approximate precision at which to calculate the area of pixels that partially overlap the footprint in SQUARE DEGREES (e.g. 0.01 means precise to 0.01 sq. deg., or 36 sq. arcmin.). Lower numbers mean better precision.

  • outfile (str, optional) – Write the pixel->weight array to the file passed as outfile (could be full directory path + file).

  • outplot (str, optional) – Create a plot named outplot (pass a name for a plot in the current directory, a full path for a plot in a different directory). This is passed to matplotlib.pyplot’s savefig routine.

Returns pixweight:

An array of the weight for each pixel at the passed nside. The weight is the fracion of the pixel that overlaps the passed tiles: WEIGHT=1 for the pixel is entirely contained in the tiles; WEIGHT=0 for the pixel is entirely outside of the tiles; 0 < WEIGHT < 1 for a pixel that overlaps the tiles. The index of the array is the HEALPixel integer.

Notes

It is sufficient to create the weights at a suitably high nside, say nside=256 (0.052456 sq. deg. per pixel) as pixel numbers at lower nsides can be obtained by integer division by powers of 4, e.g. pix_@_nside_128 = pix@nside_256//4 and fractional weights at lower nsides are the mean of the 4 pixels at the higher nside desimodel.io.load_pixweight() can downsample the array to lower nsides.

desimodel.footprint.program2pass(program)[source]

Convert string program name to tile passes for that program.

Parameters:

program (str for str array) – program name, e.g. DARK, BRIGHT, or GRAY.

Returns:

List of integer passes that cover that program, or list of lists if input was array-like.

desimodel.footprint.radec2pix(nside, ra, dec)[source]

Convert ra, dec to nested pixel number.

Parameters:
  • nside (int) – HEALPix nside, 2**k where 0 < k < 30.

  • ra (float or array) – Right Accention in degrees.

  • dec (float or array) – Declination in degrees.

Returns:

Array of integer pixel numbers using nested numbering scheme.

Notes

This is syntactic sugar around:

hp.ang2pix(nside, ra, dec, lonlat=True, nest=True)

but also works with older versions of healpy that didn’t have lonlat yet.

desimodel.footprint.tileids2pix(nside, tileids, radius=None, per_tile=False)[source]

Like tiles2pix(), but accept integer tileid or list of tileids instead of table of tiles.

desimodel.footprint.tiles2fracpix(nside, step=1, tiles=None, radius=None, fact=128)[source]

Returns a sorted array of just the fractional pixels that overlap the tiles.

Parameters:
  • nside (int) – HEALPix nside, 2**k where 0 < k < 30.

  • step (int, optional) – The number of integration steps around the edges of a HEALPix pixel. step=1 means just the pixel vertices. step=2 means the vertices and the corners and the points halfway between the vertices. See also the HEALPix boundary document .

  • tiles (Table-like, optional) – Table-like with RA,DEC columns; or None to use all DESI tiles from desimodel.io.load_tiles().

  • radius (float, optional) – Tile radius in degrees; if None use desimodel.focalplane.get_tile_radius_deg().

  • fact (int, optional) – Factor healpy uses to resolve pixel overlaps. When this is large there are fewer false positives at the expense of run time (although fact=2**8 seems fast). Must be a power of 2.

Returns:

Integer array of pixel numbers that cover these tiles, excluding pixels that fully overlap the tiles (i.e., just pixels that partially overlap the tiles). The integers are sorted.

Notes

There are potentially malicious cases where a pixel just brushes a tile, such that there is a very small area where the pixel overlaps the tile. To guard against these case, call this function with progressively larger step values until it converges.

desimodel.footprint.tiles2pix(nside, tiles=None, radius=None, per_tile=False, fact=128)[source]

Returns sorted array of pixels that overlap the tiles.

Parameters:
  • nside (int) – HEALPix nside, 2**k where 0 < k < 30.

  • tiles (Table-like, optional) – tiles with columns RA,DEC or TILERA,TILEDEC, or None to load desimodel.io.load_tiles() (deprecated)

  • radius (float, optional) – tile radius in degrees; if None use desimodel.focalplane.get_tile_radius_deg().

  • per_tile (bool, optional) – If True, return a list of arrays of pixels per tile.

  • fact (int, optional) – Factor healpy uses to resolve pixel overlaps. When this is large there are fewer false positives at the expense of run time (although fact=2**8 seems fast). Must be a power of 2.

Returns:

Integer array of pixel numbers that cover these tiles; or if per_tile is True, returns list of arrays such that pixels[i] is an array of pixel numbers covering tiles[i].

desimodel.inputs

Code for working with raw input data to the DESI model data.

desimodel.inputs.ci

Utilities for updating Commissioning Instrument corners in data/focalplane/ci-corners.ecsv.

desimodel.inputs.ci.update()[source]

Update $DESIMODEL/data/focalplane/ci-corners.ecsv from DESI-4633v11

desimodel.inputs.docdb

Utility functions for working with DocDB files.

desimodel.inputs.docdb._auth(machine='desi.lbl.gov')[source]

Get authentication credentials.

desimodel.inputs.docdb._xls_col2int(col)[source]

Convert column string name to index, starting at 0

e.g. A -> 0, B -> 1, … Z -> 25, AA -> 26, AB -> 27

desimodel.inputs.docdb.download(docnum, docver, filename, outdir=None, overwrite=False)[source]

Downloads and writes outdir/DESI-{docnum}v{docver}-{filename}

Parameters:
  • docnum – integer DocDB number

  • docver – integer version number

  • filename – string filename within that DocDB entry

Options:

outdir: output directory; default $DESIMODEL/data/inputs/docdb/ overwrite: overwrite pre-existing file

Returns:

path to output file written

Notes

  • only supports python3

  • creates outdir if needed

  • prepends DESI-{docnum}v{docver} to {filename} even if filename already starts with that (in DocDB, some do and some don’t…)

desimodel.inputs.docdb.xls_read_col(filename, sheetname, column, firstrow, lastrow, dtype=None)[source]

Read Excel file column from firstrow to lastrow

Parameters:
  • filename (str) – Excel filename

  • sheetname (str) – sheet name within the filename

  • column (str) – Excel-style column string, e.g. ‘A’, ‘B’, or ‘AC’

  • firstrow (int) – 1-indexed first row to include

  • lastrow (int) – 1-indexed last row to include

Options:

dtype: convert output to this numpy dtype

Returns numpy array of data

Example

B5:B10 -> column=’B’, firstrow=5, lastrow=10 -> length 6 array

desimodel.inputs.docdb.xls_read_row(filename, sheetname, rownum, firstcol, lastcol, dtype=None)[source]

Read Excel file row from firstcol to lastcol

Parameters:
  • filename (str) – Excel filename

  • sheetname (str) – sheet name within the filename

  • rownum (int) – 1-indexed row to read

  • firstcol (str) – Excel-style column name, e.g. ‘A’, ‘B’, or ‘AC’

  • lastcol (str) – last column to include

Options:

dtype: convert output to this numpy dtype

Returns numpy array of data

Example

B5:D5 -> rownum=5, firstcol=’B’, lastcol=’D’ -> length 3 array

desimodel.inputs.fiberpos

Utilities for updating positioner to fiber mapping.

desimodel.inputs.fiberpos.update(testdir=None, seed=2)[source]

Update positioner to fiber number mapping from DocDB

Options:
testdir: if not None, write files here instead of

$DESIMODEL/data/footprint/fiberpos*

seed:

integer random number seed for randomization within a cartridge

Writes testdir/fiberpos* or $DESIMODEL/data/focalplane/fiberpos*

desimodel.inputs.fiberpos.write_text_fiberpos(filename, fiberpos)[source]

Writes a fiberpos table to filename, maintaining backwards compatibility with the original fiberpos.txt format

Parameters:
  • filename – output file name string

  • fiberpos – astropy Table of fiber positions

desimodel.inputs.focalplane

Utilities for constructing a focalplane model.

desimodel.inputs.focalplane.create(testdir=None, posdir=None, fibermaps=None, petalloc=None, startvalid=None, fillfake=False, fakeoffset=False, fakefiberpos=False, reset=False)[source]

Construct DESI focalplane and state files.

This function gathers information from the following sources:
  • Petal verification files on DocDB

  • Positioner device configuration files (e.g. from svn).

  • DESI-0530, to get the mapping from device ID to device type as well as the nominal device X/Y offsets on petal 0 (for fillfake option).

  • Exclusion configobj files in $DESIMODEL/data/focalplane.

Parameters:
  • testdir (str) – Override the output directory for testing.

  • posdir (str) – Directory containing the many positioner conf files. If None, simulate identical, nominal positioners. A None value will force fillfake=True.

  • fibermaps (list) – Override list of tuples (DocDB number, DocDB version, DocDB csv file) of where to find the petal mapping files.

  • petalloc (dict) – Mapping of petal ID to petal location.

  • startvalid (str) – The first time when this focalplane model is valid. ISO 8601 format string.

  • fillfake (bool) – If True, fill missing device locations with fake positioners with nominal values for use in simulations.

  • fakeoffset (bool) – If True, artificially sets the theta / phi angle offsets to zero. This replicates the behavior of legacy fiberassign and should only be used for testing.

  • fakefiberpos (bool) – If True, ignore the real fibermaps and load the old fiberpos file to get the mapping. Only useful for testing.

  • reset (bool) – If True, ignore all previous focalplane models and start with all positioners “good”. Default propagates the state of most recent model, after verifying that the positioners are the same.

Returns:

None

desimodel.inputs.focalplane.devices_from_fiberpos(fp)[source]

Populate focalplane properties from a fiberpos file.

This is only used for testing consistency with the previous fiberpos files. It should not be used for work with the real instrument. The focalplane properties are modified in place.

Parameters:

fp (dict) – The focalplane dictionary.

Returns:

None

desimodel.inputs.focalplane.devices_from_files(fp, posdir=None, fillfake=False, fakeoffset=False, fibermaps=None)[source]

Populate focalplane properties from information in files.

This populates the focalplane with device information gathered from the “pos_settings” files in svn and from the “Petal verification” files on DocDB.

The focalplane dictionary is modified in place.

Parameters:
  • fp (dict) – The focalplane dictionary.

  • posdir (str) – Directory containing the many positioner conf files.

  • fillfake (bool) – If true, fill missing POS and ETC locations with a fake nominal positioner.

  • fakeoffset (bool) – If true, use theta / phi offsets that matched very old versions of fiberassign.

  • fibermaps (list) – (optional) Override list of tuples (DocDB number, DocDB version, DocDB csv file) of where to find the petal mapping files.

Returns:

None

desimodel.inputs.focalplane_sync

Tools for checking and synchronizing focalplane state to online system.

desimodel.inputs.focalplane_sync.convert_fp_calibs(fpcal, sim=False)[source]

Convert the online system information.

This returns a tuple containing the focalplane, the current state, and the set of unique exclusion polygons found in the file.

Parameters:
  • fpcal (Table) – The table loaded from a dump from the online system.

  • sim (bool) – If True, clear all transient state issues and set hardware to be as “good as possible”, for use in simulations.

Returns:

The (focalplane, state, exclusions, time string) loaded from

the cal file.

Return type:

(tuple)

desimodel.inputs.focalplane_sync.create_from_calibs(calib_file, out_dir=None, reset=False, sim_good=False, commit=False, test=False, fibermaps=None)[source]

Construct a DESI focalplane from a calibration dump.

This uses a dump from the online system and compares it to the current latest focalplane model and state.

Parameters:
  • calib_file (str) – Path to the calibration dump.

  • out_dir (str) – Override the output directory for testing. Default writes to $DESIMODEL/data/focalplane/

  • reset (bool) – If True, ignore the current focalplane model and create a new model from this calibration dump. Default compares the new focalplane to the old and looks for changes in device state. These changes are appended to the existing log.

  • sim_good (bool) – If True, clear all transient state issues and set hardware to be as “good as possible”, for use in simulations.

  • commit (bool) – If True, attempt to commit the result.

  • test (bool) – If True, perform all operations but do not update any files.

  • fibermaps (list) – Override list of tuples (DocDB number, DocDB version, DocDB csv file) of where to find the petal mapping files.

Returns:

None

desimodel.inputs.focalplane_sync.load_fp_calibs(path)[source]

Load data dumped from the online system.

desimodel.inputs.focalplane_utils

Helpers for constructing a focalplane model.

desimodel.inputs.focalplane_utils.compute_theta_phi_range(phys_t, phys_p)[source]

Compute the min/max range about the initial offset.

Based on the “full_range” defined in plate_control/petal/posmodel.py

Parameters:
  • phys_t (float) – PHYSICAL_RANGE_T in degrees.

  • phys_p (float) – PHYSICAL_RANGE_P in degrees.

Returns:

The (theta_min, theta_max, phi_min, phi_max) angles.

Return type:

(tuple)

desimodel.inputs.focalplane_utils.create_device()[source]

Create an empty device property dictionary.

desimodel.inputs.focalplane_utils.create_nominal(petal_loc)[source]

Create a nominal focalplane layout.

This uses DocDB 0530 to construct a nominal focalplane. All positioner devices are assigned to their nominal X/Y locations, nominal theta / phi offsets and ranges, and nominal arm lengths.

Quantities not specified in 0530, such as physical petal and device IDs, are set to -1.

The input petal_loc dictionary is required, and only petal IDs in this dictionary will be created.

Note: The X/Y offsets used are those relative to the petal when placed at location 3. After modifying these with data from other sources, the final offsets are rotated into place.

Parameters:

petal_loc (dict) – Dictionary of petal ID to petal location.

Returns:

Dictionary of petal location properties, containing

dictionaries of device properties.

Return type:

(dict)

desimodel.inputs.focalplane_utils.create_tables(n_fp_rows, n_state_rows=None)[source]

Create empty focalplane and state tables.

This function keeps the construction of the table schema in a single place that can be used across the code.

Parameters:
  • n_fp_rows (int) – The number of rows in the focalplane table.

  • n_state_rows (int) – The number of rows in the state table. If None, use the same number of rows as the focalplane table.

Returns:

The (focalplane, state) tables.

Return type:

(tuple)

desimodel.inputs.focalplane_utils.device_compare(fpold, fpnew, check)[source]

Compare two sets of focalplane device properties.

Parameters:
  • fpold (Table) – The original device properties.

  • fpnew (Table) – The new device properties.

  • check (list) – The column names to check for equality.

Returns:

A dictionary containing the differences. The keys are

the LOCATION value, and the value is a dict with “old” and “new” keys that contain the table rows that differ.

Return type:

(dict)

desimodel.inputs.focalplane_utils.device_loc_to_type(loc)[source]

Get the fixed, hardcoded device type for a device location.

desimodel.inputs.focalplane_utils.device_printdiff(diff)[source]

Print a diff dictionary created with device_compare().

desimodel.inputs.focalplane_utils.exclusions_equal(ex1, ex2)[source]

Return True if the two polygons are equal, else False

desimodel.inputs.focalplane_utils.load_petal_fiber_map(existing=None, fibermaps=None)[source]

Loads info from petal verification files.

This loads the petal verification files from DocDB and populates a dictionary of properties.

Parameters:
  • existing (dict) – An existing dictionary to populate. If None, a new one is created and returned.

  • fibermaps (list) – (optional) Override list of tuples (DocDB number, DocDB version, DocDB csv file) of where to find the petal mapping files.

Returns:

A dictionary of dictionaries with the device location info

for every petal ID.

Return type:

(dict)

desimodel.inputs.focalplane_utils.propagate_state(state, excl, oldstate, oldexcl)[source]

Propagate state to a new focalplane model.

This takes a new state and exclusions and sets this new state to be the same as the old one for all locations that are specified in the oldstate. Any exclusions not defined in the new dictionary are copied from the old.

This function assumes that the old and new focalplane models have already been verified to be identical…

Parameters:
  • state (Table) – The new state table, modified in place.

  • excl (dict) – The new exclusions, modified in place.

  • oldstate (Table) – The old state table.

  • oldexcl (dict) – The old exclusions.

Returns:

None

desimodel.inputs.focalplane_utils.restricted_positioner_phi(radius, theta_arm, phi_arm, offset_p, min_p, max_p)[source]

Compute the MIN_P angle needed to restrict positioner reach.

Given the positioner arm lengths, desired maximum reach, and PHI offset and min / max, compute the new minimum phi angle needed to keep the positioner within the retracted radius.

Parameters:
  • radius (float) – The restricted radius in mm.

  • theta_arm (float) – The theta arm length in mm.

  • phi_arm (float) – The phi arm length in mm.

  • offset_p (float) – The OFFSET_P phi zero point.

  • min_p (float) – The MIN_P minimum phi angle.

  • max_p (float) – The MAX_P maximum phi angle.

Returns:

The restricted MIN_P value.

Return type:

(float)

desimodel.inputs.focalplane_utils.rotate_petals(fp)[source]

Rotate the X/Y offsets according to petal location.

The X / Y offsets of each device are rotated to the petal location for that device. The focalplane dictionary is modified in place.

Parameters:

fp (dict) – The focalplane dictionary.

Returns:

None

desimodel.inputs.focalplane_utils.update_exclusions(excl, paths=[])[source]

Update exclusion polygons in a focalplane model.

Parameters:
  • excl (dict) – Dictionary of exclusion polygons, modified in place.

  • paths (list) – List of file paths to append to the exclusions.

Returns:

None

desimodel.inputs.gfa

Utilities for updating GFA data.

desimodel.inputs.gfa.build_gfa_table(testdir=None)[source]

Builds the GFA table given the data from DESI-0530-v14 Excel spreadsheet and writes an .ecsv file using the astropy table library.

The GFA corners come from the P1-P4 “Reference projection of active area” in rows 26-29 of columns C-E of DESI-0530-v14.

The saved table has columns PETAL,CORNER,X,Y,Z,Q,S,RADIUS_DEG.

Parameters:

testdir – If not None, write files here instead of standard locations under $DESIMODEL/data/

desimodel.inputs.throughput

Utilities for updating throughput model.

desimodel.inputs.throughput.get_waveminmax(psffile)[source]

return wmin, wmax as taken from the header of a PSF file, e.g. $DESIMODEL/data/specpsf/psf-b.fits

desimodel.inputs.throughput.load_fiberinput(filename)[source]

Load fiberinput as calculated by fiberloss.py

Parameters:

filename – fiberloss input file, e.g. $DESIMODEL/data/throughput/fiberloss-elg.dat

Returns InterpolatedUnivariateSpline instance.

desimodel.inputs.throughput.load_spec_throughputs(filenames, columns='ABCD', first_row=2, last_row=647)[source]

Loads spectrograph*CCD throughputs from DESI-5501 excel files.

Parameters:

filenames – list of per-spectrograph filenames.

Returns arrays of wavelength in nm and throughput per spectrograph.

desimodel.inputs.throughput.load_throughput(filename, specthru_row=95, thru_row=97)[source]

Load throughputs from DESI-0347, removing the spectrograph contributions which will be loaded separately from higher resolution data.

Parameters:

filename – DESI-0347 Excel file location

Returns (thruspine, xlsdata), where

thruspline: InterpolatedUnivariateSpline of thru vs. wave[Angstroms] xlsdata: tuple of (wave, totalthru, specthru)

Notes

  • Alas, DESI-0347 doesn’t fill in the final throughput for 3500 and 9950 Angstroms, even though the inputs are there.

desimodel.inputs.throughput.update(testdir=None, desi347_version=16, desi5501_version=3, desi5501_KOSI=True)[source]

Update thru-[brz].fits from DESI-0347 and DESI-0344

Parameters:
  • testdir – If not None, write files here instead of standard locations under $DESIMODEL/data/

  • desi347_version – version of DESI-347 to use

  • desi5501_version – version of DESI-5501 to use

  • [bool] (desi5501_KOSI) – use KOSI throughput measurements in 5501

desimodel.install

Install data files not handled by pip install.

desimodel.install.assert_svn_exists()[source]

Assert svn command exists and raise an informative error if not

desimodel.install.default_install_dir()[source]

Return the default install directory. Assumes this file lives in a ‘site-packages’ directory.

Returns:

The path to the install directory.

Return type:

str

desimodel.install.install(desimodel=None, version=None)[source]

Primary workhorse function.

Parameters:
  • desimodel (str, optional) – Allows the install directory to be explicitly set.

  • version (str, optional) – Allows the desimodel version to be explicitly set.

Raises:

RuntimeError – Standard error output from svn export command when status is non-zero.

desimodel.install.main()[source]

Entry point for the install_desimodel_data script.

Returns:

An integer suitable for passing to sys.exit().

Return type:

int

desimodel.install.svn_export(desimodel_version=None)[source]

Create a svn export command suitable for downloading a particular desimodel version.

Parameters:

desimodel_version (str, optional) – The version X.Y.Z to download, trunk, or something of the form branches/… Defaults to trunk.

Returns:

A svn command in list form, suitable for passing to subprocess.Popen.

Return type:

list

desimodel.io

I/O utility functions for files in desimodel.

exception desimodel.io.MissingEnvVar[source]
desimodel.io.datadir(surveyops=False)[source]

Returns location to desimodel data.

Parameters:

surveyops (bool) – If True then find the relevant path for the $DESI_SURVEYOPS directory rather than the $DESIMODEL directory.

Notes

If surveyops`==``False` and DESIMODEL is set, then $DESIMODEL overrides data installed with the package.

desimodel.io.findfile(filename, surveyops=False)[source]

Return full path to data file $DESIMODEL/data/filename.

Parameters:
  • filename (str) – Name of the file, relative to the desimodel data directory.

  • surveyops (bool) – If True then find the relevant path for the $DESI_SURVEYOPS directory rather than the $DESIMODEL directory.

Returns:

The full path.

Return type:

str

Notes

This is a precursor for a potential future refactor where desimodel data would be installed with the package and DESIMODEL would become an optional override.

desimodel.io.get_focalplane_dates()[source]

Returns the dates of new focalplane definitions.

There are two levels of time-dependent changes within the focalplane. First are the focalplane definitions, defined by a set of files $DESIMODEL/data/focalplane/{desi-exclusion,desi-focalplane,desi-state}_DATE.. Those are the dates returned by this function, as a list of datetime objects.

The second level is that, within the “state” table, there are changes to the states of individual positioners. (These are the dates returned when get_time_range=True is set in load_focalplane().)

Returns:

dates – The dates when the focalplane changed.

Return type:

list of datetime

desimodel.io.load_desiparams()[source]

Returns DESI parameter dictionary loaded from $DESIMODEL/data/desi.yaml.

Returns:

The parameters read from the YAML file.

Return type:

dict

desimodel.io.load_deviceloc()[source]

Returns a table from $DESIMODEL/data/focalplane/fiberpos-all.fits.

Returns:

The data from the FITS file, with columns converted to uppercase.

Return type:

Table

desimodel.io.load_fiberpos()[source]

Returns fiberpos table from $DESIMODEL/data/focalplane/fiberpos.fits.

Returns:

The data from the FITS file, sorted by FIBER.

Return type:

Table

desimodel.io.load_focalplane(time=None, get_time_range=False)[source]

Load the focalplane state that is valid for the given time.

Parameters:

time (datetime) – The time to query with explicit timezone. Default to current time (now()) with timezone UTC.

Returns:

A tuple of (FP layout, exclusion polygons, state, time string). The FP layout is a Table. The exclusion polygons are a dictionary indexed by names that are referenced in the state. The state is a Table. The time string is the resulting UTC ISO format time string for the creation date of the FP model.

If get_time_range=True, returns two additional values: time_low and time_high, both datetime objects giving the range of dates over which this description of the focal plane is valid. time_high may be None, indicating that there is no later known hardware state. In particular, these dates refer to the state of the positioners, which are more fine-grained than the fp and exclusion objects.

Return type:

tuple

desimodel.io.load_gfa()[source]

Returns GFA table from $DESIMODEL/data/focalplane/gfa.ecsv.

Returns:

The data from the ECSV file.

Return type:

Table

desimodel.io.load_pixweight(nside, pixmap=None)[source]

Loads $DESIMODEL/data/footprint/desi-healpix-weights.fits.

Parameters:
  • nside (int) – After loading, the array will be resampled to the passed HEALPix nside.

  • pixmap (FITS_rec, optional) – Input pixel weight map, already read from a weights file.

Returns:

HEALPix weight map for the DESI footprint at the requested nside.

Return type:

Weight

desimodel.io.load_platescale()[source]

Loads platescale.txt.

Returns:

The data table read from the file.

Return type:

recarray

Notes

The returned object has these columns:

radius

Radius from center of focal plane [mm].

theta

Radial angle that has a centroid at this radius [deg].

radial_platescale

Meridional (radial) plate scale [um/arcsec].

az_platescale:

Sagittal (azimuthal) plate scale [um/arcsec].

arclength:

Unknown description.

desimodel.io.load_psf(channel)[source]

Returns specter PSF object for the given channel ‘b’, ‘r’, or ‘z’.

Parameters:

channel ({'b', 'r', 'z'}) – Spectrograph channel.

Returns:

A specter PSF object.

Return type:

PSF

desimodel.io.load_target_info()[source]

Loads data/targets/targets.yaml and returns the nested dictionary.

This is primarily syntactic sugar to avoid end users constructing paths and filenames by hand (which e.g. broke when targets.dat was renamed to targets.yaml).

Returns:

The dictionary read from the YAML file.

Return type:

dict

desimodel.io.load_throughput(channel)[source]

Returns specter Throughput object for the given channel ‘b’, ‘r’, or ‘z’.

Parameters:

channel ({'b', 'r', 'z'}) – Spectrograph channel.

Returns:

A specter throughput object.

Return type:

Throughput

desimodel.io.load_tiles(onlydesi=True, extra=False, tilesfile=None, cache=True, programs=None, surveyops=True)[source]

Return DESI tiles structure from $DESI_SURVEYOPS/trunk/ops/tiles-main.ecsv.

Parameters:
  • onlydesi (bool, optional) – If True, trim to just the tiles in the DESI footprint.

  • extra (bool, optional) – If True, include extra layers with PROGRAM='EXTRA'.

  • tilesfile (str, optional) – Name of tiles file to load; or None for default. See Notes for details.

  • cache (bool, optional) – If False, force reload of data from tiles file, instead of using cached values.

  • programs (list or str, optional) – Pass a list of program names to restrict to only those programs, e.g. [“DARK”, “BACKUP”].

  • surveyops (bool) – If True then find the relevant path for the $DESI_SURVEYOPS directory rather than the $DESIMODEL directory.

Returns:

The data table portion of the FITS file.

Return type:

FITS_rec

Raises:

FileNotFoundError – If the value of tilesfile does not exist.

Notes

Keyword-based environment variable expansion is performed on the tilesfile value, so e.g.:

tiles = load_tiles(tilesfile='{HOME}/my-tiles.fits')

will be expanded with the value of HOME.

If the parameter tilesfile is set, this function uses the following search method:

  1. Paths corresponding to both $DESI_SURVEYOPS/trunk/ops and $DESI_SURVEYOPS/ops are always both checked, to cover different svn checkout approaches.

  2. If the value includes an explicit path, even ./, use that file.

  3. If the value does not include an explicit path, and the file name is identical to a file in $DESI_SURVEYOPS/trunk/ops/, use the file in $DESI_SURVEYOPS/trunk/ops/ and issue a warning.

  4. If no matching file can be found at all, raise an exception.

desimodel.io.reset_cache()[source]

Reset I/O cache.

desimodel.trim

Code for trimming desimodel/data into smaller files.

desimodel.trim.inout(indir, outdir, filename)[source]

returns os.path.join(indir, filename) and .join(outdir, filename)

desimodel.trim.rebin_image(image, n)[source]

rebin 2D array pix into bins of size n x n

New binsize must be evenly divisible into original pix image

desimodel.trim.trim_data(indir, outdir, overwrite=False)[source]

Trim a $DESIMODEL/data directory into a lightweight version for testing.

Parameters:
  • indir (str) – A $DESIMODEL/data directory from svn.

  • outdir (str) – Output data directory location.

  • overwrite (bool, optional) – If True, remove outdir if it already exists.

desimodel.trim.trim_focalplane(indir, outdir)[source]

copy everything in focalplane

desimodel.trim.trim_footprint(indir, outdir)[source]

Copies subset of desi-tiles.fits and .ecsv but not .par. Also creates a corresponding version of desi-healpix-weights.fits.

desimodel.trim.trim_inputs(indir, outdir)[source]

Don’t copy any inputs

desimodel.trim.trim_sky(indir, outdir)[source]

copy solarspec file as-is

desimodel.trim.trim_specpsf(indir, outdir)[source]

trim specpsf files to be much smaller

desimodel.trim.trim_spectra(indir, outdir)[source]

downsample spectra, and only a few of them

desimodel.trim.trim_targets(indir, outdir)[source]

copy everything in targets/

desimodel.trim.trim_throughput(indir, outdir)[source]

downsample throughput files

desimodel.trim.trim_weather(indir, outdir)[source]

copy everything in weather/

desimodel.weather

Model of the expected weather conditions at KPNO during the DESI survey.

To generate a random time series of expected FWHM seeing in arcsecs and atmospheric transparency, use, for example:

n = 10000
dt = 300 # seconds
t = np.arange(n) * dt
gen = np.random.RandomState(seed=123)
seeing = sample_seeing(n, dt_sec=dt, gen=gen)
transp = sample_transp(n, dt_sec=dt, gen=gen)

The resulting arrays are randomly sampled from models of the 1D probability density and 2-point power spectral density derived from MzLS observations. See DESI-doc-3087 for details.

Used by surveysim.weather for simulations of DESI observing and survey strategy studies.

desimodel.weather._seeing_fit_model(x)[source]

Evalute the fit to MzLS seeing described in DESI-doc-3087.

desimodel.weather._seeing_psd(freq)[source]

Evaluate the ‘chi-by-eye’ fit of the seeing PSD described in DESI-doc-3087.

desimodel.weather._transp_psd(freq)[source]

Evaluate the ‘chi-by-eye’ fit of the transparency PSD described in DESI-doc-3087.

desimodel.weather.dome_closed_fractions(start_date, stop_date, replay='Y2007,Y2008,Y2009,Y2010,Y2011,Y2012,Y2013,Y2014')[source]

Return dome-closed fractions for each night of the survey.

Years can be replayed in any order. If the number of years to replay is less than the survey duration, they are repeated.

Parameters:
  • start_date (datetime.date or None) – Survey starts on the evening of this date. Use the first_day config parameter if None (the default).

  • stop_date (datetime.date or None) – Survey stops on the morning of this date. Use the last_day config parameter if None (the default).

  • replay (str) – Comma-separated list of years to replay, identified by arbitrary strings that must match column names in the DESIMODEL weather history.

Returns:

1D array of N probabilities between 0-1, where N is the number of nights spanned by the start and stop dates.

Return type:

numpy array

desimodel.weather.get_seeing_pdf(median_seeing=1.1, max_seeing=2.5, n=250)[source]

Return PDF of FWHM seeing for specified clipped median value.

Note that this is atmospheric seeing, not delivered image quality. The reference wavelength for seeing values is 6355A, in the r band, and the observed wavelength dependence in Dey & Valdes is closer to lambda ** (-1/15) than the lambda ** (-1/5) predicted by Kolmogorov theory. See DESI-doc-3087 for details.

Scales the clipped MzLS seeing PDF in order to achieve the requested median value. Note that clipping is applied before scaling, so the output PDF is clipped at scale * max_seeing.

Parameters:
  • median_seeing (float) – Target FWHM seeing value in arcsec. Must be in the range [0.95, 1.30].

  • max_seeing (float) – Calculate scaled median using unscaled values below this value.

  • n (int) – Size of grid to use for tabulating the returned arrays.

Returns:

Tuple (fwhm, pdf) that tabulates pdf[fwhm]. Normalized so that np.sum(pdf * np.gradient(fwhm)) = 1.

Return type:

tuple

desimodel.weather.get_transp_pdf(n=250)[source]

Return PDF of atmospheric transparency.

Derived from MzLS observations, but corrected for dust accumulation and measurement error. See DESI-doc-3087 for details.

Parameters:

n (int) – Size of grid to use for tabulating the returned arrays.

Returns:

Tuple (transp, pdf) that tabulates pdf[transp]. Normalized so that np.sum(pdf * np.gradient(transp)) = 1.

Return type:

tuple

desimodel.weather.sample_seeing(n_sample, dt_sec=180.0, median_seeing=1.1, max_seeing=2.5, gen=None)[source]

Generate a random time series of FWHM seeing values.

See DESI-doc-3087 for details. Uses get_seeing_pdf(), _seeing_psd() and sample_timeseries().

Parameters:
  • n_sample (int) – Number of equally spaced samples to generate.

  • dt_sec (float) – Time interval between samples in seconds.

  • median_seeing (float) – See get_seeing_pdf().

  • mex_seeing (float) – See get_seeing_pdf().

  • gen (np.random.RandomState or None) – Provide an existing RandomState for full control of reproducible random numbers, or None for non-reproducible random numbers.

Returns:

1D array of randomly generated samples.

Return type:

array

desimodel.weather.sample_timeseries(x_grid, pdf_grid, psd, n_sample, dt_sec=180.0, gen=None)[source]

Sample a time series specified by a power spectrum and 1D PDF.

The PSD should describe the temporal correlations of whitened samples. Generated samples will then be unwhitened to recover the input 1D PDF. See DESI-doc-3087 for details.

Uses whiten_transforms_from_cdf().

Parameters:
  • x_grid (array) – 1D array of N increasing grid values covering the parameter range to sample from.

  • pdf_grid (array) – 1D array of N increasing PDF values corresponding to each x_grid. Does not need to be normalized.

  • psd (callable) – Function of frequency in 1/days that returns the power-spectral density of whitened temporal fluctations to sample from. Will only be called for positive frequencies. Normalization does not matter.

  • n_sample (int) – Number of equally spaced samples to generate.

  • dt_sec (float) – Time interval between samples in seconds.

  • gen (np.random.RandomState or None) – Provide an existing RandomState for full control of reproducible random numbers, or None for non-reproducible random numbers.

desimodel.weather.sample_transp(n_sample, dt_sec=180.0, gen=None)[source]

Generate a random time series of atmospheric transparency values.

See DESI-doc-3087 for details. Uses get_transp_pdf(), _transp_psd() and sample_timeseries().

Parameters:
  • n_sample (int) – Number of equally spaced samples to generate.

  • dt_sec (float) – Time interval between samples in seconds.

  • gen (np.random.RandomState or None) – Provide an existing RandomState for full control of reproducible random numbers, or None for non-reproducible random numbers.

Returns:

1D array of randomly generated samples.

Return type:

array

desimodel.weather.whiten_transforms(data, data_min=None, data_max=None)[source]

Calculate a pair of transforms to whiten and unwhiten a distribution.

Uses desimodel.weather.whiten_transforms_from_cdf().

Parameters:
  • data (array) – 1D array of samples from the distribution to whiten.

  • data_min (float or None) – Clip the distribution to this minimum value, or at min(data) if None. Must be <= min(data).

  • data_max (float or None) – Clip the distribution to this maximum value, or at max(data) if None. Must be >= max(data).

Returns:

See desimodel.weather.whiten_transforms_from_cdf().

Return type:

tuple

desimodel.weather.whiten_transforms_from_cdf(x, cdf)[source]

Calculate a pair of transforms to whiten and unwhiten a distribution.

The whitening transform is monotonic and invertible.

Parameters:
  • x (array) – 1D array of non-decreasing values giving bin edges for the distribution to whiten and unwhiten.

  • cdf (array) – 1D array of non-decreasing values giving the cummulative probability density associated with each bin edge. Does not need to be normalized. Must have the same length as x.

Returns:

Tuple (F,G) of callable objects that whiten y=F(x) and unwhiten x=G(y) samples x of the input distribution, so that y has a Gaussian distribution with zero mean and unit variance.

Return type:

tuple