In this tutorial a more advanced set of examples are presented on SingleImage class, which allows tod do more specific tasks with the instances.
We import the packages, and also a pair of sample images
In [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
In [2]:
from astropy.visualization import LinearStretch, LogStretch, ZScaleInterval, MinMaxInterval, ImageNormalize
In [3]:
import properimage.single_image as si
In [4]:
img_path = './../../../data/aligned_eso085-030-004.fit'
In [5]:
img = si.SingleImage(img_path)
Quickly we get the answer for the number of sources a priori we would use and the estimated size of thw PSF cutout stamp.
If we want to know the different properties assigned to this instance we can enumerate them:
In [6]:
print(img.attached_to)
In [7]:
img.header
Out[7]:
In [8]:
norm = ImageNormalize(img.pixeldata, interval=ZScaleInterval(),
stretch=LinearStretch())
plt.figure(figsize=(9,10))
plt.imshow(img.pixeldata, cmap='Greys_r', norm=norm)
Out[8]:
In [9]:
plt.figure(figsize=(9,10))
plt.imshow(img.mask, cmap='Greys_r')
Out[9]:
In [10]:
plt.figure(figsize=(9,10))
plt.imshow(img.background, cmap='Greys_r')
plt.colorbar(orientation='horizontal')
plt.tight_layout()
As the background is being estimated only if accesed, then it prints the results.
In [11]:
norm = ImageNormalize(img.bkg_sub_img, interval=ZScaleInterval(),
stretch=LinearStretch())
plt.figure(figsize=(9,8))
plt.imshow(img.bkg_sub_img, cmap='Greys_r', norm=norm)
plt.colorbar(orientation='horizontal')
plt.tight_layout()
In [12]:
norm = ImageNormalize(img.bkg_sub_img, interval=ZScaleInterval(),
stretch=LinearStretch())
plt.figure(figsize=(9,8))
plt.imshow(img.interped, cmap='Greys_r', norm=norm)
plt.colorbar(orientation='horizontal')
plt.tight_layout()
In [13]:
print(img.stamp_shape)
In [14]:
print(img.stamps_pos[0:10])
In [15]:
print(img.best_sources[0:10][['x', 'y', 'cflux']])
In [16]:
print(img.n_sources)
In [17]:
print(img.cov_matrix)
In [18]:
a_fields, psf_basis = img.get_variable_psf(inf_loss=0.01)
In [19]:
print(len(psf_basis), len(a_fields))
Check the information loss argument, which states the maximum amount of information lost in the basis expansion. If we change it the basis is updated:
In [20]:
a_fields, psf_basis = img.get_variable_psf(inf_loss=0.10)
print(len(psf_basis), len(a_fields))
Of course the elements of the basis are unchanged, only a subset is returned. So going from small inf_loss to bigger values is the same as choosing less elements in the calculated basis.
Once obtained this basis and coefficient fields we can display them using some of the plot module functionalities:
In [21]:
from properimage.plot import plot_afields, plot_psfbasis
In [22]:
plot_psfbasis(psf_basis=psf_basis, nbook=True)
For the a_fields object we need to give the coordinates where we evaluate this coefficients.
A function is provided, inside img instance object.
In [23]:
x, y = img.get_afield_domain()
In [24]:
plot_afields(a_fields=a_fields, x=x, y=y, nbook=True)
In [25]:
S = img.s_component
In [26]:
norm = ImageNormalize(S, interval=MinMaxInterval(),
stretch=LogStretch())
plt.figure(figsize=(9,8))
plt.imshow(S, cmap='Greys_r', norm=norm)
plt.colorbar(orientation='horizontal')
plt.tight_layout()
We can also attempt to place our PSF measurement on top of the stars of the image. This is done by placing a delta function in each star position, and convolving with the autopsfs obtained, and add them weighted with the a(x,y) fields.
In [30]:
a_fields, psf_basis = img.get_variable_psf(inf_loss=0.05)
In [31]:
plt.figure(figsize=(12, 6))
for i in range(8):
nsrc = np.random.randint(0, img.n_sources)
xc, yc = img.best_sources[nsrc][['y', 'x']]
try:
patch = si.extract_array(img.pixeldata, img.stamp_shape,
[xc, yc], fill_value=img._bkg.globalrms, mode='strict')
except:
nsrc = np.random.randint(0, img.n_sources)
xc, yc = img.best_sources[nsrc][['y', 'x']]
patch = si.extract_array(img.pixeldata, img.stamp_shape,
[xc, yc], fill_value=img._bkg.globalrms, mode='strict')
plt.subplot(2, 4, i+1)
patch = np.log10(patch)
plt.imshow(patch, vmin=np.percentile(patch, q=10), vmax=np.percentile(patch, q=98))
plt.tick_params(labelsize=16)
try:
thepsf = img.get_psf_xy(xc, yc)
except ValueError:
print(xc, yc)
#print(patch.shape, thepsf.shape)
labels = {'sum': np.sum(thepsf)}
plt.title(r'$\sum PSF = {sum:4.3f}$'.format(**labels))
plt.contour(thepsf, levels=[0.0015, 0.003, 0.01, 0.03], cmap='Greys')
plt.tight_layout()
In [ ]: