Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
323 changes: 323 additions & 0 deletions Visualization/AFW_Display_Demo.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# **Demo of lsst.afw.display -- displaying images using the LSST DM Astronomical Framework library**\n",
"\n",
"**Owner:** Brant Robertson ([@brantr](https://github.com/LSSTScienceCollaborations/StackClub/issues/new?body=@brantr)) \n",
"**Level:** Introductory \n",
"**Last Verified to Run:** 2018-08-24 \n",
"**Verified Stack Release:** v16.0 \n",
"\n",
"## **Learning Objectives:**\n",
"\n",
"In this tutorial we will \n",
"\n",
"* Show how to access the `lsst.afw.display` routines.\n",
"\n",
"* Use the LSST data Butler to access processed data and inspect it visually.\n",
"\n",
"This tutorial is designed to help users get a brief feel for the `lsst.afw.display` library that enables the visual inspection of data. The [`lsst.afw` library](https://github.com/lsst/afw) provides an \"Astronomical Framework\" (afw) while the `lsst.daf.*` libraries (see, e.g., [daf_base](https://github.com/lsst/daf_base)) provides a Data Access Framework (daf). Both libraries are used in this tutorial, with the `lsst.daf.persistence` library used to access a calibrated exposure (calexp) and the `lsst.afw.display` library used to show the exposure image on the screen.\n",
"\n",
"This tutorial made use of the [`LowSurfaceBrightness.ipynb` StackClub notebook](https://nbviewer.jupyter.org/github/LSSTScienceCollaborations/StackClub/blob/rendered/SourceDetection/LowSurfaceBrightness.nbconvert.ipynb) by [Alex Drlica-Wagner](https://github.com/LSSTScienceCollaborations/StackClub/issues/new?body=@kadrlica)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## **Step 0) Import Common Python Libraries**\n",
"\n",
"The [`matplotlib`](https://matplotlib.org/), [`numpy`](http://www.numpy.org/), and [`astropy`](http://www.astropy.org/) libraries are widely used Python libraries for plotting, scientific computing, and astronomical data analysis. We will use these packages in common ways below, including the `matplotlib.pyplot` plotting sublibrary. We also import the [`warnings` library](https://docs.python.org/2/library/warnings.html) to prevent some routine warning messages from printing to the screen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#allow for matplotlib to create inline plots in our notebook\n",
"%matplotlib inline \n",
"import numpy as np #imports numpy with the alias np\n",
"import matplotlib.pyplot as plt #imports matplotlib.pyplot as plt\n",
"import warnings #imports the warnings library"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's go ahead and import from `astropy` the image stretch limits from the familiar `zscale()` function."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from astropy.visualization import ZScaleInterval #This function allows use to use the `zscale()` rescaling limits function familiar from, e.g., DS9, to adjust the image stretch.\n",
"zscale = ZScaleInterval() #create an alias to the `ZScaleInterval()` function"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And let the kernel know that we're happy not to have some useful warnings printed during this tutorial."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"warnings.simplefilter(\"ignore\", category=FutureWarning) #prevent some helpful but ancillary warning messages from printing during some LSST DM Release calls\n",
"warnings.simplefilter(\"ignore\", category=UserWarning) #prevent some helpful but ancillary warning messages from printing during some LSST DM Release calls"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As a last preparatory task, we set the parameters of `matplotlib.pyplot` to give us a large default size for an image."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.rcParams['figure.figsize'] = (8.0, 8.0) #set a large default size for our images"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## **Step 1) Loading the LSST DM Stack**\n",
"\n",
"To manipulate data, the LSST DM Stack provides a `Butler` that enables generic access routines to DM-generated data. For more information, see [the Data Butler entry in the LSST Software User Guide](https://confluence.lsstcorp.org/display/LSWUG/Data+Butler). In order to access a calibrated exposure from data stored in the format required by the LSST Data Butler, we must load the `lsst.daf.persistence` library to produce a Butler instance from the data."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import lsst.daf.persistence as dafPersist #load lsst.daf.persistence to gain access to a Butler instance"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we need to load the `lsst.afw.display` library to gain access to the image visualization routines we'd like to use."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import lsst.afw.display as afwDisplay #load lsst.afw.display to gain access to image visualization routines."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Step 2) Importing Data to Visualize**\n",
"\n",
"To plot an image to the screen, we must first load some data. In this tutorial, we will use the `Twinkles` simulated images available in the StackClub data repository. These data sit in the data directory `/project/shared/data/Twinkles_subset/output_data_v2` and contain a set of data produced in generating a calibrated exposure by the DM Stack. These data are organized in a structure that enables a DM Stack `Butler` instance to be generated and provide access to a single filter image (in this case `r` band), a specific detector raft (2,2), a specific sensor in the raft (`1,1`) and a specific visit (in this case, 235 -- note only one band is available per visit in this example).\n",
"\n",
"Once we define a string that contains the data directory, we start the `Butler` instance using the `lsst.daf.persistence` library alias `dafPersist` and its `Butler` class. The `Butler` object is initialized with a string containing the data directory we wish to access. Running the cell may take a few moments."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"datadir = \"/project/shared/data/Twinkles_subset/output_data_v2\" #our data directory containing the Twinkles data organized as Butler expects\n",
"butler = dafPersist.Butler(datadir) #create an instance of the Butler, which we call `butler`, with access to our data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With the `Butler` instance now generated using our data directory, we can retrieve the desired calibrated exposure by telling the butler which filter, raft, sensor, and visit we wish to view. To do this, we definie dictionary with the required information."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Grab a calexp of interest\n",
"dataId = {'filter': 'r', 'raft': '2,2', 'sensor': '1,1', 'visit': 235} #Define a dictionary with the filter, raft, sensor, and visit we wish to view\n",
"calexp = butler.get('calexp', **dataId) #retrieve the data using the `butler` instance and its function `get()`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Step 3) Use AFWDisplay to Visualize the Image**\n",
"\n",
"Now, with a `Butler` instance defined and a calibrated exposure retrieved, we can use [`lsst.afw.display`](https://github.com/lsst/afw/tree/master/python/lsst/afw/display) to visualize the data. The next task is to let AFWDisplay know that we want it to enroll `matplotlib` as our default display backend. To do this, we use the `setDefaultBackend()` function. Remember that we made an alias to `lsst.afw.display` called `afwDisplay`, so we'll use that to call `setDefaultBackend()`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"afwDisplay.setDefaultBackend('matplotlib') # Use lsst.afw.display with the matplotlib backend"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We are now set to display the image. To do this, we:\n",
"\n",
"* First create a `matplotlib.pyplot` figure using `plt.figure()` -- this will be familiar to anyone with experience using `matplotlib`.\n",
"* Then create an alias to the `lsst.afw.display.Display` method that will allow us to display the data to the screen. This alias will be called `afw_display`.\n",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that what you are actually doing is using the afw_display variable to persist the lsst.afw.display.interface.Display object that is returned by lsst.afw.display.Display.

