Пример #1
0
    def set_section(self, value):
        if type(value) != str:
            raise TypeError('Input type must be string. Got %s' % type(value))

        self.sec = slice_from_string(value)
        self.serial_size = self.sec[1].stop - self.sec[1].start
        self.parallel_size = self.sec[0].stop - self.sec[0].start
Пример #2
0
def slices_config(config):
    """
    From a string of the configuration file containing slices, returns a list with the slices to calculate, for example,
    the overscan, or trim image.
    :param config: string containing the slices
    :return: slices
    """
    return [slice_from_string(match.group()) for match in inside_brackets.finditer(config)]
Пример #3
0
def _trim_oscan(ccd, biassec, trimsec, model=None):
    """Subtract the overscan region and trim image to desired size.
    The CCDPROC function subtract_overscan() expects the TRIMSEC of the image
    (the part you want to keep) to span the entirety of one dimension, with the
    BIASSEC (overscan section) being at the end of the other dimension.
    Both LMI and DeVeny have edge effects on all sides of their respective
    chips, and so the TRIMSEC and BIASSEC do not meet the expectations of
    subtract_overscan().
    Therefore, this function is a wrapper to first remove the undesired ROWS
    from top and bottom, then perform the subtract_overscan() fitting and
    subtraction, followed by trimming off the now-spent overscan region.
    Args:
        ccd (:TYPE:`internal link or datatype`)
            Description.
        biassec (:TYPE:`str`)
            Description.
        trimsec (:TYPE:`str`)
            Description.
        model (:TYPE:internal link or datatype`)
            Description.
    Returns:
        ccd (:TYPE:`internal link or datatype`)
            Description.
    """

    # Convert the FITS bias & trim sections into slice classes for use
    yb, xb = slice_from_string(biassec, fits_convention=True)
    yt, xt = slice_from_string(trimsec, fits_convention=True)

    # First trim off the top & bottom rows
    ccd = ccdp.trim_image(ccd[yt.start:yt.stop, :])

    # Model & Subtract the overscan
    if model is None:
        model = models.Chebyshev1D(1)  # Chebyshev 1st order function
    else:
        model = models.Chebyshev1D(1)  # Figure out how to incorporate others
    ccd = ccdp.subtract_overscan(ccd,
                                 overscan=ccd[:, xb.start:xb.stop],
                                 median=True,
                                 model=model)

    # Trim the overscan & return
    return ccdp.trim_image(ccd[:, xt.start:xt.stop])
Пример #4
0
def slices_config(config):
    """
    From a string of the configuration file containing slices, returns a list with the slices to calculate, for example,
    the overscan, or trim image.
    :param config: string containing the slices
    :return: slices
    """
    return [
        slice_from_string(match.group())
        for match in inside_brackets.finditer(config)
    ]
Пример #5
0
def make_overscan_test_files(request, tmpdir):
    """
    Creates two files, one with overscan, one without for Alta U9

    Parameters

    test_dir: str
        Directory in which to create the overscan files.

    Returns

    info: list
        (working_dir, has_oscan, has_no_oscan)
        working_dir: str
            subdirectory of test_dir in which files are created
        has_oscan: str
            Name of FITS file that has overscan region
        has_no_oscan: str
            Name of FITS file that has no overscan region
    """
    from .header_processing.feder import ApogeeAltaU9, MaximDL5
    from os import path, mkdir
    import astropy.io.fits as fits
    import numpy as np

    test_dir = tmpdir
    oscan_names = ['yes_scan', 'no_scan']
    oscan = {'yes_scan': True,
             'no_scan': False}
    apogee = ApogeeAltaU9()
    working_dir = 'overscan_test'
    working_path = test_dir.mkdir(working_dir)
    add_instrument = lambda hdr: hdr.set('instrume', 'Apogee Alta')
    name_fits = lambda name: name + '.fit'
    for name in oscan_names:
        if oscan[name]:
            data = np.zeros([apogee.rows, apogee.columns])
            has_oscan = name
        else:
            osc_slice = slice_from_string(apogee.trim_region)
            data = np.zeros([apogee.rows, osc_slice[0].stop])
            no_oscan = name
        hdu = fits.PrimaryHDU(data)
        hdr = hdu.header
        add_instrument(hdu.header)
        mdl5 = MaximDL5()
        # all headers need a software name
        hdr[mdl5.fits_keyword] = mdl5.fits_name[0]
        hdr['imagetyp'] = 'LIGHT'
        hdu.writeto(path.join(working_path.strpath, name_fits(name)))

    return (working_path.strpath, name_fits(has_oscan), name_fits(no_oscan))
