Source code for gemini_instruments.common

"""
Structures and functions that can be shared across instrument code.

When should you add something here? Here's some criteria: the code
that belongs in here is not generally useful outside of
gemini_instruments, and:

    - more than one instrument share the code to override a method
      that provides *default* behaviour, meaning that there's no
      common ancestor where you can put this; or,
    - it doesn't make sense to put the code in a method, as it
      doesn't rely on internal knowledge of a class.
"""
from astrodata import Section

[docs] def build_group_id(ad, desc_list, prettify=(), force_list=(), additional=None): """ Builds a Group ID from information found in the descriptors. It takes a number of descriptor names, invokes and then concatenates their result (converted to string) to from a group ID. Additional parameters can be passed to modify the result. Parameters ---------- ad: AstroData An instance of `AstroData` derivative that the descriptors will be desc_list: list of str A list of descriptor names (order matters) which will be used to build the Group ID prettify: sequence/set of str Names of descriptors that need to be invoked with `pretty=True` force_list: sequence/set of str The descriptors named in this list will have their results coerced into a list, if they returned something else. additional: str Additional information that will be added verbatim at the end of the Group ID Returns ------- A string with the group id """ desc_object_string_list = [] for descriptor in desc_list: desc_method = getattr(ad, descriptor) if descriptor in prettify or 'section' in descriptor: desc_object = desc_method(pretty=True) else: desc_object = desc_method() # Ensure we get a list, even if only looking at one extension if (descriptor in force_list and not isinstance(desc_object, list)): desc_object = [desc_object] # Convert descriptor to a string and store desc_object_string_list.append(str(desc_object)) # Add in any none descriptor related information if additional is not None: desc_object_string_list.append(additional) # Create and return the final group_id string return '_'.join(desc_object_string_list)
[docs] def build_ir_section(ad, pretty=False): """ 1st gen Gemini IR instruments don't have handy BIASSEC/DATASEC/etc keywords. This function creates section info out of other keywords. Code common to NIRI and GNIRS. Parameters ---------- ad: AstroData The object that we want to extract the section from pretty: bool if True, return a string rather than a Section Returns ------- A list of `Section` instances. """ # This is identical to the GNIRS code try: hirows = ad.hdr['HIROW'] lowrows = ad.hdr['LOWROW'] hicols = ad.hdr['HICOL'] lowcols = ad.hdr['LOWCOL'] except KeyError: return None # NOTE: Rows are X and cols are Y? These Romans are crazy def format_section(x1,x2,y1,y2, pretty): return "[{:d}:{:d},{:d}:{:d}]".format(x1+1, x2+1, y1+1, y2+1) if pretty else Section(x1, x2+1, y1, y2+1) if ad.is_single: xs = hirows - lowrows + 1 ys = hicols - lowcols + 1 return format_section(512 - xs // 2, 512 + xs // 2 - 1, 512 - ys // 2, 512 + ys // 2 - 1, pretty) else: xsize = [x2 - x1 + 1 for x1, x2 in zip(lowrows, hirows)] ysize = [y2 - y1 + 1 for y1, y2 in zip(lowcols, hicols)] return [format_section(512 - xs // 2, 512 + xs // 2 - 1, 512 - ys // 2, 512 + ys // 2 - 1, pretty) for xs, ys in zip(xsize, ysize)]