Beispiel #1
0
def _data_stretch(image, vmin=None, vmax=None, pmin=0.25, pmax=99.75,
                  stretch='linear', vmid=None, exponent=2):

    if vmin is None or vmax is None:
        interval = AsymmetricPercentileInterval(pmin, pmax, n_samples=10000)
        try:
            vmin_auto, vmax_auto = interval.get_limits(image)
        except IndexError:  # no valid values
            vmin_auto = vmax_auto = 0

    if vmin is None:
        log.info("vmin = %10.3e (auto)" % vmin_auto)
        vmin = vmin_auto
    else:
        log.info("vmin = %10.3e" % vmin)

    if vmax is None:
        log.info("vmax = %10.3e (auto)" % vmax_auto)
        vmax = vmax_auto
    else:
        log.info("vmax = %10.3e" % vmax)

    if stretch == 'arcsinh':
        stretch = 'asinh'

    normalizer = simple_norm(image, stretch=stretch, power=exponent,
                             asinh_a=vmid, min_cut=vmin, max_cut=vmax, clip=False)

    data = normalizer(image, clip=True).filled(0)
    data = np.nan_to_num(data)
    data = np.clip(data * 255., 0., 255.)

    return data.astype(np.uint8)
Beispiel #2
0
def starfind(setup,
             path_to_image,
             reduction_metadata,
             plot_it=False,
             log=None):
    """
    The routine will quickly identify stars in a given image and return 
    a star list and image quality parameters. The output is to be used
    to select suitable candidate images for constructing a template
    reference image.
    
    :param object setup: this is an instance of the ReductionSetup class. See
                         reduction_control.py
    
    :param string path_to_image: The full path to the image to be processed.
    
    :param object reduction_metadata: The reduction metadata object from
                         which to extract the saturation value.
    
    :param boolean plot_it: Do you want to plot the selected stars?
    
    :param string log: Full The full path to the log file.
    
    :return status, report, params: the first two are strings reporting whether
                          the stage was completed successfully. params is 
                          a dictionary with the image quality parameters.
    
    :rtype string, string, dictionary
    """

    imname = path_to_image.split('/')[-1]

    if log != None:
        log.info('Starting starfind')

    params = {
        'sky': 0.0,
        'fwhm_y': 0.0,
        'fwhm_x': 0.0,
        'corr_xy': 0.0,
        'nstars': 0,
        'sat_frac': 0.0,
        'symmetry': 1.
    }

    t0 = time.time()
    im = fits.open(path_to_image)
    header = im[0].header
    scidata = im[0].data

    # Get size of image
    ymax, xmax = scidata.shape

    # If it is a large image, consider 250x250 pixel subregions and
    # choose the one with the fewest saturated pixels to evaluate stats
    try:

        saturation = reduction_metadata.reduction_parameters[1]['MAXVAL']

    except:

        if log != None:

            status = 'ERROR'
            report = ('Could not extract the saturation parameter '
                      'from the configuration file.')

            log.info(report)

            return status, report, params

    nr_sat_pix = 100000
    bestx1 = -1
    bestx2 = -1
    besty1 = -1
    besty2 = -1
    regionsx = np.arange(0, xmax, 250)
    regionsy = np.arange(0, ymax, 250)

    for i in regionsx[0:-1]:

        x1 = i
        x2 = i + 250

        for j in regionsy[0:-1]:

            y1 = j
            y2 = j + 250
            nr_pix = len(
                scidata[y1:y2,
                        x1:x2][np.where(scidata[y1:y2, x1:x2] > saturation)])
            #print x1, x2, y1, y2, nr_pix

            if nr_pix < nr_sat_pix:
                nr_sat_pix = nr_pix
                bestx1 = x1
                bestx2 = x2
                besty1 = y1
                besty2 = y2

    #mean, median, std = sigma_clipped_stats(scidata[1:ymax, 1:xmax], sigma=3.0, iters=5)
    # Evaluate mean, median and standard deviation for the selected subregion
    mean, median, std = sigma_clipped_stats(scidata[besty1:besty2,
                                                    bestx1:bestx2],
                                            sigma=3.0,
                                            iters=5)

    # Identify stars
    daofind = DAOStarFinder(fwhm=3.0, threshold=5. * std)

    sources = daofind(scidata[besty1:besty2, bestx1:bestx2] - median)

    # Write steps to a log file
    if log != None:
        log.info("Identifying sources on image %s ...\n" %
                 path_to_image.split('/')[-1])
        log.info("Found %s sources.\n" % str(len(sources)))

        if len(sources) == 0:

            status = 'ERROR'
            report = 'Insufficient number of sources found. Stopping execution.'

            log.info(report)

            return status, report, params

        elif (len(sources) > 0 and len(sources) <= 5):

            log.info('WARNING: Too few sources detected on image.')

        else:

            log.info('Using best sources to determine FWHM (up to 30).')

    # Discount saturated stars
    sources = sources[np.where(sources['peak'] < saturation)]
    sources.sort('peak')
    sources.reverse()

    # Store the number of identified sources and fraction of saturated pixels
    nstars = len(sources)
    sat_frac = nr_sat_pix / (250. * 250.)

    # Discount stars too close to the edges of the image
    sources = sources[np.where((sources['xcentroid'] > 10)
                               & (sources['xcentroid'] < 240)
                               & (sources['ycentroid'] < 240)
                               & (sources['ycentroid'] > 30))]

    # Keep only up to 100 stars
    sources = sources[0:100]

    sources_with_close_stars_ids = []
    # Discount stars with close neighbours (within r=10 pix)

    for i in np.arange(len(sources)):

        source_i = sources[i]

        for other_source in sources[i + 1:]:

            if (np.sqrt(
                (source_i['xcentroid'] - other_source['xcentroid'])**2 +
                (source_i['ycentroid'] - other_source['ycentroid'])**2) <= 10):

                sources_with_close_stars_ids.append(i)
                #print source_i, other_source

            continue

    # Keep up to 30 isolated sources only (may be fewer)
    sources.remove_rows(sources_with_close_stars_ids)
    sources = sources[0:30]

    if log != None:
        log.info("Kept %s sources.\n" % str(len(sources)))

    #return sources
    # Uncomment the following line to display source list in browser window:
    #sources.show_in_browser()

    # Fit a model to identified sources and estimate PSF shape parameters
    sky_arr = []
    fwhm_x_arr = []
    fwhm_y_arr = []
    corr_xy_arr = []

    i = 0
    while (i <= len(sources) - 1):

        try:
            i_peak = sources[i]['peak']
            position = [sources[i]['xcentroid'], sources[i]['ycentroid']]
            #print position
            stamp_size = (20, 20)
            cutout = Cutout2D(scidata[besty1:besty2, bestx1:bestx2], position,
                              stamp_size)  # in pixels
            yc, xc = cutout.position_cutout
            yy, xx = np.indices(cutout.data.shape)
            fit = psf.fit_star(cutout.data,
                               yy,
                               xx,
                               psf_model='BivariateNormal')
            fit_params = fit[0]
            fit_errors = fit[1].diagonal()**0.5
            biv = psf.BivariateNormal()
            background = psf.ConstantBackground()
            fit_residuals = psf.error_star_fit_function(
                fit_params, cutout.data, biv, background, yy, xx)
            fit_residuals = fit_residuals.reshape(cutout.data.shape)
            cov = fit[1] * np.sum(fit_residuals**2) / ((stamp_size[0])**2 - 6)
            fit_errors = cov.diagonal()**0.5
            #print fit_params
            model = biv.psf_model(yy, xx, fit_params)
            fwhm_y_arr.append(fit_params[3])
            fwhm_x_arr.append(fit_params[4])
            corr_xy_arr.append(fit_params[5])
            sky_arr.append(fit_params[6])

            if plot_it == True:
                plt.figure(figsize=(3, 8))
                plt.subplot(3, 1, 1)
                plt.imshow(cutout.data, cmap='gray', origin='lower')
                plt.colorbar()
                plt.title("Data")
                plt.subplot(3, 1, 2)
                plt.imshow(model, cmap='gray', origin='lower')
                plt.colorbar()
                plt.title("Model")
                plt.subplot(3, 1, 3)
                plt.imshow(fit_residuals, cmap='gray', origin='lower')
                plt.title("Residual")
                plt.colorbar()
                plt.savefig(path.join(setup.red_dir, 'starfind_model.png'))
        except:
            if log != None:
                log.info("Could not fit source: %s." % str(i))

        i = i + 1

    # Estimate the median values for the parameters over the stars identified
    params['sky'] = np.median(sky_arr)
    params['fwhm_y'] = np.median(fwhm_y_arr)
    params['fwhm_x'] = np.median(fwhm_x_arr)
    params['corr_xy'] = np.median(corr_xy_arr)
    params['nstars'] = nstars
    params['sat_frac'] = sat_frac

    try:
        if xmax > 200 and ymax > 200:
            psf_emp, psf_error_emp = empirical_psf_simple.empirical_psf_median(
                np.copy(scidata)[:200, :200], 20, saturation)
        else:
            psf_emp, psf_error_emp = empirical_psf_simple.empirical_psf_median(
                np.copy(scidata), 20, saturation)
        #imgname = os.path.basename(path_to_image)
        #hduout=fits.PrimaryHDU(psf_emp)
        #hduout.writeto('psf_'+imgname,overwrite = True)
        symmetry_metric = empirical_psf_simple.symmetry_check(psf_emp)
        params['symmetry'] = symmetry_metric
    except Exception as e:

        if log != None:
            report = ('Could not extract the symmetry based on the PSF ')
            log.info(report)

    if log != None:
        log.info('Measured median values:')
        log.info('Sky background = ' + str(params['sky']))
        log.info('FWHM X = ' + str(params['fwhm_x']))
        log.info('FWHM Y = ' + str(params['fwhm_y']))
        log.info('Corr XY = ' + str(params['corr_xy']))
        log.info('Nstars = ' + str(params['nstars']))
        log.info('Saturation fraction = ' + str(params['sat_frac']))
        log.info('symmetry = ' + str(params['symmetry']))
    # If plot_it is True, plot the sources found
    if plot_it == True:

        temp = np.copy(scidata[besty1:besty2, bestx1:bestx2])
        temp[np.where(temp < median)] = median
        temp[np.where(temp > 25000)] = 25000
        positions = (sources['xcentroid'], sources['ycentroid'])
        apertures = CircularAperture(positions, r=4.)
        norm = ImageNormalize(interval=AsymmetricPercentileInterval(10, 40),
                              stretch=SqrtStretch())
        plt.imshow(temp, cmap='gray', origin='lower', norm=norm)
        plt.title("Data")
        #plt.colorbar()
        apertures.plot(color='red', lw=1.2, alpha=0.5)
        plt.savefig(path.join(setup.red_dir, 'stars250x250.png'))
        im.close()

    if log != None:
        log.info("Finished processing image %s in %.3f seconds.\n" %
                 (str(imname), (time.time() - t0)))

    status = 'OK'
    report = 'Completed successfully'
    return status, report, params