Пример #6
0
def make_overscan_test_files(request, tmpdir):
    """
    Creates two files, one with overscan, one without for Alta U9

    Parameters

    test_dir: str
        Directory in which to create the overscan files.

    Returns

    info: list
        (working_dir, has_oscan, has_no_oscan)
        working_dir: str
            subdirectory of test_dir in which files are created
        has_oscan: str
            Name of FITS file that has overscan region
        has_no_oscan: str
            Name of FITS file that has no overscan region
    """
    from .header_processing.feder import ApogeeAltaU9, MaximDL5
    from os import path, mkdir
    import astropy.io.fits as fits
    import numpy as np

    test_dir = tmpdir
    oscan_names = ['yes_scan', 'no_scan']
    oscan = {'yes_scan': True, 'no_scan': False}
    apogee = ApogeeAltaU9()
    working_dir = 'overscan_test'
    working_path = test_dir.mkdir(working_dir)
    add_instrument = lambda hdr: hdr.set('instrume', 'Apogee Alta')
    name_fits = lambda name: name + '.fit'
    for name in oscan_names:
        if oscan[name]:
            data = np.zeros([apogee.rows, apogee.columns])
            has_oscan = name
        else:
            osc_slice = slice_from_string(apogee.trim_region)
            data = np.zeros([apogee.rows, osc_slice[0].stop])
            no_oscan = name
        hdu = fits.PrimaryHDU(data)
        hdr = hdu.header
        add_instrument(hdu.header)
        mdl5 = MaximDL5()
        # all headers need a software name
        hdr[mdl5.fits_keyword] = mdl5.fits_name[0]
        hdr['imagetyp'] = 'LIGHT'
        hdu.writeto(path.join(working_path.strpath, name_fits(name)))

    return (working_path.strpath, name_fits(has_oscan), name_fits(no_oscan))
Пример #7
0
    def has_overscan(self, image_dimensions):
        """
        Determine whether an image taken by this instrument has overscan

        Parameters
        ----------
        image_dimensions : list-like with two elements
            Shape of the image; can be any type as long as it has two elements.
            The order should be the FITS order, ``NAXIS1`` then ``NAXIS2``.

        Returns
        -------
        bool
            Indicates whether or not image has overscan present.
        """

        if self.trim_region is None:
            return False

        # Grab the trim region as a slice to make it easier to access end
        # points. Do *not* convert from FITS convention because input
        # dimensions follow FITS conventions.
        trim_dim = slice_from_string(self.trim_region)

        dim_end = lambda ax: (trim_dim[ax].stop + 1
                              if trim_dim[ax].stop is not None
                              else image_dimensions[ax])
        # print(trim_dim1, trim_dim2)
        # if trim_dim1.stop is not None:
        #     dim1_end = trim_dim1.stop + 1
        # else:
        #     # None means use the whole thing....
        #     dim1_end = image_dimensions[0]

        # if trim_dim2.stop is not None:
        #     dim2_end = trim_dim2.stop + 1
        # else:
        #     # None means use the whole thing....
        #     dim2_end = image_dimensions[1]

        if (dim_end(0) < image_dimensions[0] or
            dim_end(1) < image_dimensions[1]):

            return True
        else:
            return False
Пример #8
0
    def has_overscan(self, image_dimensions):
        """
        Determine whether an image taken by this instrument has overscan

        Parameters
        ----------
        image_dimensions : list-like with two elements
            Shape of the image; can be any type as long as it has two elements.
            The order should be the FITS order, ``NAXIS1`` then ``NAXIS2``.

        Returns
        -------
        bool
            Indicates whether or not image has overscan present.
        """

        if self.trim_region is None:
            return False

        # Grab the trim region as a slice to make it easier to access end
        # points. Do *not* convert from FITS convention because input
        # dimensions follow FITS conventions.
        trim_dim = slice_from_string(self.trim_region)

        dim_end = lambda ax: (trim_dim[ax].stop + 1 if trim_dim[ax].stop is
                              not None else image_dimensions[ax])
        # print(trim_dim1, trim_dim2)
        # if trim_dim1.stop is not None:
        #     dim1_end = trim_dim1.stop + 1
        # else:
        #     # None means use the whole thing....
        #     dim1_end = image_dimensions[0]

        # if trim_dim2.stop is not None:
        #     dim2_end = trim_dim2.stop + 1
        # else:
        #     # None means use the whole thing....
        #     dim2_end = image_dimensions[1]

        if (dim_end(0) < image_dimensions[0]
                or dim_end(1) < image_dimensions[1]):

            return True
        else:
            return False
