示例#1
0
def test_plot_image():

	mu = [3.5, 3]
	x, y = np.mgrid[0:15, 0:15]
	pos = np.dstack((x, y))
	var = multivariate_normal(mean=mu, cov=[[1,0],[0,1]])
	gauss = 5 * var.pdf(pos) - 0.05 # Make sure it has some negative values as well
	gauss[8,8] = np.NaN
	gauss[4,4] = -0.2

	scales = ['linear', 'sqrt', 'log', 'asinh', 'histeq', 'sinh', 'squared']

	fig, axes = plt.subplots(2, 4, figsize=(14, 8))
	axes = axes.flatten()
	for k, scale in enumerate(scales):
		ax = axes[k]
		plot_image(gauss, ax=ax, scale=scale, title=scale, cbar='right')
		ax.plot(mu[1], mu[0], 'r+')

	# In the final plot:
	plot_image(gauss, ax=axes[-1], scale='log', title='log - Reds', cmap='Reds', cbar='right')

	fig.tight_layout()

	return fig
示例#2
0
def test_plot_cbar_and_nans():

	# Construct image:
	np.random.seed(42)
	img = np.random.rand(10, 10)
	img[2:8, 2:8] = np.NaN

	fig, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4, figsize=(16, 6))
	plot_image(img, ax=ax1, scale='linear', vmin=0.4, cbar='left')
	plot_image(img, ax=ax2, scale='sqrt', vmin=0.4, cbar='bottom')
	plot_image(img, ax=ax3, scale='log', vmin=0.4, cbar='right')
	plot_image(img, ax=ax4, scale='asinh', vmin=0.4, cbar='top')
	return fig
示例#3
0
def test_plot_image_invalid():

	mu = [3.5, 3]
	x, y = np.mgrid[0:10, 0:10]
	pos = np.dstack((x, y))
	var = multivariate_normal(mean=mu, cov=[[1,0],[0,1]])
	gauss = var.pdf(pos)

	fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))

	# Run with invalid scale:
	with pytest.raises(ValueError):
		plot_image(gauss, ax=ax1, scale='invalid-scale')

	# Plot with single NaN:
	gauss[1,1] = np.NaN
	plot_image(gauss, ax=ax1, scale='log')

	# Run with all-NaN image:
	gauss[:, :] = np.NaN
	plot_image(gauss, ax=ax2, cbar='right')
	return fig