Beispiel #3
0
    async def get(self, object_id: str = None):
        """
        ---
        summary: Serve alert cutout as fits or png
        tags:
          - alerts
          - kowalski

        parameters:
          - in: query
            name: instrument
            required: false
            schema:
              type: str
          - in: query
            name: candid
            description: "ZTF alert candid"
            required: true
            schema:
              type: integer
          - in: query
            name: cutout
            description: "retrieve science, template, or difference cutout image?"
            required: true
            schema:
              type: string
              enum: [science, template, difference]
          - in: query
            name: file_format
            description: "response file format: original loss-less FITS or rendered png"
            required: true
            default: png
            schema:
              type: string
              enum: [fits, png]
          - in: query
            name: interval
            description: "Interval to use when rendering png"
            required: false
            schema:
              type: string
              enum: [min_max, zscale]
          - in: query
            name: stretch
            description: "Stretch to use when rendering png"
            required: false
            schema:
              type: string
              enum: [linear, log, asinh, sqrt]
          - in: query
            name: cmap
            description: "Color map to use when rendering png"
            required: false
            schema:
              type: string
              enum: [bone, gray, cividis, viridis, magma]

        responses:
          '200':
            description: retrieved cutout
            content:
              image/fits:
                schema:
                  type: string
                  format: binary
              image/png:
                schema:
                  type: string
                  format: binary

          '400':
            description: retrieval failed
            content:
              application/json:
                schema: Error
        """
        instrument = self.get_query_argument("instrument", "ZTF").upper()
        if instrument not in INSTRUMENTS:
            raise ValueError("Instrument name not recognised")

        # allow access to public data only by default
        selector = {1}

        for stream in self.associated_user_object.streams:
            if "ztf" in stream.name.lower():
                selector.update(set(stream.altdata.get("selector", [])))

        selector = list(selector)

        try:
            candid = int(self.get_argument("candid"))
            cutout = self.get_argument("cutout").capitalize()
            file_format = self.get_argument("file_format", "png").lower()
            interval = self.get_argument("interval", default=None)
            stretch = self.get_argument("stretch", default=None)
            cmap = self.get_argument("cmap", default=None)

            known_cutouts = ["Science", "Template", "Difference"]
            if cutout not in known_cutouts:
                return self.error(
                    f"Cutout {cutout} of {object_id}/{candid} not in {str(known_cutouts)}"
                )
            known_file_formats = ["fits", "png"]
            if file_format not in known_file_formats:
                return self.error(
                    f"File format {file_format} of {object_id}/{candid}/{cutout} not in {str(known_file_formats)}"
                )

            normalization_methods = {
                "asymmetric_percentile": AsymmetricPercentileInterval(
                    lower_percentile=1, upper_percentile=100
                ),
                "min_max": MinMaxInterval(),
                "zscale": ZScaleInterval(nsamples=600, contrast=0.045, krej=2.5),
            }
            if interval is None:
                interval = "asymmetric_percentile"
            normalizer = normalization_methods.get(
                interval.lower(),
                AsymmetricPercentileInterval(lower_percentile=1, upper_percentile=100),
            )

            stretching_methods = {
                "linear": LinearStretch,
                "log": LogStretch,
                "asinh": AsinhStretch,
                "sqrt": SqrtStretch,
            }
            if stretch is None:
                stretch = "log" if cutout != "Difference" else "linear"
            stretcher = stretching_methods.get(stretch.lower(), LogStretch)()

            if (cmap is None) or (
                cmap.lower() not in ["bone", "gray", "cividis", "viridis", "magma"]
            ):
                cmap = "bone"
            else:
                cmap = cmap.lower()

            query = {
                "query_type": "find",
                "query": {
                    "catalog": "ZTF_alerts",
                    "filter": {
                        "candid": candid,
                        "candidate.programid": {"$in": selector},
                    },
                    "projection": {"_id": 0, f"cutout{cutout}": 1},
                },
                "kwargs": {"limit": 1, "max_time_ms": 5000},
            }

            response = kowalski.query(query=query)

            if response.get("status", "error") == "success":
                alert = response.get("data", [dict()])[0]
            else:
                return self.error("No cutout found.")

            cutout_data = bj.loads(bj.dumps([alert[f"cutout{cutout}"]["stampData"]]))[0]

            # unzipped fits name
            fits_name = pathlib.Path(alert[f"cutout{cutout}"]["fileName"]).with_suffix(
                ""
            )

            # unzip and flip about y axis on the server side
            with gzip.open(io.BytesIO(cutout_data), "rb") as f:
                with fits.open(io.BytesIO(f.read())) as hdu:
                    header = hdu[0].header
                    data_flipped_y = np.flipud(hdu[0].data)

            if file_format == "fits":
                hdu = fits.PrimaryHDU(data_flipped_y, header=header)
                hdul = fits.HDUList([hdu])

                stamp_fits = io.BytesIO()
                hdul.writeto(fileobj=stamp_fits)

                self.set_header("Content-Type", "image/fits")
                self.set_header(
                    "Content-Disposition", f"Attachment;filename={fits_name}"
                )
                self.write(stamp_fits.getvalue())

            if file_format == "png":
                buff = io.BytesIO()
                plt.close("all")

                fig, ax = plt.subplots(figsize=(4, 4))
                fig.subplots_adjust(0, 0, 1, 1)
                ax.set_axis_off()

                # replace nans with median:
                img = np.array(data_flipped_y)
                # replace dubiously large values
                xl = np.greater(np.abs(img), 1e20, where=~np.isnan(img))
                if img[xl].any():
                    img[xl] = np.nan
                if np.isnan(img).any():
                    median = float(np.nanmean(img.flatten()))
                    img = np.nan_to_num(img, nan=median)
                norm = ImageNormalize(img, stretch=stretcher)
                img_norm = norm(img)
                vmin, vmax = normalizer.get_limits(img_norm)
                ax.imshow(img_norm, cmap=cmap, origin="lower", vmin=vmin, vmax=vmax)
                plt.savefig(buff, dpi=42)
                buff.seek(0)
                plt.close("all")
                self.set_header("Content-Type", "image/png")
                self.write(buff.getvalue())

        except Exception:
            _err = traceback.format_exc()
            return self.error(f"failure: {_err}")
