The main dependencies of PNICER are astropy, numpy, scipy, matplotlib, and scikit-learn. Here we only import the necessary packages to run this notebook.
In [3]:
import sys
from pnicer import ApparentMagnitudes
from pnicer.utils.auxiliary import get_resource_path
%matplotlib inline
The easiest way to initialize PNICER is to simply point it to catalog files in FITS format. The package includes a set of test resources which can be loaded with the get_resource_path method that was imported above. PNICER uses a set of measured intrinsic magnitudes (or colors) in an extinction-free control field to de-redden an extincted science field. In our test case we use the Orion A molecular cloud as science field and another field a few degrees away for our control field.
In [4]:
# ----------------------------------------------------------------------
# Find the test files included in the package
science_path = get_resource_path(package="pnicer.tests_resources", resource="Orion_A_2mass.fits")
control_path = get_resource_path(package="pnicer.tests_resources", resource="CF_2mass.fits")
Of course, you can also specify any valid path in your file system that points to a FITS catalog file. Something like the following will do the job for you.
science_path = "/path/to/science.fits"
control_path = "/path/to/control.fits"
In [5]:
# ----------------------------------------------------------------------
# Define feature names and extinction vector
mag_names = ["Jmag", "Hmag", "Kmag"]
err_names = ["e_Jmag", "e_Hmag", "e_Kmag"]
extvec = [2.5, 1.55, 1.0] # Indebetouw et al. 2015
Data can be initialized as a ApparentMagnitudes instance. Alternativley also a ApparentColors instance can be used if the data are already photometric colors. While for ApparentMagnitudes, the parameter space will be spanned by magnitudes, Colors calculates the probability density in color space.
Now we have everything we need to initialize our data. We do this by loading everyting directly from the FITS files and the 'from_fits' method:
In [6]:
science = ApparentMagnitudes.from_fits(path=science_path, extvec=extvec,
mag_names=mag_names, err_names=err_names,
lon_name="GLON", lat_name="GLAT",
frame="galactic", coo_unit="deg")
In [7]:
control = ApparentMagnitudes.from_fits(path=control_path, extvec=extvec,
mag_names=mag_names, err_names=err_names,
lon_name="GLON", lat_name="GLAT",
frame="galactic", coo_unit="deg")
Now we have two ApparentMagnitudes instances for our science and control field. We can also create a ApparentColors instance directly from a ApparentMagnitudes instance which calculates consecutive colors for the input data:
In [8]:
science_color = science.mag2color()
control_color = control.mag2color()
Before diving into extinction, let us take a look at the data. PNICER includes a set of plotting methods, which help to quickly visualize your data. One, for instance, may first like to look at the density distribution for the feature combinations:
In [9]:
science.plot_combinations_kde()
We can do the same plot in color space with the instances created before:
In [10]:
science.mag2color().plot_combinations_kde()
Also, it is very useful to look at the spatial distribution of sources. With the following plotting method we can display a kernel density map of all input features.
In [11]:
science.plot_sources_kde(bandwidth=15/60)
Now that we had a look at our data, it is time to calculate the extinction. The software package offers both the new PNICER method, as well as a NICER implementation. Running them is very simple:
In [12]:
ext_pnicer = science_color.pnicer(control=control_color)
Or for NICER:
In [13]:
ext_nicer = science.nicer(control=control)
We must note a few things here:
Furthermore, PNICER returns a probabilistic description of the extinction for each source and for the moment needs to be discretized to get useable values.
In [14]:
ext_pnicer_discrete = ext_pnicer.discretize()
ext_pnicer_discrete.extinction
Out[14]:
NICER returns discrete extinction by design
In [15]:
ext_nicer.extinction
Out[15]:
Both calculations return and Extinction instance from which further options are available. We can save the data in a FITS table if we want:
In [16]:
ext_pnicer_discrete.save_fits(path="/tmp/temp.fits")
The Extinction instance we got above can now also be used to calculate and extinction map. For this, various options are available
In [17]:
pnicer_emap = ext_pnicer_discrete.build_map(bandwidth=5 / 60, metric="gaussian", sampling=2, use_fwhm=True)
The methods above returns an ExtinctionMap instance, which again can be used for various subsequent tasks. We can save the data as a FITS image:
In [18]:
pnicer_emap.save_fits(path="/tmp/temp.fits")
Note that this already includes an automaically calculated astrometric projection. We can also display the results with a convenient plotting method:
In [19]:
pnicer_emap.plot_map(figsize=10)
The red background here refers to pixels where not enough sources are available. These are the basics of PNICER/NICER. Happy hunting for extinction! :)