示例#4
0
def make_movie(hdf_file, fps=15, dpi=100, overwrite=False):
    """
	Create animation of the contents of a HDF5 files produced by the photometry pipeline.

	The function will create a MP4 movie file with the same name as the input file,
	placed in the same directory, containing the animation.

	Parameters:
		hdf_file (string): Path to the HDF5 file to produce movie from.
		fps (integer): Frames per second of generated movie. Default=15.
		dpi (integer): DPI of the movie. Default=100.
		overwrite (boolean): Overwrite existing MP4 files? Default=False.

	.. codeauthor:: Rasmus Handberg <*****@*****.**>
	"""

    logger = logging.getLogger(__name__)
    tqdm_settings = {'disable': not logger.isEnabledFor(logging.INFO)}
    logger.info("Processing '%s'", hdf_file)

    # File to be created:
    output_file = os.path.splitext(hdf_file)[0] + '.mp4'
    if os.path.exists(output_file):
        if overwrite:
            logger.debug("Deleting existing output file")
            os.remove(output_file)
        else:
            logger.info("Movie file already exists")
            return output_file

    # Open HDF5 file:
    # We need to have write-privaledges because we are going to updated some attributes
    save_image_scales = False
    with h5py.File(hdf_file, 'r') as hdf:
        # Load the image scales if they have already been calculated:
        vmin = hdf['backgrounds'].attrs.get('movie_vmin')
        vmax = hdf['backgrounds'].attrs.get('movie_vmax')
        vmin2 = hdf['images'].attrs.get('movie_vmin')
        vmax2 = hdf['images'].attrs.get('movie_vmax')

        # Calculate scales to use for plotting the images:
        if not vmin:
            logger.info("Calculating image scales...")
            numfiles = len(hdf['images'])
            vmax = np.empty(numfiles)
            vmin = np.empty(numfiles)
            vmax2 = np.empty(numfiles)
            vmin2 = np.empty(numfiles)
            for k in trange(numfiles, **tqdm_settings):
                vmin[k], vmax[k] = np.nanpercentile(
                    hdf['backgrounds/%04d' % k], [1.0, 99.0])
                vmin2[k], vmax2[k] = np.nanpercentile(hdf['images/%04d' % k],
                                                      [1.0, 99.0])

            vmin = np.nanpercentile(vmin, 25.0)
            vmax = np.nanpercentile(vmax, 75.0)
            vmin2 = np.nanpercentile(vmin2, 25.0)
            vmax2 = np.nanpercentile(vmax2, 75.0)
            save_image_scales = True

    # If needed, reopen the file for saving the attributes:
    if save_image_scales:
        with h5py.File(hdf_file, 'r+') as hdf:
            # Save image scales to HDF5 file:
            hdf['backgrounds'].attrs['movie_vmin'] = vmin
            hdf['backgrounds'].attrs['movie_vmax'] = vmax
            hdf['images'].attrs['movie_vmin'] = vmin2
            hdf['images'].attrs['movie_vmax'] = vmax2
            hdf.flush()

    # We should now be ready for creating the movie, reopen the file as readonly:
    logger.info("Creating movie...")
    with h5py.File(hdf_file, 'r') as hdf:
        numfiles = len(hdf['images'])
        dummy_img = np.full_like(hdf['images/0000'], np.NaN)
        time = np.asarray(hdf['time'])
        cadenceno = np.asarray(hdf['cadenceno'])
        sector = hdf['images'].attrs.get('SECTOR')
        camera = hdf['images'].attrs.get('CAMERA')
        ccd = hdf['images'].attrs.get('CCD')

        with plt.style.context('dark_background'):
            plt.rc('axes', titlesize=15)

            fig, ax = plt.subplots(1, 4, figsize=(20, 6.8), dpi=dpi)

            # Colormap to use for FFIs:
            cmap = plt.get_cmap('viridis')
            cmap.set_bad('k', 1.0)

            # Colormap for Flags:
            viridis = plt.get_cmap('Dark2')
            newcolors = viridis(np.linspace(0, 1, 4))
            newcolors[:1, :] = np.array([1, 1, 1, 1])
            cmap_flags = ListedColormap(newcolors)

            imgs = [None] * 4
            imgs[0] = plot_image(dummy_img,
                                 ax=ax[0],
                                 scale='sqrt',
                                 vmin=vmin,
                                 vmax=vmax,
                                 title='Original Image',
                                 cmap=cmap,
                                 cbar='bottom',
                                 cbar_pad=0.05)
            imgs[1] = plot_image(dummy_img,
                                 ax=ax[1],
                                 scale='sqrt',
                                 vmin=vmin,
                                 vmax=vmax,
                                 title='Background',
                                 cmap=cmap,
                                 cbar='bottom',
                                 cbar_pad=0.05)
            imgs[2] = plot_image(dummy_img,
                                 ax=ax[2],
                                 scale='sqrt',
                                 vmin=vmin2,
                                 vmax=vmax2,
                                 title='Background subtracted',
                                 cmap=cmap,
                                 cbar='bottom',
                                 cbar_pad=0.05)
            imgs[3] = plot_image(
                dummy_img,
                ax=ax[3],
                scale='linear',
                vmin=-0.5,
                vmax=3.5,
                title='Pixel Flags',
                cmap=cmap_flags,
                cbar='bottom',
                cbar_pad=0.05,
                clabel='Flags',
                cbar_ticks=[0, 1, 2, 3],
                cbar_ticklabels=['None', 'Not used', 'Man Excl', 'Shenan'])

            for a in ax:
                a.set_xticks([])
                a.set_yticks([])

            figtext = fig.suptitle("to come\nt=???????", fontsize=16)
            fig.subplots_adjust(left=0.03,
                                right=0.97,
                                top=0.95,
                                bottom=0.03,
                                wspace=0.05)
            set_copyright(fig)

            metadata = {
                'title':
                'TESS Sector {sector:d}, Camera {camera:d}, CCD {ccd:d}'.
                format(sector=sector, camera=camera, ccd=ccd),
                'artist':
                'TASOC'
            }

            # Set up the writer (FFMpeg)
            WriterClass = animation.writers['ffmpeg']
            writer = WriterClass(fps=fps,
                                 codec='h264',
                                 bitrate=-1,
                                 metadata=metadata)
            with writer.saving(fig, output_file, dpi):
                for k in trange(numfiles, **tqdm_settings):
                    dset_name = '%04d' % k
                    flux0 = np.asarray(hdf['images/' + dset_name])
                    bkg = np.asarray(hdf['backgrounds/' + dset_name])

                    # Plot original image, background and new image:
                    imgs[0].set_data(flux0 + bkg)
                    imgs[1].set_data(bkg)
                    imgs[2].set_data(flux0)

                    # Background Shenanigans flags, if available:
                    if 'pixel_flags/' + dset_name in hdf:
                        img = np.asarray(hdf['pixel_flags/' + dset_name])

                        flags = np.zeros_like(img, dtype='uint8')
                        flags[img & PixelQualityFlags.NotUsedForBackground !=
                              0] = 1
                        flags[img & PixelQualityFlags.ManualExclude != 0] = 2
                        flags[img & PixelQualityFlags.BackgroundShenanigans !=
                              0] = 3

                        imgs[3].set_data(flags)

                    # Update figure title with cadence information;
                    figtext.set_text(
                        "Sector {sector:d}, Camera {camera:d}, CCD {ccd:d}\ndset={dset:s}, cad={cad:d}, t={time:.6f}"
                        .format(sector=sector,
                                camera=camera,
                                ccd=ccd,
                                dset=dset_name,
                                cad=cadenceno[k],
                                time=time[k]))

                    writer.grab_frame()

            plt.close(fig)

    return output_file