Beispiel #4
0
def display_single(img,
                   pixel_scale=0.168,
                   physical_scale=None,
                   xsize=8,
                   ysize=8,
                   ax=None,
                   alpha=1.0,
                   stretch='arcsinh',
                   scale='zscale',
                   zmin=None,
                   zmax=None,
                   contrast=0.25,
                   no_negative=False,
                   lower_percentile=1.0,
                   upper_percentile=99.0,
                   cmap=IMG_CMAP,
                   scale_bar=True,
                   scale_bar_length=5.0,
                   scale_bar_fontsize=20,
                   scale_bar_y_offset=0.5,
                   scale_bar_color='w',
                   scale_bar_loc='left',
                   color_bar=False,
                   color_bar_loc=1,
                   color_bar_width='75%',
                   color_bar_height='5%',
                   color_bar_fontsize=18,
                   color_bar_color='w',
                   add_text=None,
                   text_fontsize=30,
                   text_color='w'):
    """Display single image.

    Parameters
    ----------
        img: np 2-D array for image

        xsize: int, default = 8
            Width of the image.

        ysize: int, default = 8
            Height of the image.

    """
    if ax is None:
        fig = plt.figure(figsize=(xsize, ysize))
        ax1 = fig.add_subplot(111)
    else:
        ax1 = ax

    # Stretch option
    if stretch.strip() == 'arcsinh':
        img_scale = np.arcsinh(img)
        if zmin is not None:
            zmin = np.arcsinh(zmin)
        if zmax is not None:
            zmax = np.arcsinh(zmax)
    elif stretch.strip() == 'log':
        if no_negative:
            img[img <= 0.0] = 1.0E-10
        img_scale = np.log(img)
        if zmin is not None:
            zmin = np.log(zmin)
        if zmax is not None:
            zmax = np.log(zmax)
    elif stretch.strip() == 'log10':
        if no_negative:
            img[img <= 0.0] = 1.0E-10
        img_scale = np.log10(img)
        if zmin is not None:
            zmin = np.log10(zmin)
        if zmax is not None:
            zmax = np.log10(zmax)
    elif stretch.strip() == 'linear':
        img_scale = img
    else:
        raise Exception("# Wrong stretch option.")

    # Scale option
    if scale.strip() == 'zscale':
        try:
            vmin, vmax = ZScaleInterval(
                contrast=contrast).get_limits(img_scale)
        except IndexError:
            # TODO: Deal with problematic image
            vmin, vmax = -1.0, 1.0
    elif scale.strip() == 'percentile':
        try:
            vmin, vmax = AsymmetricPercentileInterval(
                lower_percentile=lower_percentile,
                upper_percentile=upper_percentile).get_limits(img_scale)
        except IndexError:
            # TODO: Deal with problematic image
            vmin, vmax = -1.0, 1.0
    elif scale.strip() == 'minmax':
        vmin, vmax = np.nanmin(img_scale), np.nanmax(img_scale)
    else:
        vmin, vmax = np.nanmin(img_scale), np.nanmax(img_scale)

    if zmin is not None:
        vmin = zmin
    if zmax is not None:
        vmax = zmax

    show = ax1.imshow(img_scale,
                      origin='lower',
                      cmap=cmap,
                      interpolation='none',
                      vmin=vmin,
                      vmax=vmax,
                      alpha=alpha)

    # Hide ticks and tick labels
    ax1.tick_params(labelbottom=False,
                    labelleft=False,
                    axis=u'both',
                    which=u'both',
                    length=0)

    # Put scale bar on the image
    (img_size_x, img_size_y) = img.shape
    if physical_scale is not None:
        pixel_scale *= physical_scale
    if scale_bar:
        if scale_bar_loc == 'left':
            scale_bar_x_0 = int(img_size_x * 0.04)
            scale_bar_x_1 = int(img_size_x * 0.04 +
                                (scale_bar_length / pixel_scale))
        else:
            scale_bar_x_0 = int(img_size_x * 0.95 -
                                (scale_bar_length / pixel_scale))
            scale_bar_x_1 = int(img_size_x * 0.95)

        scale_bar_y = int(img_size_y * 0.10)
        scale_bar_text_x = (scale_bar_x_0 + scale_bar_x_1) / 2
        scale_bar_text_y = (scale_bar_y * scale_bar_y_offset)
        if physical_scale is not None:
            scale_bar_text = r'$%d\ \mathrm{kpc}$' % int(scale_bar_length)
        else:
            scale_bar_text = r'$%d^{\prime\prime}$' % int(scale_bar_length)
        scale_bar_text_size = scale_bar_fontsize

        ax1.plot([scale_bar_x_0, scale_bar_x_1], [scale_bar_y, scale_bar_y],
                 linewidth=3,
                 c=scale_bar_color,
                 alpha=1.0)
        ax1.text(scale_bar_text_x,
                 scale_bar_text_y,
                 scale_bar_text,
                 fontsize=scale_bar_text_size,
                 horizontalalignment='center',
                 color=scale_bar_color)
    if add_text is not None:
        text_x_0 = int(img_size_x * 0.08)
        text_y_0 = int(img_size_y * 0.80)
        ax1.text(text_x_0,
                 text_y_0,
                 r'$\mathrm{' + add_text + '}$',
                 fontsize=text_fontsize,
                 color=text_color)

    # Put a color bar on the image
    if color_bar:
        ax_cbar = inset_axes(ax1,
                             width=color_bar_width,
                             height=color_bar_height,
                             loc=color_bar_loc)
        if ax is None:
            cbar = plt.colorbar(show,
                                ax=ax1,
                                cax=ax_cbar,
                                orientation='horizontal')
        else:
            cbar = plt.colorbar(show,
                                ax=ax,
                                cax=ax_cbar,
                                orientation='horizontal')

        cbar.ax.xaxis.set_tick_params(color=color_bar_color)
        cbar.ax.yaxis.set_tick_params(color=color_bar_color)
        cbar.outline.set_edgecolor(color_bar_color)
        plt.setp(plt.getp(cbar.ax.axes, 'xticklabels'),
                 color=color_bar_color,
                 fontsize=color_bar_fontsize)
        plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'),
                 color=color_bar_color,
                 fontsize=color_bar_fontsize)

    if ax is None:
        return fig
    return ax1