Пример #9
0
def cropImage(image, trim=None, zoom=None, center=None, pixels=None, width=None):
    if isinstance(image, str):
        image = fits2CCDData(image, single=True).data
    if trim is not None:
        return image[slice_from_string(trim)]
    if center is None:
        center = (image.shape[0] / 2, image.shape[1] / 2)
    dy, dx = image.shape
    if zoom is not None:
        if isinstance(zoom, (list, tuple)):
            xzoom, yzoom = zoom
        else:
            xzoom, yzoom = zoom, zoom
        if xzoom < 1.0 or yzoom < 1.0:
            print ('WARNING: Zoom needs to be >= 1.0 [%s, %s]! Nothing done!' % (xzoom, yzoom))
            return image
        dy /= yzoom 
        dx /= xzoom
        idy = slice(center[0] - int(dy / 2), center[0] + int(dy / 2), None)
        idx = slice(center[1] - int(dx / 2), center[1] + int(dx / 2), None)
        image = image[idy, idx]
    elif pixels is not None:
        if isinstance(pixels, (tuple, list, np.ndarray)):
            ypix, xpix = pixels
        else:
            ypix, xpix = pixels, pixels
        if ypix is not None:
            image = image[ypix : dy - ypix, ...]
        if xpix is not None:
            image = image[..., xpix: dx - xpix]
    elif width is not None:
        if isinstance(width, (tuple, list, np.ndarray)):
            ywidth, xwidth = width
        else:
            ywidth, xwidth = width, width
        if ywidth is not None:
            idy = slice(center[0] - int(ywidth / 2), center[0] + int(ywidth / 2), None)
            image = image[idy, ...]
        if xwidth is not None:
            idx = slice(center[1] - int(xwidth / 2), center[1] + int(xwidth / 2), None)
            image = image[..., idx]
    return image
Пример #10
0
    def _calc_zsw(fun, arr, section=None):
        fun_simple = _nanfun2nonnan(fun)
        if section is not None:
            try:
                sl = slice_from_string(section, fits_convention=True)
            except (AttributeError, ValueError):  # i.e., int-convertible
                sl = int(section)
        else:
            sl = [slice(None)]*(arr.ndim - 1)

        # TODO: There must be a better way to do this "redo" strategy...
        try:
            # If converted to numpy, this must work without error:
            if isinstance(sl, int):
                zsw = [fun_simple(arr[i].ravel()[::sl], axis=None)
                       for i in range(arr.shape[0])]
            else:
                zsw = fun_simple(arr[(slice(None), *sl)],
                                 axis=tuple(np.arange(arr.ndim)[1:]))
            redo = ~np.all(np.isfinite(zsw))
        except TypeError:  # does not accept tuple axis
            redo = True

        if redo:
            zsw = []
            if isinstance(sl, int):
                try:
                    zsw = [(fun(arr[i].ravel()[::sl], axis=None))
                           for i in range(arr.shape[0])]
                except TypeError:  # original fun has no `axis` parameter
                    zsw = [(fun(arr[i].ravel()[::sl]))
                           for i in range(arr.shape[0])]
            else:
                try:
                    zsw = [(fun(arr[(i, *sl)], axis=None)) for i in range(arr.shape[0])]
                except TypeError:  # original fun has no `axis` parameter
                    zsw = [(fun(arr[(i, *sl)])) for i in range(arr.shape[0])]
        # raise ValueError()
        return np.atleast_1d(zsw)
Пример #11
0
 def parse_scan(scan):
     # print scan
     # Try to parse it to integer
     try:
         reg_len = int(scan[1])
         if scan[0] == 'serial_pre':
             log.debug('Serial pre-scan with %i length.' % reg_len)
             return self.section[0], slice(self.section[1].start-reg_len,self.section[1].start)
         elif scan[0] == 'serial_pos':
             log.debug('Serial pos-scan with %i length.' % reg_len)
             return self.section[0], slice(self.section[1].stop,self.section[1].stop+reg_len)
         elif scan[0] == 'parallel_pre':
             log.debug('Parallel pre-scan with %i length.' % reg_len)
             return slice(self.section[0].start-reg_len,self.section[0].start), self.section[1]
         elif scan[0] == 'parallel_pos':
             log.debug('Parallel pos-scan with %i length.' % reg_len)
             return slice(self.section[0].stop,self.section[0].stop+reg_len), self.section[1]
         else:
             raise KeyError('%s is not a valid key. Should be one of serial_pre, serial_pos, '
                            'parallel_pre or parallel_pos' % (scan[0]))
     except ValueError, e:
         log.debug('Region is not convertible to int. Falling back to slice mode.')
         return slice_from_string(scan[1])