9. Using Dataset objects

Author: Ralf Farkas
Suitable for VIP v1.0.0 onwards.
Last update: 24/03/2022

The Dataset class is VIP’s main entry point to process data. It contains the data cube with the associated parallactic angles and a PSF, but also information about injected companions and the FWHM. A Dataset object has many methods for dataset-related operations (e.g. recentering, subsampling, injecting fake companions) which can be directly applied to them. Dataset supports both 3D (ADI) and 4D (ADI+mSDI) data.

The following tutorial gives an overview of the new object oriented way of using VIP.

Table of Contents

[1]:
from matplotlib import pyplot as plt
import vip_hci as vip
vvip = vip.__version__
print("VIP version: ", vvip)
from packaging import version

if version.parse(vvip) < version.parse("1.0.0"):
    msg = "Please upgrade your version of VIP"
    msg+= "It should be 1.0.0 or above to run this notebook."
    raise ValueError(msg)
VIP version:  1.3.3

9.1. Create a Dataset object

9.1.1. From FITS files

The VIP_extras repository contains a folder with example datasets:

[2]:
!ls ../datasets
MCMC_results
MCMC_results_plc_ch20
MCMC_results_plc_ch29
MCMC_results_plc_ch38
MCMC_results_plc_top8ch
betapic_hci_dataset.npz
naco_betapic.npz
naco_betapic_cube.fits
naco_betapic_cube_cen.fits
naco_betapic_pa.fits
naco_betapic_psf.fits
sinfoni_HD179218_cube.fits
sinfoni_HD179218_lbda.fits
speckle_residuals_results
sphere_ifs_HIP39826_SED_model.fits
sphere_ifs_HIP39826_airmass.fits
sphere_ifs_HIP39826_cube.fits
sphere_ifs_HIP39826_pa.fits
sphere_ifs_HIP39826_psf.fits
sphere_ifs_HIP39826_wl.fits
sphere_ifs_PDS70_cen.fits
sphere_ifs_PDS70_psf.fits
sphere_ifs_PDS70_wl.fits
sphere_ifs_YJ_APLC_CoroTransmission.fits
sphere_v471tau_cube.fits
sphere_v471tau_pa.fits
sphere_v471tau_psf.fits
sphere_v471tau_wl.fits

To create a Dataset object, we can directly pass the paths to the FITS files:

[3]:
betapic = vip.Dataset(cube="../datasets/naco_betapic_cube.fits",
                      angles="../datasets/naco_betapic_pa.fits",
                      psf="../datasets/naco_betapic_psf.fits")
Cube array shape: (61, 101, 101)
Angles array shape: (61,)
PSF array shape: (39, 39)

or, equivalently, use numpy arrays in memory:

[4]:
cube = vip.fits.open_fits("../datasets/naco_betapic_cube.fits")
angles = vip.fits.open_fits("../datasets/naco_betapic_pa.fits")
psf = vip.fits.open_fits("../datasets/naco_betapic_psf.fits")

betapic = vip.Dataset(cube=cube, angles=angles, psf=psf)
Fits HDU-0 data successfully loaded. Data shape: (61, 101, 101)
Fits HDU-0 data successfully loaded. Data shape: (61,)
Fits HDU-0 data successfully loaded. Data shape: (39, 39)
Cube array shape: (61, 101, 101)
Angles array shape: (61,)
PSF array shape: (39, 39)

9.1.2. Storing/loading a Dataset

A Dataset object, with all the information associated to it, can be stored as one single file. That can be especially useful for reproducing results later, or for sharing a dataset as one compact entity. Internally, VIP uses numpy’s compressed npz format for that, so the data in the file could also be opened on machines without VIP installed.

The Dataset can be stored to disk using it’s .save() method, which takes the filename as a parameter:

[5]:
betapic.save("../datasets/betapic_hci_dataset")

The .npz extension is automatically appended:

[6]:
!ls ../datasets
MCMC_results
MCMC_results_plc_ch20
MCMC_results_plc_ch29
MCMC_results_plc_ch38
MCMC_results_plc_top8ch
betapic_hci_dataset.npz
naco_betapic.npz
naco_betapic_cube.fits
naco_betapic_cube_cen.fits
naco_betapic_pa.fits
naco_betapic_psf.fits
sinfoni_HD179218_cube.fits
sinfoni_HD179218_lbda.fits
speckle_residuals_results
sphere_ifs_HIP39826_SED_model.fits
sphere_ifs_HIP39826_airmass.fits
sphere_ifs_HIP39826_cube.fits
sphere_ifs_HIP39826_pa.fits
sphere_ifs_HIP39826_psf.fits
sphere_ifs_HIP39826_wl.fits
sphere_ifs_PDS70_cen.fits
sphere_ifs_PDS70_psf.fits
sphere_ifs_PDS70_wl.fits
sphere_ifs_YJ_APLC_CoroTransmission.fits
sphere_v471tau_cube.fits
sphere_v471tau_pa.fits
sphere_v471tau_psf.fits
sphere_v471tau_wl.fits

The file we just stored can be loaded again using the Dataset.load():

[7]:
betapic_from_file = vip.Dataset.load("../datasets/betapic_hci_dataset")

Now betapic_from_file is exactly the same Dataset object as betapic.

9.2. Operations on a Dataset

The complete list of methods can be found in the VIP documentation. The following should give a short overview.

9.2.1. Displaying

Displaying the data is easy. Note than in Jupyter, you can usually double-click an image to zoom in.

[8]:
%matplotlib inline
betapic.plot()
plt.show
:Dataset   [x,y,time]   (flux)
:Cube_shape     [101, 101, 61]
[8]:
<function matplotlib.pyplot.show(*, block=None)>

9.2.2. Access and change attributes

One can access the underlaying data using attributes:

[9]:
# access the underlying data:
betapic.psf.shape
[9]:
(39, 39)

Attributes can also be set directly:

[10]:
if version.parse(vvip) <= version.parse("1.0.3"):
    from vip_hci.conf import VLT_NACO
else:
    from vip_hci.config import VLT_NACO

betapic.px_scale = VLT_NACO["plsc"]
betapic.px_scale
[10]:
0.02719

9.2.3. Modifying the object using methods

Many of the operations require a normalized psf:

[11]:
betapic.normalize_psf()

Mean FWHM: 4.801
Flux in 1xFWHM aperture: 1.307
Normalized PSF array shape: (39, 39)
The attribute `psfn` contains the normalized PSF
`fwhm` attribute set to
4.801

…which creates a fwhm attribute:

[12]:
betapic.fwhm
[12]:
4.800978626597029

9.2.4. Injecting companions

[13]:
betapic.inject_companions(flux=10000, rad_dists=30, n_branches=2)
Branch 1:
        (X,Y)=(80.00, 50.00) at 0.82 arcsec (30.00 pxs from center)
Branch 2:
        (X,Y)=(20.00, 50.00) at 0.82 arcsec (30.00 pxs from center)
Coordinates of the injections stored in self.injections_yx
[14]:
betapic.injections_yx
[14]:
[(50.0, 80.0), (50.00000000000001, 20.0)]
[15]:
%matplotlib inline
betapic.plot()
:Dataset   [x,y,time]   (flux)
:Cube_shape     [101, 101, 61]