Beispiel #5
0
#kde = stats.gaussian_kde(imx)
#density = kde(imx)
#peak = max(peak,0.01)
#low_perc = max(low_perc,0.01)
# set 1% as the minimum cut
#print ("Histo Peak at %f, will use it as lower percentile (i.e. remove everything below)"%(h_peak))
#
#peak_norm = (peak - np.min(bins1))/(np.max(bins1) - np.min(bins1))
#print ("Normalized peak is at %f"%(peak_norm))
#n1, bins1, patches1 = plt.hist(image[~np.isnan(image)], 50, normed=1, facecolor='green', histtype='step',alpha=0.75)
#
#%%
fig = plt.figure(figsize=(10, 10))

norm = ImageNormalize(image,
                      interval=AsymmetricPercentileInterval(
                          mode_x * 100, 99.5),
                      stretch=AsinhStretch())
#norm = ImageNormalize(image,interval=PercentileInterval(98),stretch=SqrtStretch())
#norm = ImageNormalize(image,interval=PercentileInterval(99.5),stretch=LogStretch())
ax = fig.add_subplot(111)
ax.imshow(image,
          cmap=cm.gray,
          norm=norm,
          origin="lower",
          interpolation="nearest")
ax.get_xaxis().set_ticks([])
ax.get_yaxis().set_ticks([])
ax.annotate("%s, %i %s" % (target, myObsid, band),
            textcoords='axes fraction',
            fontsize=10,
            xy=(0.05, 0.95),
Beispiel #6
0
def display_single(img,
                   pixel_scale=0.168,
                   physical_scale=None,
                   xsize=8,
                   ysize=8,
                   ax=None,
                   stretch='arcsinh',
                   scale='zscale',
                   scale_manual=None,
                   contrast=0.25,
                   no_negative=False,
                   lower_percentile=1.0,
                   upper_percentile=99.0,
                   cmap=IMG_CMAP,
                   scale_bar=True,
                   scale_bar_length=5.0,
                   scale_bar_fontsize=20,
                   scale_bar_y_offset=0.5,
                   scale_bar_color='w',
                   scale_bar_alpha=1.0,
                   scale_bar_loc='left',
                   color_bar=False,
                   color_bar_loc=1,
                   color_bar_width='75%',
                   color_bar_height='5%',
                   color_bar_fontsize=18,
                   color_bar_color='w',
                   add_text=None,
                   text_fontsize=30,
                   text_box=None,
                   text_facecolor='gray',
                   text_x_offset=0.08,
                   text_y_offset=0.80,
                   text_color='w',
                   text_fontweight='normal'):
    """
    Display single image using ``arcsinh`` stretching, "zscale" scaling and ``viridis`` colormap as default. 
    This function is from ``kungpao`` https://github.com/dr-guangtou/kungpao.

    Parameters:
        img (numpy 2-D array): The image array.
        pixel_scale (float): The pixel size, in unit of "arcsec/pixel".
        physical_scale (bool): Whether show the image in physical scale.
        xsize (int): Width of the image, default = 8. 
        ysize (int): Height of the image, default = 8. 
        ax (``matplotlib.pyplot.axes`` object): The user could provide axes on which the figure will be drawn.
        stretch (str): Stretching schemes. Options are "arcsinh", "log", "log10" and "linear".
        scale (str): Scaling schemes. Options are "zscale" and "percentile".
        contrast (float): Contrast of figure.
        no_negative (bool): If true, all negative pixels will be set to zero.
        lower_percentile (float): Lower percentile, if using ``scale="percentile"``.
        upper_percentile (float): Upper percentile, if using ``scale="percentile"``.
        cmap (str): Colormap.
        scale_bar (bool): Whether show scale bar or not.
        scale_bar_length (float): The length of scale bar.
        scale_bar_y_offset (float): Offset of scale bar on y-axis.
        scale_bar_fontsize (float): Fontsize of scale bar ticks.
        scale_bar_color (str): Color of scale bar.
        scale_bar_alpha (float): alpha of scale bar.
        scale_bar_loc (str): Scale bar position, options are "left" and "right".
        color_bar (bool): Whether show colorbar or not.
        add_text (str): The text you want to add to the figure. Note that it is wrapped within ``$\mathrm{}$``.
        text_fontsize (float): Fontsize of text.
        text_y_offset (float): Offset of text on y-axis.
        text_color (str): Color of text.
        text_box (dict): dictionary for box. Such as `dict(boxstyle='round', facecolor='wheat', alpha=0.5)`.

    Returns:
        ax: If the input ``ax`` is not ``None``.

    """
    from PIL import Image, ImageOps
    if ax is None:
        fig = plt.figure(figsize=(xsize, ysize))
        ax1 = fig.add_subplot(111)
    else:
        ax1 = ax

    if isinstance(img, Image.Image):
        img = ImageOps.flip(img)
        show = ax1.imshow(
            img,
            origin='lower',
            cmap=cmap,
        )
        (img_size_x, img_size_y) = img.size
    else:
        (img_size_x, img_size_y) = img.shape
        # Stretch option
        if stretch.strip() == 'arcsinh':
            img_scale = np.arcsinh(img)
        elif stretch.strip() == 'log':
            if no_negative:
                img[img <= 0.0] = 1.0E-10
            img_scale = np.log(img)
        elif stretch.strip() == 'log10':
            if no_negative:
                img[img <= 0.0] = 1.0E-10
            img_scale = np.log10(img)
        elif stretch.strip() == 'linear':
            img_scale = img
        else:
            raise Exception("# Wrong stretch option.")

        # Scale option
        if scale.strip() == 'zscale':
            try:
                zmin, zmax = ZScaleInterval(
                    contrast=contrast).get_limits(img_scale)
            except IndexError:
                # TODO: Deal with problematic image
                zmin, zmax = -1.0, 1.0
        elif scale.strip() == 'percentile':
            try:
                zmin, zmax = AsymmetricPercentileInterval(
                    lower_percentile=lower_percentile,
                    upper_percentile=upper_percentile).get_limits(img_scale)
            except IndexError:
                # TODO: Deal with problematic image
                zmin, zmax = -1.0, 1.0
        else:
            zmin, zmax = np.nanmin(img_scale), np.nanmax(img_scale)

        if scale_manual is not None:
            assert len(
                scale_manual) == 2, '# length of manual scale must be two!'
            zmin, zmax = scale_manual

        show = ax1.imshow(img_scale,
                          origin='lower',
                          cmap=cmap,
                          vmin=zmin,
                          vmax=zmax)

    # Hide ticks and tick labels
    ax1.tick_params(labelbottom=False,
                    labelleft=False,
                    axis=u'both',
                    which=u'both',
                    length=0)
    #ax1.axis('off')

    # Put scale bar on the image

    if physical_scale is not None:
        pixel_scale *= physical_scale
    if scale_bar:
        if scale_bar_loc == 'left':
            scale_bar_x_0 = int(img_size_x * 0.04)
            scale_bar_x_1 = int(img_size_x * 0.04 +
                                (scale_bar_length / pixel_scale))
        else:
            scale_bar_x_0 = int(img_size_x * 0.95 -
                                (scale_bar_length / pixel_scale))
            scale_bar_x_1 = int(img_size_x * 0.95)

        scale_bar_y = int(img_size_y * 0.10)
        scale_bar_text_x = (scale_bar_x_0 + scale_bar_x_1) / 2
        scale_bar_text_y = (scale_bar_y * scale_bar_y_offset)
        if physical_scale is not None:
            if scale_bar_length > 1000:
                scale_bar_text = r'$%d\ \mathrm{Mpc}$' % int(
                    scale_bar_length / 1000)
            else:
                scale_bar_text = r'$%d\ \mathrm{kpc}$' % int(scale_bar_length)
        else:
            if scale_bar_length < 60:
                scale_bar_text = r'$%d^{\prime\prime}$' % int(scale_bar_length)
            elif 60 < scale_bar_length < 3600:
                scale_bar_text = r"%d arcmin" % int(
                    scale_bar_length / 60)  # r'$%d^{\prime}$'
            else:
                scale_bar_text = r'$%d^{\circ}$' % int(scale_bar_length / 3600)
        scale_bar_text_size = scale_bar_fontsize

        ax1.plot([scale_bar_x_0, scale_bar_x_1], [scale_bar_y, scale_bar_y],
                 linewidth=5,
                 c=scale_bar_color,
                 alpha=scale_bar_alpha)
        ax1.text(scale_bar_text_x,
                 scale_bar_text_y,
                 scale_bar_text,
                 fontsize=scale_bar_text_size,
                 fontweight=text_fontweight,
                 horizontalalignment='center',
                 color=scale_bar_color,
                 alpha=scale_bar_alpha)
    if add_text is not None:
        text_x_0 = int(img_size_x * text_x_offset)
        text_y_0 = int(img_size_y * text_y_offset)
        ax1.text(text_x_0,
                 text_y_0,
                 add_text,
                 horizontalalignment='left',
                 verticalalignment='top',
                 fontsize=text_fontsize,
                 color=text_color,
                 bbox=text_box,
                 fontweight=text_fontweight)
    # Put a color bar on the image
    if color_bar:
        ax_cbar = inset_axes(ax1,
                             width=color_bar_width,
                             height=color_bar_height,
                             loc=color_bar_loc)
        if ax is None:
            cbar = plt.colorbar(show,
                                ax=ax1,
                                cax=ax_cbar,
                                orientation='horizontal')
        else:
            cbar = plt.colorbar(show,
                                ax=ax,
                                cax=ax_cbar,
                                orientation='horizontal')

        cbar.ax.xaxis.set_tick_params(color=color_bar_color)
        cbar.ax.yaxis.set_tick_params(color=color_bar_color)
        cbar.outline.set_edgecolor(color_bar_color)
        plt.setp(plt.getp(cbar.ax.axes, 'xticklabels'),
                 color=color_bar_color,
                 fontsize=color_bar_fontsize)
        plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'),
                 color=color_bar_color,
                 fontsize=color_bar_fontsize)

    if ax is None:
        return fig
    return ax1
