|
4 | 4 | "cell_type": "markdown", |
5 | 5 | "metadata": {}, |
6 | 6 | "source": [ |
7 | | - "<img align=\"left\" src = https://project.lsst.org/sites/default/files/Rubin-O-Logo_0.png width=250> \n", |
| 7 | + "<img align=\"left\" src = https://project.lsst.org/sites/default/files/Rubin-O-Logo_0.png width=250 style=\"padding: 10px\"> \n", |
8 | 8 | "<b>Introduction to the LSST data Butler</b> <br>\n", |
9 | 9 | "Last verified to run on <b>TBD</b> with LSST Science Pipelines release <b>TBD</b> <br>\n", |
10 | 10 | "Contact author: Alex Drlica-Wagner <br>\n", |
|
14 | 14 | "Questions welcome at <a href=\"https://community.lsst.org/c/support/dp0\">community.lsst.org/c/support/dp0</a> <br>\n", |
15 | 15 | "Find DP0 documentation and resources at <a href=\"https://dp0-1.lsst.io\">dp0-1.lsst.io</a> <br>\n", |
16 | 16 | "\n", |
17 | | - "<br>\n", |
| 17 | + "<br><br>\n", |
18 | 18 | "This notebook provides an introduction to the use of the data Butler. The Butler is the LSST Science Pipelines interface for managing, reading, and writing datasets. The Butler can be used to explore the contents of the DP0.1 data repository and access the DP0.1 data. The current version of the Butler (referred to as \"Gen-3\") is still under development, and this notebook may be modified in the future.\n", |
19 | 19 | "\n", |
20 | 20 | "<br>\n", |
21 | | - "<br>\n", |
22 | 21 | "The goals of this notebook are to:<br>\n", |
23 | 22 | "1. create an instance of the Butler<br>\n", |
24 | 23 | "2. explore the DP0.1 data repository<br>\n", |
|
292 | 291 | "cell_type": "markdown", |
293 | 292 | "metadata": {}, |
294 | 293 | "source": [ |
295 | | - "It looks like `band` is what we want, so we put it in the `where` argument of `queryDatasets`. Let's try the $g$ band." |
| 294 | + "It looks like `band` is what we want, so we include that in the `dataId` argument of `queryDatasets`. We can also select only visits with visit numbers larger than 700000 by adding a constraint in the `where` argument of `queryDatasets`. Let's try the $g$ band." |
296 | 295 | ] |
297 | 296 | }, |
298 | 297 | { |
|
344 | 343 | "cell_type": "markdown", |
345 | 344 | "metadata": {}, |
346 | 345 | "source": [ |
347 | | - "The `calexp` is a calibrated CCD image from a single exposure. We'll use the afwDisplay interface to show the pixel values and mask plane (more on afwDisplay can be found in other notebooks)." |
| 346 | + "The `calexp` (also known as a \"processed visit image,\" or PVI) is a calibrated CCD image from a single exposure. We'll use the afwDisplay interface to show the pixel values and mask plane (more on afwDisplay can be found in other notebooks)." |
348 | 347 | ] |
349 | 348 | }, |
350 | 349 | { |
|
364 | 363 | "cell_type": "markdown", |
365 | 364 | "metadata": {}, |
366 | 365 | "source": [ |
| 366 | + "Note the blue coloring of most sources in the above image (if you have sensitive eyes, you may also see some red streaks). The colors are set by the \"mask\" plane, which encodes things such as bad pixels, or ones that saturated (in this case, the blue pixels are those that are part of detected sources). See the Image Display and Manipulation tutorial for more about the mask plane. \n", |
| 367 | + "\n", |
367 | 368 | "Now that we have a calibrated image, we may want to get the catalog of sources that were extracted from it. To get the `src` catalog associated with this `calexp` we pass the `dataId` to the butler with the `src` datasetType. Note that this performs another query to the registry database to find the `src` catalog that matches our dataId requirements." |
368 | 369 | ] |
369 | 370 | }, |
|
401 | 402 | "afw_display.mtv(calexp)\n", |
402 | 403 | "plt.gca().axis('off')\n", |
403 | 404 | "\n", |
| 405 | + "# We use display buffering to avoid re-drawing the image after each source is plotted\n", |
404 | 406 | "with afw_display.Buffering():\n", |
405 | 407 | " for s in src:\n", |
406 | 408 | " afw_display.dot('+', s.getX(), s.getY(), ctype=afwDisplay.RED)\n", |
|
413 | 415 | "source": [ |
414 | 416 | "### 4. How to query for multiple data sets\n", |
415 | 417 | "\n", |
416 | | - "In the case above, both the `calexp` and `src` can be found by the registry, but this will not always necessarily be the case. The `queryDimensions` method provides a more flexible way to query for multiple datasets (requiring an instance of all datasets to be available for that dataId) or ask for different dataId keys than what is used to identify the dataset (which invokes various built-in relationships). An example of this is provided below:" |
| 418 | + "In the case above, both the `calexp` and `src` can be found by the registry, but this will not always necessarily be the case. The `queryDataIds` method provides a more flexible way to query for multiple datasets (requiring an instance of all datasets to be available for that dataId) or ask for different dataId keys than what is used to identify the dataset (which invokes various built-in relationships). An example of this is provided below:" |
417 | 419 | ] |
418 | 420 | }, |
419 | 421 | { |
|
422 | 424 | "metadata": {}, |
423 | 425 | "outputs": [], |
424 | 426 | "source": [ |
425 | | - "# Use queryDimensions to provide more flexible access\n", |
| 427 | + "# Use queryDataIds to grab the dataIds for a subset taken from a single visit\n", |
426 | 428 | "dataIds = registry.queryDataIds([\"visit\", \"detector\", \"band\"], datasets=[\"calexp\",\"src\"], where='visit = 703697',\n", |
427 | 429 | " collections=collection)\n", |
428 | 430 | "for i,dataId in enumerate(dataIds):\n", |
|
436 | 438 | "metadata": {}, |
437 | 439 | "outputs": [], |
438 | 440 | "source": [ |
439 | | - "# Use queryDataIds to grab the dataIds for a subset\n", |
| 441 | + "# Use queryDataIds to grab the dataIds for a subset using the \"where\" functionality\n", |
440 | 442 | "dataIds = registry.queryDataIds([\"visit\", \"detector\"], datasets=[\"calexp\",\"src\"], \n", |
441 | 443 | " where=\"band='g' and detector=0 and visit > 700000\",\n", |
442 | 444 | " collections=collection)\n", |
|
458 | 460 | "metadata": {}, |
459 | 461 | "outputs": [], |
460 | 462 | "source": [ |
| 463 | + "# Use queryDimensions to provide more flexible access\n", |
461 | 464 | "for dim in ['exposure','visit','detector']:\n", |
462 | 465 | " print(list(registry.queryDimensionRecords(dim, where='visit = 971990 and detector=0'))[0])\n", |
463 | 466 | " print()" |
|
764 | 767 | "plt.title('Butler coadd_forced_src objects in tract 4638 patch 43')" |
765 | 768 | ] |
766 | 769 | }, |
| 770 | + { |
| 771 | + "cell_type": "markdown", |
| 772 | + "metadata": {}, |
| 773 | + "source": [ |
| 774 | + "As a final note -- did you notice that the RA and Dec columns (`coord_ra` and `coord_dec`, specifically) have units of _radians_? As an exercise, you could use what you've learned from above to confirm this by accessing the table schema. (Also note that you can scroll up and find the answer in the outputs from a cell you already executed.) " |
| 775 | + ] |
| 776 | + }, |
767 | 777 | { |
768 | 778 | "cell_type": "code", |
769 | 779 | "execution_count": null, |
|
0 commit comments