|
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", |
11 | | - "Credit: Originally developed in the context of the LSST Stack Club <br>\n", |
| 11 | + "Credit: Originally developed by Alex Drlica-Wagner in the context of the LSST Stack Club <br>\n", |
12 | 12 | "Target audience: All DP0 delegates. <br>\n", |
13 | 13 | "Container Size: medium <br>\n", |
14 | | - "<br>\n", |
15 | 14 | "Questions welcome at <a href=\"https://community.lsst.org/c/support/dp0\">community.lsst.org/c/support/dp0</a> <br>\n", |
16 | 15 | "Find DP0 documentation and resources at <a href=\"https://dp0-1.lsst.io\">dp0-1.lsst.io</a> <br>\n", |
17 | 16 | "\n", |
| 17 | + "<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 | | - "The goals of this notebook are:\n", |
| 20 | + "<br>\n", |
| 21 | + "<br>\n", |
| 22 | + "The goals of this notebook are to:<br>\n", |
| 23 | + "1. create an instance of the Butler<br>\n", |
| 24 | + "2. explore the DP0.1 data repository<br>\n", |
| 25 | + "3. retrive and display some image and catalog data<br>\n", |
| 26 | + "4. create in image cutout at a user-specified coordinate<br>\n", |
| 27 | + "5. retrieve and plot catalog data \n", |
21 | 28 | "\n", |
22 | | - "1. Create a Butler.\n", |
23 | | - "2. Programmatically explore the content of the DP0.1 data repository\n", |
24 | | - "3. Grab some DP0.1 data! \n", |
25 | | - "4. Grab a cutout of the DP0.1 coadds at a specific (RA,Dec).\n", |
26 | 29 | "\n", |
27 | | - "**Credit:** This notebook was originally developed by Alex Drlica-Wagner in the context of the LSST Stack Club.\n", |
28 | 30 | "\n", |
29 | 31 | "### Setup" |
30 | 32 | ] |
|
64 | 66 | "cell_type": "markdown", |
65 | 67 | "metadata": {}, |
66 | 68 | "source": [ |
67 | | - "We import several packages from the LSST Science Pipelines. The first import gives us access to the Butler, while the second provides tools for displaying data. More details on data display can be found in [03_Intro_to_AFW_Display.ipynb](03_Intro_to_AFW_Display.ipynb)." |
| 69 | + "We import several packages from the LSST Science Pipelines. \n", |
| 70 | + "The first import gives us access to the Butler, while the second provides tools for displaying data.\n", |
| 71 | + "\n", |
| 72 | + "More details and techniques regarding image display can be found in the `rubin-dp0` GitHub Organization's [tutorial-notebooks](https://github.com/rubin-dp0/tutorial-notebooks) repository." |
68 | 73 | ] |
69 | 74 | }, |
70 | 75 | { |
|
140 | 145 | "source": [ |
141 | 146 | "This is our first glimpse at the data contained in the repository, but it doesn't teach us *which* collection we are actually interested in. The names do give us some hints though...\n", |
142 | 147 | "\n", |
| 148 | + "* `2.2i` - refers to the processing run of the LSST DESC DC2 data (the `i` stands for `imSim`)\n", |
143 | 149 | "* `calib` - refers to calibration products that are used for instrument signature removal\n", |
| 150 | + "* `runs` - refers to processed data products\n", |
144 | 151 | "* `refcats` - refers to the reference catalogs used for astrometric and photometric calibration\n", |
145 | 152 | "* `skymaps` - are the geometric representations of the sky coverage\n", |
146 | | - "* `2.2i` - refers to the processing run of the LSST DESC DC2 data (the `i` stands for `imSim`)\n", |
147 | 153 | "\n", |
148 | 154 | "Collections can be nested, so we can access to everything for DC2 Run 2.2i (the primary DP0.1 data set) by selecting the collection `2.2i/runs/DP0.1`. This is a pointer to other collections that expand out recursively... More on collections can be found here: https://pipelines.lsst.io/v/weekly/modules/lsst.daf.butler/organizing.html#collections" |
149 | 155 | ] |
|
205 | 211 | "- `calexp` - Refers to individual calibrated exposure\n", |
206 | 212 | "- `deepCoadd` - Refers to products produced on the coadd images (both images and and source catalogs)\n", |
207 | 213 | "- `src` - refers the the catalog of sources\n", |
208 | | - "- `skyMap` - refers to geometric representations of the sky coverage" |
| 214 | + "- `skyMap` - refers to geometric representations of the sky coverage\n", |
| 215 | + "\n", |
| 216 | + "<b> Which data sets are most appropriate for DP0.1? </b><br>\n", |
| 217 | + "Most DP0.1 delegates will only be interested in data sets with types `ExposureF` or `SourceCatalog`. \n", |
| 218 | + "For images, stick to the `calexp` (processed visit images, or PVIs) and `deepCoadd` (stacked PVIs).\n", |
| 219 | + "For catalogs, the `src` should be used with the `calexp` images, and the `deepCoadd_forced_src` are the most appropriate to be used with the `coadds`.\n", |
| 220 | + "More information can be found in the DP0.1 Data Products Definitions Document (DPDD) at [dp0-1.lsst.io](http://dp0-1.lsst.io).\n", |
| 221 | + "\n", |
| 222 | + "<br>\n" |
209 | 223 | ] |
210 | 224 | }, |
211 | 225 | { |
|
233 | 247 | "cell_type": "markdown", |
234 | 248 | "metadata": {}, |
235 | 249 | "source": [ |
236 | | - "We can get the path from the URI that is returned by `butler.getURI`. Note that this URI does not have to refer to a local path on the filesystem." |
| 250 | + "We can get the path from the URI that is returned by `butler.getURI`. Note that this URI does not refer to a local path on the filesystem. We do not need to know exactly where the data live in order to access it. That's the power of the Butler." |
237 | 251 | ] |
238 | 252 | }, |
239 | 253 | { |
|
300 | 314 | "cell_type": "markdown", |
301 | 315 | "metadata": {}, |
302 | 316 | "source": [ |
303 | | - "### 3. Get some data\n", |
| 317 | + "### 3. Retrieve and plot a calexp with sources\n", |
304 | 318 | "\n", |
305 | 319 | "Ok, now we have all the information we need to ask the Butler to get a specific data product. We have identified a collection (`2.2i/runs/DP0.1`), a `datasetType` (`calexp`), and the `dataId` (from the `datasetRef`) to uniquely specify an instance of this data set." |
306 | 320 | ] |
|
397 | 411 | "cell_type": "markdown", |
398 | 412 | "metadata": {}, |
399 | 413 | "source": [ |
400 | | - "### 4. Querying for multiple data sets\n", |
| 414 | + "### 4. How to query for multiple data sets\n", |
401 | 415 | "\n", |
402 | 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:" |
403 | 417 | ] |
|
453 | 467 | "cell_type": "markdown", |
454 | 468 | "metadata": {}, |
455 | 469 | "source": [ |
456 | | - "### 5. Grabbing an Image Cutout\n", |
| 470 | + "### 5. Generate an Image Cutout\n", |
457 | 471 | "\n", |
458 | 472 | "Say we want to grab a cutout of the DP0.1 coadded images at a specific location. In order to do this, we need a few other packages from the LSST Science Pipelines. In particular, access to the geometry and coordinate packages." |
459 | 473 | ] |
|
546 | 560 | "afw_display.mtv(cutout_image.image)\n", |
547 | 561 | "plt.gca().axis('off')" |
548 | 562 | ] |
| 563 | + }, |
| 564 | + { |
| 565 | + "cell_type": "markdown", |
| 566 | + "metadata": {}, |
| 567 | + "source": [ |
| 568 | + "### 6. Retrieve and plot catalog data from the Butler\n", |
| 569 | + "\n", |
| 570 | + "The TAP service is the recommended way to retrieve DP0.1 catalog data for a notebook, and there are several other tutuorials that demonstrate how to use the TAP service.\n", |
| 571 | + "\n", |
| 572 | + "But if Butler access to catalog data is needed, start by retrieving only the schema of a Butler catalog.\n", |
| 573 | + "Unlike with TAP schema (as in the first tutorial notebook), the Butler schema do not come with embedded column descriptions. Refer to the DP0.1 Data Products Definitions Document (DPDD) at [dp0-1.lsst.io](http://dp0-1.lsst.io) to find out more about the columns." |
| 574 | + ] |
| 575 | + }, |
| 576 | + { |
| 577 | + "cell_type": "code", |
| 578 | + "execution_count": null, |
| 579 | + "metadata": {}, |
| 580 | + "outputs": [], |
| 581 | + "source": [ |
| 582 | + "schema_coadd_src = butler.get('deepCoadd_forced_src_schema')\n", |
| 583 | + "schema_coadd_src.asAstropy()" |
| 584 | + ] |
| 585 | + }, |
| 586 | + { |
| 587 | + "cell_type": "markdown", |
| 588 | + "metadata": {}, |
| 589 | + "source": [ |
| 590 | + "<br>\n", |
| 591 | + "The catalogs are very large and it is not feasible to try and retrieve it in its entirety.\n", |
| 592 | + "Instead, in this example we identify the tract and patch of interest and retrieve only catalog data for a small region of sky.\n", |
| 593 | + "Use the same ra and dec coordinates as above to find the patch and tract." |
| 594 | + ] |
| 595 | + }, |
| 596 | + { |
| 597 | + "cell_type": "code", |
| 598 | + "execution_count": null, |
| 599 | + "metadata": {}, |
| 600 | + "outputs": [], |
| 601 | + "source": [ |
| 602 | + "radec = geom.SpherePoint(ra, dec, geom.degrees)\n", |
| 603 | + "\n", |
| 604 | + "skymap = butler.get(\"skyMap\")\n", |
| 605 | + "\n", |
| 606 | + "tractInfo = skymap.findTract(radec)\n", |
| 607 | + "tract = tractInfo.getId()\n", |
| 608 | + "\n", |
| 609 | + "patchInfo = tractInfo.findPatch(radec)\n", |
| 610 | + "patch = tractInfo.getSequentialPatchIndex(patchInfo)\n", |
| 611 | + "\n", |
| 612 | + "print(tract, patch)\n", |
| 613 | + "\n", |
| 614 | + "coaddId = {'tract': tract, 'patch': patch, 'band':'i'}\n", |
| 615 | + "\n", |
| 616 | + "coadd_src = butler.get('deepCoadd_forced_src',coaddId)\n", |
| 617 | + "coadd_src = src.copy(True)" |
| 618 | + ] |
| 619 | + }, |
| 620 | + { |
| 621 | + "cell_type": "code", |
| 622 | + "execution_count": null, |
| 623 | + "metadata": {}, |
| 624 | + "outputs": [], |
| 625 | + "source": [ |
| 626 | + "# Show the table contents if desired\n", |
| 627 | + "# coadd_src.asAstropy()" |
| 628 | + ] |
| 629 | + }, |
| 630 | + { |
| 631 | + "cell_type": "markdown", |
| 632 | + "metadata": {}, |
| 633 | + "source": [ |
| 634 | + "<br>\n", |
| 635 | + "\n", |
| 636 | + "Convert to a Pandas dataframe (see the first tutorial) for easy interaction.\n", |
| 637 | + "The following cells offer options for printing the column names or the data values." |
| 638 | + ] |
| 639 | + }, |
| 640 | + { |
| 641 | + "cell_type": "code", |
| 642 | + "execution_count": null, |
| 643 | + "metadata": {}, |
| 644 | + "outputs": [], |
| 645 | + "source": [ |
| 646 | + "data = coadd_src.asAstropy().to_pandas()" |
| 647 | + ] |
| 648 | + }, |
| 649 | + { |
| 650 | + "cell_type": "code", |
| 651 | + "execution_count": null, |
| 652 | + "metadata": {}, |
| 653 | + "outputs": [], |
| 654 | + "source": [ |
| 655 | + "# print(data.columns)" |
| 656 | + ] |
| 657 | + }, |
| 658 | + { |
| 659 | + "cell_type": "code", |
| 660 | + "execution_count": null, |
| 661 | + "metadata": {}, |
| 662 | + "outputs": [], |
| 663 | + "source": [ |
| 664 | + "# for col in data.columns:\n", |
| 665 | + "# print(col)" |
| 666 | + ] |
| 667 | + }, |
| 668 | + { |
| 669 | + "cell_type": "code", |
| 670 | + "execution_count": null, |
| 671 | + "metadata": {}, |
| 672 | + "outputs": [], |
| 673 | + "source": [ |
| 674 | + "# data['coord_ra'].values" |
| 675 | + ] |
| 676 | + }, |
| 677 | + { |
| 678 | + "cell_type": "markdown", |
| 679 | + "metadata": {}, |
| 680 | + "source": [ |
| 681 | + "Plot the locations of sources in the patch." |
| 682 | + ] |
| 683 | + }, |
| 684 | + { |
| 685 | + "cell_type": "code", |
| 686 | + "execution_count": null, |
| 687 | + "metadata": {}, |
| 688 | + "outputs": [], |
| 689 | + "source": [ |
| 690 | + "fig = plt.figure()\n", |
| 691 | + "plt.plot( data['coord_ra'].values, data['coord_dec'].values, 'o', ms=2, alpha=0.5 )\n", |
| 692 | + "plt.xlabel('RA')\n", |
| 693 | + "plt.ylabel('Dec')\n", |
| 694 | + "plt.title('Butler coadd_forced_src objects in tract 4638 patch 43')" |
| 695 | + ] |
549 | 696 | } |
550 | 697 | ], |
551 | 698 | "metadata": { |
|
0 commit comments