#pl.subplots_adjust(left=panel_rect[0], bottom=panel_rect[1], right=panel_rect[0]+panel_rect[2], top=panel_rect[1]+panel_rect[3])
pl.imshow(FitsImage, cmap='gray', origin='lower', aspect='equal', norm=LogNorm())
#cb = pl.colorbar()
# 
# Save eps
# 
fig.savefig('%s.scale.log.jpg'%(FitsFile), format='jpg')
print('Output to %s'%('%s.scale.log.jpg'%(FitsFile)))


# 
# Plot the fits image in 99.5 percentile
# 
if [[ 1 == 0 ]]; then
    pl.cla()
    #fig.delaxes(fig.axes[-1]) # remove previous colorbar
    #pl.subplots_adjust(left=panel_rect[0], bottom=panel_rect[1], right=panel_rect[0]+panel_rect[2], top=panel_rect[1]+panel_rect[3])
    normfun = ImageNormalize(FitsImage, interval=AsymmetricPercentileInterval(19.5,99.5))
    pl.imshow(FitsImage, cmap='gray', origin='lower', aspect='equal', norm=normfun)
    #cb = pl.colorbar()
    # 
    # Save eps
    # 
    fig.savefig('%s.scale.995.jpg'%(FitsFile), format='jpg')
    print('Output to %s'%('%s.scale.995.jpg'%(FitsFile)))



print('Done!')

