In [1]:
import AngularCatalog_class as ac
import ImageMask_class as imclass
from astropy.io import fits
from astropy.io import ascii
import numpy as np
import numpy.random as rand
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = (10, 6)
ImageMask
There are three main ways to create an ImageMask
in Py2PAC, all classmethod
s of ImageMask
:
from_ranges
: Creates a rectangular image mask over a range in RA and Dec with equal completeness in all parts of the image. Bug to be fixed: doesn't allow for negative RAsfrom_array
: This doesn't work the way it should at the moment because WCS is wonky. This creates a rectangular image mask with the completeness in each cell defined by the value of an input array. I show here how it currently malfunctions. Eventually, this should be fixed.from_FITS_weight_file
: Reads in a weight map in FITS format and converts it to completeness=1 at points with weight above the 5th percentile and completeness=0 below.We'll make the simplest mask first. The arguments to from_ranges
are two arrays, the RA range first, then the Dec range, both in degrees.
In [2]:
mask_from_ranges = imclass.ImageMask.from_ranges([0, 1], [0, 0.5])
To see what the mask looks like, we generate some random points and plot them.
In [3]:
#Generate the randoms
ra, dec, completeness = mask_from_ranges.generate_random_sample(1e4)
#Plot
fig=plt.figure()
ax=fig.add_subplot(111)
ax.set_xlabel("RA (deg)")
ax.set_ylabel("Dec (deg)")
ax.scatter(ra, dec)
Out[3]:
Simple enough. Note that if you manually change the completenesses in the ImageMask._mask, it will behave like from_array
, which is to say "not the way you expect" (this is on the list of things to be fixed). See the next section.
WARNING: This method does not work the way it should. I have included it solely to show how the function is broken.
The concept for this method is to make it so that an arbitrary array with elements that range from 0 to 1 can be used as an image mask. However, at the present time, dividing the area into even bins doesn't work for reasons unbeknownst to me. We'll make a mask from the identity matrix to illustrate the strangeness, but then show how uneven completeness works.
In [4]:
#Make the mask array
mask_array = np.identity(4)
print mask_array
#Make the ImageMask
mask_from_array = imclass.ImageMask.from_array(mask_array, [0,1], [0,1])
In [5]:
%%capture
## ^ Use to suppress lengthy output
#Generate randoms
ra, dec, completeness = mask_from_array.generate_random_sample(1e4)
In [6]:
#Plot the randoms
fig=plt.figure()
ax=fig.add_subplot(111)
ax.set_xlabel("RA (deg)")
ax.set_ylabel("Dec (deg)")
ax.scatter(ra, dec)
Out[6]:
The main thing to note here is that the binning isn't even. The mask also has a different orientation from the orientation of the array. The origin is in the lower left, at the minimum RA and Dec. To see this, we'll use a slightly different array to mask.
In [7]:
#Make the new array mask
mask_array2 = np.identity(4)
mask_array2[0,0] = 0.2
mask_array2[0, 3] = 0.2
print mask_array2
#Make the new mask
mask_from_array2 = imclass.ImageMask.from_array(mask_array2, [0,1], [0,1])
In [8]:
%%capture
## ^ Use to suppress lengthy output
#Generate randoms
ra2, dec2, completeness = mask_from_array2.generate_random_sample(1e4)
In [9]:
#Plot the randoms
fig=plt.figure()
ax=fig.add_subplot(111)
ax.set_xlabel("RA (deg)")
ax.set_ylabel("Dec (deg)")
ax.scatter(ra2, dec2)
Out[9]:
This clearly shows that the origin is in the lower left and also illustrates how variable completeness would be implemented in this version of Py2PAC. Again, this should be fixed so the bins are square (or at least rectangular) in future versions.
This function was written with the weight files from the CANDELS mosaics in mind. In principle, it should work with any FITS image with lower values denoting lower exposure times. The routine reads in the FITS file and finds the 5th percentile of the nonzero weight values from a random sample of 1e6 values on the image (to make computation time manageable). Then, a mask is created that has completeness 1 above the 5th percentile and 0 below.
This example uses a CANDELS tile weight file. The file is too large to be included in the repository, so the file "hlsp_candels_hst_wfc3_gs-tot-sect33_f160w_v1.0_wht.fits" (found here) must be downloaded and placed in the examples folder.
In [10]:
#Make the mask
weight_file = 'hlsp_candels_hst_wfc3_gs-tot-sect33_f160w_v1.0_wht.fits'
mask_from_fits = imclass.ImageMask.from_FITS_weight_file(weight_file)
In [11]:
%%capture
## ^ Use to suppress lengthy output
#Generate randoms
ra, dec, completeness = mask_from_fits.generate_random_sample(1e5)
In [12]:
#Plot the randoms
fig=plt.figure()
fig.set_size_inches(7,7)
ax=fig.add_subplot(111)
ax.set_xlabel("RA (deg)")
ax.set_ylabel("Dec (deg)")
ax.scatter(ra, dec)
Out[12]:
AngularCatalog
An AngularCatalog
can be created either with externally generated RAs and Decs or with randomly generated RAs and Decs. They can have an ImageMask
of any kind. We'll start with pre-existing RAs and Decs (we'll make some up) and then move on to the random_catalog
class method.
In [13]:
#Make the RAs and Decs
ras = rand.normal(loc=0.5, scale=0.2, size=int(1e3))
decs = rand.normal(loc=0, scale=0.2, size=int(1e3))
plt.scatter(ras, decs)
Out[13]:
Now we need to make this into an AngularCatalog
with some image mask. The options are to pass an already existing ImageMask
instance or to give the constructor the location of a weight file from which to construct the mask.
ImageMask
For this demonstration, we'll make a rectangular mask and pass it explicitly.
In [14]:
#Make the mask that we'll be using
immask = imclass.ImageMask.from_ranges([0.1, .9], [-0.4, 0.4])
#Make the catalog
cat = ac.AngularCatalog(ras, decs, image_mask=immask)
#Generate some randoms to showthe mask area
cat.generate_random_sample(number_to_make=2e4)
#Plot both the randoms and all the data (not just what's within the mask)
cat.scatterplot_points(sample="both", masked_data=False)
cat.scatterplot_points(sample="both", masked_data=True)
The first plot shows all the data and the second shows just the data within the mask area (just to confirm that the mask is working).
ImageMask
from FITS at the same time you create the AngularCatalog
You can also generate AngularCatalog
s with ImageMask
from FITS files with just the constructor. For this, we need coordinates that are in the right place, so we'll just use the CANDELS galaxies.
In [19]:
#Create an AngularCatalog with an ImageMask from a weight file
weight_file = 'hlsp_candels_hst_wfc3_gs-tot-sect33_f160w_v1.0_wht.fits'
data_file = "example_data.dat"
data = ascii.read(data_file)
#Only use the first 1000 points (it's random points, so it doesn't matter which 1000) to make
#an AngularCatalog (so we can see the randoms too on the plot)
cat_wt = ac.AngularCatalog(data['ra'][0:1000], data['dec'][0:1000], weight_file = weight_file)
In [20]:
cat_wt.generate_random_sample(number_to_make=1e4)
cat_wt.scatterplot_points(sample="both", masked_data=True)
In [21]:
#Make the AngularCatalog with an existing image mask
immask = imclass.ImageMask.from_ranges([0.1, .9], [-0.4, 0.4])
rand_cat_1 = ac.AngularCatalog.random_catalog(1e3, image_mask = immask)
rand_cat_1.scatterplot_points(sample="data")
#Make the AngularCatalog over a rectangular area
rand_cat_1 = ac.AngularCatalog.random_catalog(1e3, ra_range=[0, 0.5], dec_range=[0, 0.5])
rand_cat_1.scatterplot_points(sample="data")