示例#5
0
def make_combined_movie(input_dir,
                        mode='images',
                        fps=15,
                        dpi=100,
                        overwrite=False):
    """
	Create animation of the combined contents of all HDF5 files in a directory,
	produced by the photometry pipeline.

	Parameters:
		input_dir (string): Path to the directory with HDF5 files to produce movie from.
		mode (string): Which images to show.
			Choices are `'originals'`, `'images'`, `'backgrounds'` or `'flags'`.
			Default=images.
		fps (integer): Frames per second of generated movie. Default=15.
		dpi (integer): DPI of the movie. Default=100.
		overwrite (boolean): Overwrite existing MP4 files? Default=False.

	.. codeauthor:: Rasmus Handberg <*****@*****.**>
	"""

    # Basic input checks:
    if mode not in ('originals', 'images', 'backgrounds', 'flags'):
        raise ValueError("Invalid MODE specified")

    logger = logging.getLogger(__name__)
    tqdm_settings = {'disable': not logger.isEnabledFor(logging.INFO)}
    logger.info("Processing '%s'", input_dir)

    camccdrot = [(1, 3, 1), (1, 2, 3), (2, 3, 1), (2, 2, 3), (3, 1, 1),
                 (3, 4, 3), (4, 1, 1), (4, 4, 3), (1, 4, 1), (1, 1, 3),
                 (2, 4, 1), (2, 1, 3), (3, 2, 1), (3, 3, 3), (4, 2, 1),
                 (4, 3, 3)]

    # Find the sectors that are available:
    sectors = []
    for fname in find_hdf5_files(input_dir):
        # Load the sector number from HDF5 file attributes:
        with h5py.File(fname, 'r') as hdf:
            s = hdf['images'].attrs.get('SECTOR')

        if s is not None and int(s) not in sectors:
            sectors.append(int(s))
        else:
            # If the attribute doesn't exist try to find it from
            # parsing the file name:
            m = re.match(r'^sector(\d+)_camera\d_ccd\d\.hdf5$',
                         os.path.basename(fname))
            if int(m.group(1)) not in sectors:
                sectors.append(int(m.group(1)))

    # Create one movie per found sector:
    for sector in sectors:
        # Define the output file, and overwrite it if needed:
        output_file = os.path.join(
            input_dir,
            'sector{sector:03d}_combined_{mode:s}.mp4'.format(sector=sector,
                                                              mode=mode))
        if os.path.exists(output_file):
            if overwrite:
                logger.debug("Deleting existing output file")
                os.remove(output_file)
            else:
                logger.info("Movie file already exists")
                return output_file

        try:
            hdf = [None] * 16
            vmin = np.full(16, np.NaN)
            vmax = np.full(16, np.NaN)
            for k, (camera, ccd, rot) in enumerate(camccdrot):
                hdf_file = find_hdf5_files(input_dir,
                                           sector=sector,
                                           camera=camera,
                                           ccd=ccd)
                if hdf_file:
                    hdf[k] = h5py.File(hdf_file[0], 'r')

                    numfiles = len(hdf[k]['images'])
                    dummy_img = np.full_like(hdf[k]['images/0000'], np.NaN)
                    time = np.asarray(hdf[k]['time'])
                    cadenceno = np.asarray(hdf[k]['cadenceno'])

                    # Load the image scales if they have already been calculated:
                    if mode == 'backgrounds':
                        vmin[k] = hdf[k]['backgrounds'].attrs.get(
                            'movie_vmin', 0)
                        vmax[k] = hdf[k]['backgrounds'].attrs.get(
                            'movie_vmax', 500)
                    elif mode == 'images' or mode == 'originals':
                        vmin[k] = hdf[k]['images'].attrs.get('movie_vmin', 0)
                        vmax[k] = hdf[k]['images'].attrs.get('movie_vmax', 500)

            # Summarize the different CCDs into common values:
            vmin = np.nanpercentile(vmin, 25.0)
            vmax = np.nanpercentile(vmax, 75.0)

            logger.info("Creating combined %s movie...", mode)
            with plt.style.context('dark_background'):
                fig, axes = plt.subplots(2, 8, figsize=(25, 6.8), dpi=dpi)

                cmap = plt.get_cmap('viridis')
                cmap.set_bad('k', 1.0)

                # Colormap for Flags:
                viridis = plt.get_cmap('Dark2')
                newcolors = viridis(np.linspace(0, 1, 4))
                newcolors[:1, :] = np.array([1, 1, 1, 1])
                cmap_flags = ListedColormap(newcolors)

                imgs = [None] * 16
                for k, ax in enumerate(axes.flatten()):
                    if mode == 'flags':
                        imgs[k] = plot_image(dummy_img,
                                             ax=ax,
                                             scale='linear',
                                             vmin=-0.5,
                                             vmax=4.5,
                                             cmap=cmap_flags)
                    else:
                        imgs[k] = plot_image(dummy_img,
                                             ax=ax,
                                             scale='sqrt',
                                             vmin=vmin,
                                             vmax=vmax,
                                             cmap=cmap)
                    ax.set_xticks([])
                    ax.set_yticks([])

                figtext = fig.suptitle("to come\nt=???????", fontsize=16)
                fig.subplots_adjust(left=0.03,
                                    right=0.97,
                                    top=0.90,
                                    bottom=0.05,
                                    wspace=0.05,
                                    hspace=0.05)
                set_copyright(fig)

                metadata = {
                    'title':
                    'TESS Sector {sector:d}, {mode:s}'.format(sector=sector,
                                                              mode=mode),
                    'artist':
                    'TASOC'
                }

                # Set up the writer (FFMpeg)
                WriterClass = animation.writers['ffmpeg']
                writer = WriterClass(fps=fps,
                                     codec='h264',
                                     bitrate=-1,
                                     metadata=metadata)
                with writer.saving(fig, output_file, dpi):
                    for i in trange(numfiles, **tqdm_settings):
                        dset_name = '%04d' % i

                        for k in range(16):
                            if hdf[k] is None:
                                continue

                            # Background Shenanigans flags, if available:
                            if mode == 'flags':
                                flags = np.asarray(hdf[k]['pixel_flags/' +
                                                          dset_name])
                                img = np.zeros_like(flags, dtype='uint8')
                                img[flags
                                    & PixelQualityFlags.NotUsedForBackground !=
                                    0] = 1
                                img[flags
                                    & PixelQualityFlags.ManualExclude != 0] = 2
                                img[flags
                                    & PixelQualityFlags.BackgroundShenanigans
                                    != 0] = 3
                            elif mode == 'originals':
                                img = np.asarray(hdf[k]['images/' + dset_name])
                                img += np.asarray(hdf[k]['backgrounds/' +
                                                         dset_name])
                            else:
                                img = np.asarray(hdf[k][mode + '/' +
                                                        dset_name])

                            # Rotate the image:
                            cam, ccd, rot = camccdrot[k]
                            img = np.rot90(img, rot)

                            # Update the image:
                            imgs[k].set_data(img)

                        # Update figure title with cadence information:
                        figtext.set_text(
                            "Sector {sector:d} - {mode:s}\ndset={dset:s}, cad={cad:d}, t={time:.6f}"
                            .format(sector=sector,
                                    mode=mode,
                                    dset=dset_name,
                                    cad=cadenceno[i],
                                    time=time[i]))

                        writer.grab_frame()

                plt.close(fig)

        except:  # noqa: E722
            raise

        finally:
            for k in range(16):
                if hdf[k] is not None:
                    hdf[k].close()

    return output_file