Beispiel #8
0
    def plot_rgb(self,
                 filters,
                 ax=None,
                 ra=None,
                 dec=None,
                 radius=None,
                 north=True,
                 rscale=2,
                 upper_scale=99.7,
                 lower_scale=1,
                 asinh_factor=0.7):
        """ Given a filter, makes a normalized, asinh-stretched plot of a galaxy.
        INPUTS:
            filters:     list of filter names [red, green, blue] e.g. ["i", "r", "g"]
            ax:          axis to plot on. If None, create a new plot
            north:       align the data North? Default: True
            rpet:        radius of the galaxy. If None, use "size" from the Galaxy object
            xc, yc:      pixel coordinates of image center. If None, use ra, dec of Galaxy
            rpet_scale:  image scale in terms of galaxy radii
            upper_scale, lower_scale: scales used in normalization. By default, upper_scale
                         is given in metadata or 99.7; lower_scale is 1
        """

        # Load the images for each filter
        data = {"r": {}, "g": {}, "b": {}}
        for filt, key in zip(filters, data):
            node = self.data[filt]
            data[key]["img"] = node["img"][()]
            data[key]["wcs"] = attr_to_wcs(node.attrs)
            data[key]["pxscale"] = node.attrs["pxscale"]

        # If ra, dec and rpet are not passed, populate them using galaxy properties
        if ra is None or dec is None or radius is None:
            ra, dec, radius = self.ra, self.dec, self.size

        # Resize all images
        for k, v in data.items():
            v["img"], v["wcs"] = _resize(v["img"],
                                         v["wcs"],
                                         ra,
                                         dec,
                                         v["pxscale"],
                                         radius,
                                         scale=rscale)

        # Create a WCS to reproject the images to using blue WCS (north-aligned?)
        rgb_wcs = data["b"]["wcs"].deepcopy()
        if north:
            rgb_pxscale = data["b"]["pxscale"]
            rgb_wcs = _rotate_wcs(rgb_wcs, ra, dec, rgb_pxscale)

        # Define stretch and norm
        try:
            upper_scale = self.data.attrs["uscale"]
        except:
            pass
        stretch = AsinhStretch(asinh_factor)
        norm = AsymmetricPercentileInterval(lower_scale, upper_scale)
        norm_r = AsymmetricPercentileInterval(lower_scale, upper_scale - 0.1)

        # Reproject all data onto this new WCS, apply norm and stretch
        for k, v in data.items():
            img = reproject_interp((v["img"], v["wcs"]),
                                   rgb_wcs,
                                   shape_out=data["b"]["img"].shape)[
                                       0]  #data["b"]["img"].shape)[0]
            img = stretch(norm_r(img)) if k == "r" else stretch(norm(img))
            v["plot_img"] = img

        # Make a data cube
        rgb = np.dstack([val["plot_img"] for key, val in data.items()])

        # If ax=None, create figure
        if ax is None:
            fig = plt.figure(figsize=(6, 6))
            ax = plt.axes()
            ax.axis('off')

        ax.imshow(rgb, origin="lower")
Beispiel #9
0
def normalize_img(img_arr, stretch='asinh', minmax_percent=None, minmax_value=None, invert=False):
    """
    Apply given stretch and scaling to an image array.

    Parameters
    ----------
    img_arr : array
        The input image array.
    stretch : str
        Optional, default 'asinh'. The stretch to apply to the image array.
        Valid values are: asinh, sinh, sqrt, log, linear
    minmax_percent : array
        Optional. Interval based on a keeping a specified fraction of pixels (can be asymmetric) 
        when scaling the image. The format is [lower percentile, upper percentile], where pixel
        values below the lower percentile and above the upper percentile are clipped.
        Only one of minmax_percent and minmax_value shoul be specified.
    minmax_value : array
        Optional. Interval based on user-specified pixel values when scaling the image.
        The format is [min value, max value], where pixel values below the min value and above
        the max value are clipped.
        Only one of minmax_percent and minmax_value should be specified.
    invert : bool
        Optional, default False.  If True the image is inverted (light pixels become dark and vice versa).

    Returns
    -------
    response : array
        The normalized image array, in the form in an integer arrays with values in the range 0-255.
    """


    # Setting up the transform with the stretch
    if stretch == 'asinh':
        transform = AsinhStretch()
    elif stretch == 'sinh':
        transform = SinhStretch()
    elif stretch == 'sqrt':
        transform = SqrtStretch()
    elif stretch == 'log':
        transform = LogStretch()
    elif stretch == 'linear':
        transform = LinearStretch()
    else:
        raise InvalidInputError("Stretch {} is not supported!".format(stretch))

    # Adding the scaling to the transform
    if minmax_percent is not None:
        transform += AsymmetricPercentileInterval(*minmax_percent)
        
        if minmax_value is not None:
            warnings.warn("Both minmax_percent and minmax_value are set, minmax_value will be ignored.",
                          InputWarning)
    elif minmax_value is not None:
        transform += ManualInterval(*minmax_value)
    else:  # Default, scale the entire image range to [0,1]
        transform += MinMaxInterval()
   
    # Performing the transform and then putting it into the integer range 0-255
    norm_img = transform(img_arr)
    norm_img = np.multiply(255, norm_img, out=norm_img)
    norm_img = norm_img.astype(np.uint8)

    # Applying invert if requested
    if invert:
        norm_img = 255 - norm_img

    return norm_img
Beispiel #10
0
        imdss   = sax.imshow(dssdata, transform=sax.get_transform(dssw), cmap='bone', vmin=vmin+dmad)
        textent = None
        talpha  = .66
    else:
        sax     = plt.subplot()
        textent = [column, column+args.size, row, row+args.size]
        talpha  = 1


    lcmap     = cmap_map(lambda x: 0.6*x, cm.get_cmap(args.cmap))
    #stamp     = sax.imshow(np.log10(np.nanmedian(flux[::10], axis=0)),
    #                       cmap=lcmap, origin='lower', aspect='equal', alpha=talpha,
    #                       extent=textent)

    mstamp    = np.nanmedian(flux[::10], axis=0)
    norm      = ImageNormalize(mstamp, interval=AsymmetricPercentileInterval(0,100), stretch=LogStretch(a=250))
    stamp     = sax.imshow(mstamp,
                           cmap=lcmap, origin='lower', aspect='equal', alpha=talpha,
                           extent=textent, norm=norm)

    xm, ym = pixel_border(dap[bidx])
    for xi,yi in zip(xm, ym):
        if args.pngdss:
            sax.plot(xi, yi, color='#FF0043', lw=1.5, transform=sax.get_transform('pixel'))
        else:
            sax.plot(column+xi, row+yi, color='#FF0043', lw=1.5)
    

    #sax.grid(which='minor', zorder=99)
    #sax.grid(color='white')
