Skip to content

Commit 236b963

Browse files
committed
first functional changes
1 parent 4afd480 commit 236b963

1 file changed

Lines changed: 99 additions & 29 deletions

File tree

DP1/100_How_to_Use_RSP_Tools/105_Image_reprocessing/105_3_Forced_Photometry.ipynb

Lines changed: 99 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
"Data Release: <a href=\"https://dp1.lsst.io/\">Data Preview 1</a> <br>\n",
2323
"Container Size: large <br>\n",
2424
"LSST Science Pipelines version: r29.2.0 <br>\n",
25-
"Last verified to run: 2025-11-03 <br>\n",
26-
"Repository: <a href=\"https://github.com/lsst/tutorial-notebooks\">github.com/lsst/tutorial-notebooks</a> <br>"
25+
"Last verified to run: 2025-12-04 <br>\n",
26+
"Repository: [github.com/lsst/tutorial-notebooks](https://github.com/lsst/tutorial-notebooks)\\\n",
27+
"DOI: [10.11578/rubin/dc.20250909.20](https://doi.org/10.11578/rubin/dc.20250909.20)"
2728
]
2829
},
2930
{
@@ -42,9 +43,7 @@
4243
"Please consider acknowledging them if this notebook is used for the preparation of journal articles, software releases, or other notebooks.\n",
4344
"\n",
4445
"**Get Support:**\n",
45-
"Everyone is encouraged to ask questions or raise issues in the \n",
46-
"<a href=\"https://community.lsst.org/c/support\">Support Category</a> \n",
47-
"of the Rubin Community Forum.\n",
46+
"Everyone is encouraged to ask questions or raise issues in the [Support Category](https://community.lsst.org/c/support) of the Rubin Community Forum.\n",
4847
"Rubin staff will respond to all questions posted there."
4948
]
5049
},
@@ -58,7 +57,7 @@
5857
"\n",
5958
"This notebook performs forced photometry using the Data Preview 1 (DP1) data products on an input image, given a set of input IDs and RA/Dec coordinates. The `ForcedMeasurementDriverTask` serves as a convenience function, allowing users to measure sources without running a full-scale `pipetask` command or dealing with additional pipeline setup. This task can measure fluxes, shapes, and other properties at known source positions (e.g., from a pre-existing catalog) on a given image, without running source detection. (Note that for brevity we disable shape measurement in this notebook.)\n",
6059
"\n",
61-
"**Related tutorials:** 100-level Detect and measure sources"
60+
"**Related tutorials:** The 100-level tutorial on how to detect and measure sources."
6261
]
6362
},
6463
{
@@ -185,7 +184,9 @@
185184
"source": [
186185
"## 2. Load an image and table\n",
187186
"\n",
188-
"Identify coadded images overlapping a particular sky position and select one to run forced photometry on. Also load the corresponding `object` table using the TAP service so that forced photometry can be run at the positions of already-detected objects."
187+
"Identify coadded images overlapping a particular sky position and select one to run forced photometry on. Also load the corresponding `object` table using the TAP service so that forced photometry can be run at the positions of already-detected objects.\n",
188+
"\n",
189+
"Define the right ascension and declination as the center of the ECDFS field, and use the $r$ band."
189190
]
190191
},
191192
{
@@ -200,6 +201,14 @@
200201
"band = 'r'"
201202
]
202203
},
204+
{
205+
"cell_type": "markdown",
206+
"id": "35debe43-cd77-431b-a294-9e50a037738b",
207+
"metadata": {},
208+
"source": [
209+
"Execute a butler query for deep coadd images."
210+
]
211+
},
203212
{
204213
"cell_type": "code",
205214
"execution_count": null,
@@ -209,19 +218,26 @@
209218
"source": [
210219
"query = f\"band='{band}' AND \\\n",
211220
" patch.region OVERLAPS POINT({ra}, {dec})\"\n",
212-
"\n",
213-
"coadd_img_refs = butler.query_datasets('deep_coadd', where=query)\n",
214-
"\n",
215-
"ref = coadd_img_refs[0]"
221+
"coadd_img_refs = butler.query_datasets('deep_coadd', where=query)"
222+
]
223+
},
224+
{
225+
"cell_type": "markdown",
226+
"id": "cc662eff-84ed-4fa9-9baa-7901cda08038",
227+
"metadata": {},
228+
"source": [
229+
"Assert that at least one matching image was returned, and retrieve the first in the list."
216230
]
217231
},
218232
{
219233
"cell_type": "code",
220234
"execution_count": null,
221-
"id": "b8e8b42d-eda2-4c96-a412-22e99da51a5d",
235+
"id": "7b1aa5b0-b59e-49c2-8891-f7d0d469851b",
222236
"metadata": {},
223237
"outputs": [],
224238
"source": [
239+
"assert(len(coadd_img_refs) > 0)\n",
240+
"ref = coadd_img_refs[0]\n",
225241
"exposure = butler.get(ref)"
226242
]
227243
},
@@ -230,7 +246,7 @@
230246
"id": "3a57d04c-00ae-4278-b637-9e312084419d",
231247
"metadata": {},
232248
"source": [
233-
"Extract a list of objects from the `Object` table in a small radius near the position of interest. These will be used both as an input list for forced measurement, and as a comparison for the results."
249+
"Query for point-like objects from the `Object` table in a 0.3 degree radius near the position of interest that overlap the deep coadd image's tract and patch. "
234250
]
235251
},
236252
{
@@ -243,7 +259,7 @@
243259
"query = f\"\"\"SELECT TOP 50 objectId, coord_ra, coord_dec, {band}_psfMag, {band}_psfFlux\n",
244260
" FROM dp1.Object\n",
245261
" WHERE CONTAINS(POINT('ICRS', coord_ra, coord_dec),\n",
246-
" CIRCLE('ICRS', {ra}, {dec}, 0.1)) = 1\n",
262+
" CIRCLE('ICRS', {ra}, {dec}, 0.3)) = 1\n",
247263
" AND refExtendedness < 0.5\n",
248264
" AND {band}_psfMag < 26 AND {band}_psfMag > 17\n",
249265
" AND tract = {ref.dataId['tract']}\n",
@@ -254,11 +270,47 @@
254270
"job.wait(phases=['COMPLETED', 'ERROR'])\n",
255271
"print('Job phase is', job.phase)\n",
256272
"if job.phase == 'ERROR':\n",
257-
" job.raise_if_error()\n",
273+
" job.raise_if_error()"
274+
]
275+
},
276+
{
277+
"cell_type": "markdown",
278+
"id": "f0939bcb-a517-4ec3-b2c0-3fb3b8700681",
279+
"metadata": {},
280+
"source": [
281+
"Retrieve the search results as `objtable`.\n",
282+
"This table will be used both as an input list for forced measurement, and as a comparison for the results."
283+
]
284+
},
285+
{
286+
"cell_type": "code",
287+
"execution_count": null,
288+
"id": "1803ae74-76d1-42f1-9e29-39231188f026",
289+
"metadata": {},
290+
"outputs": [],
291+
"source": [
258292
"assert job.phase == 'COMPLETED'\n",
259293
"objtable = job.fetch_result().to_table()"
260294
]
261295
},
296+
{
297+
"cell_type": "markdown",
298+
"id": "930f2a06-8918-43f5-9a05-bca95da38b03",
299+
"metadata": {},
300+
"source": [
301+
"Ensure that the table is not empty."
302+
]
303+
},
304+
{
305+
"cell_type": "code",
306+
"execution_count": null,
307+
"id": "f3234934-8c70-4a75-87b8-2b59e5c1eb1a",
308+
"metadata": {},
309+
"outputs": [],
310+
"source": [
311+
"assert(len(objtable) > 0)"
312+
]
313+
},
262314
{
263315
"cell_type": "markdown",
264316
"id": "e4243773-e324-4415-884c-857cdb497688",
@@ -434,7 +486,7 @@
434486
"source": [
435487
"The forced measurement functionality is limited to a handful of measurement plugins (for example, model-fitting algorithms will not work with this task because they require more ancillary information than it is set up to receive). Nonetheless, it offers a quick and easy way to extract measurements at arbitrary positions.\n",
436488
"\n",
437-
"### 3.1 Compare the forced measurements to the Object table\n",
489+
"### 3.1. Compare the forced measurements to the Object table\n",
438490
"\n",
439491
"Make a plot showing the ratio of the measured PSF fluxes from the forced measurement task to the `psfFlux` for the same objects in the `Object` table. Plot these as a function of magnitude, using Astropy units to convert `slot_PsfFlux_flux` from the `result` table to AB magnitudes."
440492
]
@@ -468,7 +520,9 @@
468520
"source": [
469521
"## 4. Forced measurement on a visit image\n",
470522
"\n",
471-
"The forced measurement task can be run on any `ExposureF` object. To demonstrate this, retrieve a `visit_image` and execute the driver to extract forced photometry on that image. The appropriate input catalog for `visit_image` measurements is the `Source` table."
523+
"The forced measurement task can be run on any `ExposureF` object. To demonstrate this, retrieve a `visit_image` and execute the driver to extract forced photometry on that image. The appropriate input catalog for `visit_image` measurements is the `Source` table.\n",
524+
"\n",
525+
"Query the butler for overlapping visit images and retrieve the first in the list."
472526
]
473527
},
474528
{
@@ -480,20 +534,18 @@
480534
"source": [
481535
"query = f\"band='{band}' AND \\\n",
482536
" visit.region OVERLAPS POINT({ra}, {dec})\"\n",
483-
"\n",
484537
"visit_img_refs = butler.query_datasets('visit_image', where=query)\n",
485-
"\n",
486-
"ref = visit_img_refs[0]"
538+
"assert(len(visit_img_refs) > 0)\n",
539+
"ref = visit_img_refs[0]\n",
540+
"exposure = butler.get(ref)"
487541
]
488542
},
489543
{
490-
"cell_type": "code",
491-
"execution_count": null,
492-
"id": "171e7626-85a7-4974-b1e6-d4964f8b814b",
544+
"cell_type": "markdown",
545+
"id": "c0760743-4c48-4db1-95fb-b2d2dd05da30",
493546
"metadata": {},
494-
"outputs": [],
495547
"source": [
496-
"exposure = butler.get(ref)"
548+
"Query the TAP service for point-like sources detected in the visit image."
497549
]
498550
},
499551
{
@@ -506,7 +558,7 @@
506558
"query = f\"\"\"SELECT TOP 50 sourceId, ra, dec, psfFlux\n",
507559
" FROM dp1.Source\n",
508560
" WHERE CONTAINS(POINT('ICRS', ra, dec),\n",
509-
" CIRCLE('ICRS', {ra}, {dec}, 0.1)) = 1\n",
561+
" CIRCLE('ICRS', {ra}, {dec}, 0.3)) = 1\n",
510562
" AND extendedness < 0.5\n",
511563
" AND visit = {ref.dataId['visit']}\n",
512564
" AND detector = {ref.dataId['detector']}\"\"\"\n",
@@ -516,9 +568,27 @@
516568
"job.wait(phases=['COMPLETED', 'ERROR'])\n",
517569
"print('Job phase is', job.phase)\n",
518570
"if job.phase == 'ERROR':\n",
519-
" job.raise_if_error()\n",
571+
" job.raise_if_error()"
572+
]
573+
},
574+
{
575+
"cell_type": "code",
576+
"execution_count": null,
577+
"id": "5ebe2ed5-1b67-4ad8-b798-d69726dfba4e",
578+
"metadata": {},
579+
"outputs": [],
580+
"source": [
520581
"assert job.phase == 'COMPLETED'\n",
521-
"srctable = job.fetch_result().to_table()"
582+
"srctable = job.fetch_result().to_table()\n",
583+
"assert(len(srctable) > 0)"
584+
]
585+
},
586+
{
587+
"cell_type": "markdown",
588+
"id": "acc39c47-eb40-46a9-b130-c2873d14a41f",
589+
"metadata": {},
590+
"source": [
591+
"Configure and run forced photometry."
522592
]
523593
},
524594
{
@@ -588,7 +658,7 @@
588658
"id": "af970fba-e2b5-42db-95a5-b24e6ec11caa",
589659
"metadata": {},
590660
"source": [
591-
"### 4.1 Compare the forced measurements to the Source table\n",
661+
"### 4.1. Compare the forced measurements to the Source table\n",
592662
"\n",
593663
"Make a plot showing the ratio of the measured PSF fluxes from the forced measurement task to the `psfFlux` for the same objects in the `Source` table. Plot these as a function of magnitude, using Astropy units to convert `slot_PsfFlux_flux` from the `result` table to AB magnitudes."
594664
]

0 commit comments

Comments
 (0)