"* Before showing the data on the screen, we have to decide how to apply an image stretch given the data. The algorithm we'll use is `asinh` familiar from SDSS images, with a range of values set by `zscale`. To do this, we use the `scale()` function provided by `lsst.afw.display`. See the `scale()` function definition in the [`interface.py` file of the lsst.afw.display library](https://github.com/lsst/afw/blob/master/python/lsst/afw/display/interface.py).\n",
"* Finally, we can display the image. Do do this, we provide the `mtv()` method the `image` member of our calibrated image retrieved by the `butler`. We can then use `plt.show()` to display our figure.\n",
"\n",
"All these tasks are best done within the same notebook cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure() #create a matplotlib.pyplot figure\n",
"afw_display = afwDisplay.Display() #get an alias to the lsst.afw.display.Display() method\n",
"afw_display.scale('asinh', 'zscale') #set the image stretch algorithm and range\n",
"afw_display.mtv(calexp.image) #load the image into the display\n",
"plt.show() #show the corresponding pyplot figure"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Congrats!** We've plotted an image using `lsst.afw.display`!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Step 4) More Information about lsst.afw.display**\n",
"\n",
"To get some more information about `lsst.afw.display`, we can print the method list to see what's available. The next cell will print `lsst.afw.display` methods to the screen."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"method_list = [func for func in dir(afw_display) if callable(getattr(afw_display, func))]\n",
"print(method_list)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you'd like to learn more about any given function, please see the [`lsst.afw.display` source code](https://github.com/lsst/afw/tree/master/python/lsst/afw/display).\n",
"\n",
"You can also read the API documentation about the above functions using the Jupyter notebook `help()` function:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"help(afw_display.scale)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"help(afw_display.mtv)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Further Documentation**\n",
"\n",
"If you'd like some more information on `lsst.afw.display`, please have a look at the following websites:\n",
"\n",
"* [Info on image indexing conventions.](https://github.com/lsst/afw/blob/master/doc/lsst.afw.image/indexing-conventions.rst) \n",
"* [afw.display Doxygen website](http://doxygen.lsst.codes/stack/doxygen/x_masterDoxyDoc/namespacelsst_1_1afw_1_1display.html) \n",
"* [afw.display GitHub website](https://github.com/RobertLuptonTheGood/afw/tree/master/python/lsst/afw/display) \n",
"* [The `pipelines.lsst.io` Getting Started on Image Display website.](https://pipelines.lsst.io/getting-started/display.html)"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "LSST",
"language": "python",
"name": "lsst"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.2"
},
"livereveal": {
"scroll": true,
"start_slideshow_at": "selected"
}
},
"nbformat": 4,
"nbformat_minor": 2
}