Beispiel #11
0
def get_regstat(fixed_image, moving_image, out_stats, out_tm, out_qc, tm):
    x = [[]]

    time1 = time.time()
    # loading images
    target = plt.imread(fixed_image)
    #tar=cv2.imread(fixed_image)
    target_name = os.path.split(fixed_image)[1]
    # print(target_name)
    # target=cv2.resize(target,(5705,5705))
    # tar=cv2.resize(tar,(5705,5705))
    moving = plt.imread(moving_image)
    #mov=cv2.imread(moving_image)
    # moving=cv2.resize(moving,(5705,5705))
    # mov=cv2.resize(mov,(5705,5705))
    moving_name = os.path.split(moving_image)[-1]
    # print(moving_name)

    # registration
    #a=target.shape[0]
    b=target.shape[1]
    #moving=cv2.resize(moving,(b,b))
    mov_avg=np.mean(moving.astype("float"))
    print(target.shape)
    print(moving.shape)
    res=ird.similarity(target,moving)
    def_moving=res['timg']
    scale=res['scale']
    angle=res['angle']
    (t0,t1)=res['tvec']
    #def_moving, scale, angle, (t0, t1) = imreg.similarity(target, moving)
    def_mov_array=imreg.similarity_matrix(scale,angle,(t0,t1))
    np.save(out_tm, def_mov_array)
    def_avg=np.mean(def_moving.astype("float"))
    # def_moving=cv2.resize(def_moving,(5705,5705))

    time2 = time.time()
    ti = time2-time1
    # statistical results
    cc = np.corrcoef(moving.flat, target.flat)
    r1 = cc[0, 1]

    score1, diff = compare_ssim(target, moving, full=True, multichannel=True)

    loss_before = 0.5*(1-r1) + 0.5*(1-score1)

    cc = np.corrcoef(def_moving.flat, target.flat)
    r2 = cc[0, 1]

    score2, diff = compare_ssim(def_moving, target, full=True)

    loss_after = 0.5*(1-r2) + 0.5*(1-score2)

    mi_bef = mutual_info_score(moving.ravel(), target.ravel())

    mi_aft = mutual_info_score(target.ravel(), def_moving.ravel())

    mae = np.sum(np.absolute(target.astype("float") - moving.astype("float")))
    u1 = np.sum(target.astype("float") + moving.astype("float"))
    mean_before = np.divide(mae, u1)
    u2 = np.sum(target.astype("float") + def_moving.astype("float"))
    mae = np.sum(np.absolute(target.astype(
        "float") - def_moving.astype("float")))
    mean_after = np.divide(mae, u2)
    t = Texttable()
    #print(def_moving.shape)
    if mi_aft > mi_bef:
        plt.imsave(tm, def_moving,cmap='gray')
    else:
        plt.imsave(tm, moving,cmap='gray')
    # plt.imsave(tm,def_moving,cmap='gray')
    x.append([target_name, moving_name, r1, r2, score1, score2, loss_before,
              loss_after, mi_bef, mi_aft, mean_before, mean_after,mov_avg,def_avg, ti])

    t.add_rows(x)
    t.set_cols_align(['r', 'r', 'r', 'r', 'r', 'r',
                      'r', 'r', 'r', 'r', 'r', 'r', 'r','r', 'r'])
    t.header(['TARGET', 'MOVING', 'PCC_BEFORE', 'PCC_AFTER', 'SSIM_BEFORE', 'SSIM_AFTER',
              'loss_BEFORE', 'loss_AFTER', 'MI_BEFORE', 'MI_AFTER', 'MEAN_BEFORE', 'MEAN_AFTER', 'AVERAGE_INTENSITY_BEFORE', 'AVERAGE_INTENSITY_AFTER','TIME'])
    def_mov1 = cv2.imread(tm,0)

    # plotting the results

    transform = AsinhStretch() + AsymmetricPercentileInterval(0.1, 99.99)
    targ= transform(target)
    #targ=cv2.cvtColor(targ.astype(np.uint8),cv2.COLOR_GRAY2RGB)
    #targ_im=Image.fromarray(targ)

    plt.imsave('target.tiff', targ, cmap='gray')
    #plt.imsave(r'/media/u0132399/L-drive/GBW-0075_MILAN_Multiplex/u0140317/registration_comparison/imreg/output_images/target.tiff', targ, cmap='gray')
    movi = transform(moving)
    #movi=cv2.cvtColor(movi.astype(np.uint8),cv2.COLOR_GRAY2BGR)
    plt.imsave('moving.tiff', movi, cmap='gray')
    #movi_im=Image.fromarray(movi)
    #plt.imsave(r'/media/u0132399/L-drive/GBW-0075_MILAN_Multiplex/u0140317/registration_comparison/imreg/output_images/moving.tiff', movi, cmap='gray')
    targ = cv2.imread('target.tiff')
    #targ=Image.open(targ_im)
    movi= cv2.imread('moving.tiff')
    #movi=Image.open(movi_im)
    #targ = cv2.imread( r'/media/u0132399/L-drive/GBW-0075_MILAN_Multiplex/u0140317/registration_comparison/imreg/output_images/target.tiff')
    #movi = cv2.imread(r'/media/u0132399/L-drive/GBW-0075_MILAN_Multiplex/u0140317/registration_comparison/imreg/output_images/moving.tiff')
    
    # def_mov1=cv2.resize(def_mov1,(5705,5705))
    def_mov1 = transform(def_mov1)
    #print(def_mov2.shape)
    
    #def_mov1=cv2.cvtColor(def_mov1.astype(np.uint8),cv2.COLOR_GRAY2BGR)
    plt.imsave('def_moving.tiff', def_mov1, cmap='gray')
    #def_mov1=Image.fromarray(def_mov1)
    #plt.imsave('/media/u0132399/L-drive/GBW-0075_MILAN_Multiplex/u0140317/registration_comparison/imreg/output_images/def_moving.tiff', def_mov1, cmap='gray')
    def_mov1 = cv2.imread('def_moving.tiff')
    #def_mov1=Image.open(def_mov1)
   
    #def_mov1 = cv2.imread(r'/media/u0132399/L-drive/GBW-0075_MILAN_Multiplex/u0140317/registration_comparison/imreg/output_images/def_moving.tiff')
    #targ = targ.astype(np.uint8)
    #movi = movi.astype(np.uint8)
    #def_mov1 = def_mov1.astype(np.uint8)
    
    tar1 = np.zeros(targ.shape)
    mov1 = np.zeros(movi.shape)
    def_mov = np.zeros(def_mov1.shape)
    tar1[:, :, 0] = targ[:, :, 0]
    mov1[:, :, 2] = movi[:, :, 2]
    def_mov[:, :, 2] = def_mov1[:, :, 2]
    tar1 = tar1.astype(np.uint8)
    mov1 = mov1.astype(np.uint8)
    def_mov = def_mov.astype(np.uint8)
  
    # mov[np.where((mov>[15]).all(axis=2))]=[255,0,0]
    # def_mov1[np.where((def_mov1>[15]).all(axis=2))]=[255,0,0]
    alpha = 1
    beta = 1
    gamma = 0
    t1 = cv2.addWeighted(tar1, alpha, mov1, beta, gamma)
    
    # filename=target_name+moving_name+'unreg_imreg.tif'
    # cv2.imwrite(,t1)
    
    
    t2 = cv2.addWeighted(tar1, alpha, def_mov, beta, gamma)
    
    # filename=target_name+moving_name+'reg_imreg.tif'
    # cv2.imwrite(filename,t2)
    if mi_aft > mi_bef:
        cv2.imwrite(out_qc, t2)
        
    else:
        cv2.imwrite(out_qc, t1)
        
    # plt.figure(figsize=(10,10))
    # plt.axis('off')
    # plt.imshow(t1,cmap='gray')
    # plt.show(block=False)
    # plt.pause(5)
    # plt.close()
    # plt.figure(figsize=(10,10))
    # plt.axis('off')
    # plt.imshow(t2,cmap='gray')
    # plt.show(block=False)
    # plt.pause(5)
    # plt.close()

    df = pd.DataFrame(x, columns=['TARGET', 'MOVING', 'PCC_BEFORE', 'PCC_AFTER', 'SSIM_BEFORE', 'SSIM_AFTER',
                                  'loss_BEFORE', 'loss_AFTER', 'MI_BEFORE', 'MI_AFTER', 'MEAN_BEFORE', 'MEAN_AFTER','AVERAGE_INTENSITY_BEFORE', 'AVERAGE_INTENSITY_AFTER', 'TIME'])
    #df[columns]= ['PCC_BEFORE','PCC_AFTER','SSIM_BEFORE' ,'SSIM_AFTER','loss_BEFORE','loss_AFTER','MI_BEFORE','MI_AFTER','MEAN_BEFORE','MEAN_AFTER']
    #writer = pd.ExcelWriter(out_stats)
    df.to_csv(out_stats, index=None, header=True)
    # writer.save()
    #print(t.draw())

    return t