示例#6
0
        #flags = np.asarray(hdf['pixel_flags/' + dset_name])
        flags = np.zeros_like(flux0, dtype='int32')
        flags[512:1024, 512:1024] = 128

    flags = np.where(flags == 0, 0, np.log2(flags) + 1)

    #flags = (flags & PixelQualityFlags.BackgroundShenanigans != 0)

    white = np.array([1, 1, 1, 1])

    viridis = plt.get_cmap('viridis')
    newcolors = viridis(np.linspace(0, 1, int(np.max(flags))))
    newcolors[:1, :] = white
    newcmp = ListedColormap(newcolors)

    fig, ax = plt.subplots(1, 4, figsize=(20, 6))

    plot_image(flux0 + bkg,
               ax=ax[0],
               scale='sqrt',
               vmin=vmin,
               vmax=vmax,
               title='Original Image',
               xlabel=None,
               ylabel=None,
               cmap=plt.cm.viridis,
               make_cbar=True)
    plot_image(bkg,
               ax=ax[1],
               scale='sqrt',
               vmin=vmin,
示例#7
0
def make_combined_movie(input_dir,
                        mode='images',
                        fps=15,
                        dpi=100,
                        overwrite=False):
    """
	Create animation of the combined contents of all HDF5 files in a directory,
	produced by the photometry pipeline.

	Parameters:
		input_dir (string): Path to the directory with HDF5 files to produce movie from.
		mode (string): Which images to show.
			Choices are `'images'`, `'backgrounds'` or `'flags'`.
			Default=images.
		fps (integer): Frames per second of generated movie. Default=15.
		dpi (integer): DPI of the movie. Default=100.
		overwrite (boolean): Overwrite existing MP4 files? Default=False.

	.. codeauthor:: Rasmus Handberg <*****@*****.**>
	"""

    # Basic input checks:
    assert mode in ('images', 'backgrounds', 'flags'), "Invalid MODE specified"

    logger = logging.getLogger(__name__)
    logger.info("Processing '%s'", input_dir)

    camccdrot = [(1, 3, 1), (1, 2, 3), (2, 3, 1), (2, 2, 3), (3, 1, 1),
                 (3, 4, 3), (4, 1, 1), (4, 4, 3), (1, 4, 1), (1, 1, 3),
                 (2, 4, 1), (2, 1, 3), (3, 2, 1), (3, 3, 3), (4, 2, 1),
                 (4, 3, 3)]

    # Find the sectors that are available:
    # TODO: Could we change this so we don't have to parse the filenames?
    sectors = []
    for fname in find_hdf5_files(input_dir):
        m = re.match(r'^sector(\d+)_camera\d_ccd\d\.hdf5$',
                     os.path.basename(fname))
        if int(m.group(1)) not in sectors:
            sectors.append(int(m.group(1)))

    # Create one movie per found sector:
    for sector in sectors:
        # Define the output file, and overwrite it if needed:
        output_file = os.path.join(
            input_dir,
            'sector{sector:03d}_combined_{mode:s}.mp4'.format(sector=sector,
                                                              mode=mode))
        if os.path.exists(output_file):
            if overwrite:
                logger.debug("Deleting existing output file")
                os.remove(output_file)
            else:
                logger.info("Movie file already exists")
                return output_file

        try:
            hdf = [None] * 16
            vmin = np.full(16, np.NaN)
            vmax = np.full(16, np.NaN)
            for k, (camera, ccd, rot) in enumerate(camccdrot):
                hdf_file = find_hdf5_files(input_dir,
                                           sector=sector,
                                           camera=camera,
                                           ccd=ccd)
                if hdf_file:
                    hdf[k] = h5py.File(hdf_file[0], 'r', libver='latest')

                    numfiles = len(hdf[k]['images'])
                    dummy_img = np.zeros_like(hdf[k]['images/0000'])
                    time = np.asarray(hdf[k]['time'])
                    cadenceno = np.asarray(hdf[k]['cadenceno'])

                    # Load the image scales if they have already been calculated:
                    if mode == 'backgrounds':
                        vmin[k] = hdf[k]['backgrounds'].attrs.get(
                            'movie_vmin', 0)
                        vmax[k] = hdf[k]['backgrounds'].attrs.get(
                            'movie_vmax', 500)
                    elif mode == 'images':
                        vmin[k] = hdf[k]['images'].attrs.get('movie_vmin', 0)
                        vmax[k] = hdf[k]['images'].attrs.get('movie_vmax', 500)

            # Summarize the different CCDs into common values:
            vmin = np.nanpercentile(vmin, 25.0)
            vmax = np.nanpercentile(vmax, 75.0)

            logger.info("Creating movie...")
            with plt.style.context('dark_background'):
                fig, axes = plt.subplots(2, 8, figsize=(25, 7.3))

                cmap = plt.get_cmap('viridis')
                cmap.set_bad('k', 1.0)

                # Colormap for Flags:
                viridis = plt.get_cmap('Dark2')
                newcolors = viridis(np.linspace(0, 1, 4))
                newcolors[:1, :] = np.array([1, 1, 1, 1])
                cmap_flags = ListedColormap(newcolors)

                imgs = [None] * 16
                for k, ax in enumerate(axes.flatten()):
                    if mode == 'flags':
                        imgs[k] = plot_image(dummy_img,
                                             ax=ax,
                                             scale='linear',
                                             vmin=-0.5,
                                             vmax=4.5,
                                             xlabel=None,
                                             ylabel=None,
                                             cmap=cmap_flags,
                                             make_cbar=False)
                    else:
                        imgs[k] = plot_image(dummy_img,
                                             ax=ax,
                                             scale='sqrt',
                                             vmin=vmin,
                                             vmax=vmax,
                                             xlabel=None,
                                             ylabel=None,
                                             cmap=cmap,
                                             make_cbar=False)
                    ax.set_xticks([])
                    ax.set_yticks([])

                figtext = fig.suptitle("to come\nt=???????", fontsize=15)
                fig.set_tight_layout('tight')
                fig.subplots_adjust(top=0.85)
                set_copyright(fig)

                writer = animation.FFMpegWriter(fps=fps)
                with writer.saving(fig, output_file, dpi):
                    for k in trange(numfiles):
                        dset_name = '%04d' % k

                        for k in range(16):
                            if hdf[k] is None: continue

                            # Background Shenanigans flags, if available:
                            if mode == 'flags':
                                flags = np.asarray(hdf[k]['pixel_flags/' +
                                                          dset_name])
                                img = np.zeros_like(flags, dtype='uint8')
                                img[flags
                                    & PixelQualityFlags.NotUsedForBackground !=
                                    0] = 1
                                img[flags
                                    & PixelQualityFlags.ManualExclude != 0] = 2
                                img[flags
                                    & PixelQualityFlags.BackgroundShenanigans
                                    != 0] = 3
                            else:
                                img = np.asarray(hdf[k][mode + '/' +
                                                        dset_name])

                            # Rotate the image:
                            cam, ccd, rot = camccdrot[k]
                            img = np.rot90(img, rot)

                            # Update the image:
                            imgs[k].set_data(img)

                        # Update figure title with cadence information:
                        figtext.set_text(
                            "Sector {sector:d} - {mode:s}\ndset={dset:s}, cad={cad:d}, t={time:.6f}"
                            .format(sector=sector,
                                    mode=mode,
                                    dset=dset_name,
                                    cad=cadenceno[k],
                                    time=time[k]))

                        writer.grab_frame()

                plt.close(fig)

        except:
            raise

        finally:
            for k in range(16):
                if hdf[k] is not None:
                    hdf[k].close()

    return output_file