Beispiel #12
0
    def as_array(self,
                 interval_r=AsymmetricPercentileInterval(2.5, 99.0),
                 interval_g=AsymmetricPercentileInterval(5., 99.2),
                 interval_b=AsymmetricPercentileInterval(10., 99.2)):
        """Returns the colour image as a MxNx3 (RGB) array."""
        # First we determine the shifts
        cx, cy = 2050, 1024  # central coordinates of the image
        maxshiftx, maxshifty = 0, 0
        aligned_imgs = {}
        for idx, band in enumerate(self.filenames.keys()):
            fn = self.filenames[band]
            hdu = fits.open(os.path.join(VPHAS_DATA_PATH, fn))[self.ccd]
            wcs = WCS(hdu.header)
            img = hdu.data
            if idx == 0:  # The first image acts as reference
                cra, cdec = wcs.wcs_pix2world(cx, cy, 1)
            else:  # For all subsequent images, compute the shift using the WCS
                refx, refy = wcs.wcs_world2pix(cra, cdec, 1)
                shiftx = int(refx - cx)
                shifty = int(refy - cy)
                # Now apply the required shift to the image
                if shiftx > 0:
                    img = np.pad(img, ((0, 0), (0, shiftx)),
                                 mode=str('constant'))[:, shiftx:]
                elif shiftx < 0:
                    img = np.pad(img, ((0, 0), (-shiftx, 0)),
                                 mode=str('constant'))[:, :shiftx]
                if shifty > 0:
                    img = np.pad(img, ((0, shifty), (0, 0)),
                                 mode=str('constant'))[shifty:, :]
                elif shifty < 0:
                    img = np.pad(img, ((-shifty, 0), (0, 0)),
                                 mode=str('constant'))[:shifty, :]
                # The maximum shift applied will determine the final img shape
                maxshiftx = max(abs(shiftx), maxshiftx)
                maxshifty = max(abs(shifty), maxshifty)
            aligned_imgs[band] = img

        if maxshiftx > cx or maxshifty > cy:
            raise VphasDataException('{0}-{1}: bands do not overlap'.format(
                self.offset, self.ccd))
        # New stretch, scale, and stack the data into an MxNx3 array
        r = aligned_imgs['i'] + aligned_imgs['ha']
        g = aligned_imgs['g'] + aligned_imgs['r'] + aligned_imgs['r2']
        b = aligned_imgs['u'] + 2 * aligned_imgs['g']
        r, g, b = 1.5 * r, 0.8 * g, 2.2 * b
        vmin_r, vmax_r = np.percentile(r, [1., 99.5])
        vmin_g, vmax_g = np.percentile(g, [5., 99.5])
        vmin_b, vmax_b = np.percentile(b, [10., 99.5])
        #log.info((vmin_r, vmin_g, vmin_b))
        #log.info((vmax_r, vmax_g, vmax_b))
        #if vmin_b < 100:
        #    vmin_b = 100
        minrange = np.max(
            (1250., vmax_g - vmin_g, vmax_g - vmin_g, vmax_b - vmin_b))
        if (vmax_r - vmin_r) < minrange:
            vmax_r = vmin_r + minrange
        if (vmax_g - vmin_g) < minrange:
            vmax_g = vmin_g + minrange
        if (vmax_b - vmin_b) < minrange:
            vmax_b = vmin_b + minrange
        interval_r = ManualInterval(vmin_r, vmax_r)
        interval_g = ManualInterval(vmin_g, vmax_g)
        interval_b = ManualInterval(vmin_b, vmax_b)

        r = interval_r(r)
        g = interval_g(g)
        b = interval_b(b)
        stacked = np.dstack((r[maxshifty:-maxshifty, maxshiftx:-maxshiftx],
                             g[maxshifty:-maxshifty,
                               maxshiftx:-maxshiftx], b[maxshifty:-maxshifty,
                                                        maxshiftx:-maxshiftx]))
        return LuptonColorStretch()(stacked)
Beispiel #13
0
def data_to_pitch(data_array,
                  pitch_range=[100, 10000],
                  center_pitch=440,
                  zero_point="median",
                  stretch='linear',
                  minmax_percent=None,
                  minmax_value=None):
    """
    Map data array to audible pitches in the given range, and apply stretch and scaling
    as required.

    Parameters
    ----------
    data_array : array-like
        Data to map to pitch values. Individual data values should be floats.
    pitch_range : array
        Optional, default [100,10000]. Range of acceptable pitches in Hz. 
    center_pitch : float
        Optional, default 440. The pitch in Hz where that the the zero point of the 
        data will be mapped to.
    zero_point : str or float
        Optional, default "median". The data value that will be mapped to the center
        pitch. Options are mean, median, or a specifical data value (float).
    stretch : str
        Optional, default 'linear'. The stretch to apply to the data array.
        Valid values are: asinh, sinh, sqrt, log, linear
    minmax_percent : array
        Optional. Interval based on a keeping a specified fraction of data values (can be asymmetric) 
        when scaling the data. The format is [lower percentile, upper percentile], where data
        values below the lower percentile and above the upper percentile are clipped.
        Only one of minmax_percent and minmax_value should be specified.
    minmax_value : array
        Optional. Interval based on user-specified data values when scaling the data array.
        The format is [min value, max value], where data values below the min value and above
        the max value are clipped.
        Only one of minmax_percent and minmax_value should be specified.

    Returns
    -------
    response : array
        The normalized data array, with values in given pitch range.
    """

    # Parsing the zero point
    if zero_point in ("med", "median"):
        zero_point = np.median(data_array)
    if zero_point in ("ave", "mean", "average"):
        zero_point = np.mean(data_array)

    # Normalizing the data_array and adding the zero point (so it can go through the same transform)
    data_array = np.append(np.array(data_array), zero_point)

    # Setting up the transform with the stretch
    if stretch == 'asinh':
        transform = AsinhStretch()
    elif stretch == 'sinh':
        transform = SinhStretch()
    elif stretch == 'sqrt':
        transform = SqrtStretch()
    elif stretch == 'log':
        transform = LogStretch()
    elif stretch == 'linear':
        transform = LinearStretch()
    else:
        raise InvalidInputError("Stretch {} is not supported!".format(stretch))

    # Adding the scaling to the transform
    if minmax_percent is not None:
        transform += AsymmetricPercentileInterval(*minmax_percent)

        if minmax_value is not None:
            warnings.warn(
                "Both minmax_percent and minmax_value are set, minmax_value will be ignored.",
                InputWarning)
    elif minmax_value is not None:
        transform += ManualInterval(*minmax_value)
    else:  # Default, scale the entire image range to [0,1]
        transform += MinMaxInterval()

    # Performing the transform and then putting it into the pich range
    pitch_array = transform(data_array)

    zero_point = pitch_array[-1]
    pitch_array = pitch_array[:-1]

    pitch_array = np.multiply((center_pitch - pitch_range[0]) / zero_point,
                              pitch_array,
                              out=pitch_array) + pitch_range[0]

    return pitch_array