202.5. Raw images¶
202.5. Raw images¶
Data Release: Data Preview 1
Container Size: large
LSST Science Pipelines version: r29.1.1
Last verified to run: 2025-06-23
Repository: github.com/lsst/tutorial-notebooks
Learning objective: To understand the format and metadata of a raw
exposure.
LSST data products: raw
Packages: lsst.daf.butler
, lsst.afw.display
Credit: Originally developed by the Rubin Community Science team. Please consider acknowledging them if this notebook is used for the preparation of journal articles, software releases, or other notebooks.
Get Support: Everyone is encouraged to ask questions or raise issues in the Support Category of the Rubin Community Forum. Rubin staff will respond to all questions posted there.
1. Introduction¶
A raw
exposure is stored and made available exactly as it was read out of the camera.
The raw
exposures should not be used for scientific analysis.
Use the visit_image
instead, which has been fully processed and calibrated.
- butler dataset type:
raw
- number of images: 16125
Related tutorials: The 100-level tutorials on how to use the Butler, TAP, SIA, and Firefly demonstrate how to query for and retrieve images, and how to manipulate the Firefly display interface.
1.1. Import packages¶
Import the Rubin data Butler
and the afw.display
package to retrieve and display calibration images.
from lsst.daf.butler import Butler
import lsst.afw.display as afwDisplay
import lsst.geom
1.2. Define parameters and functions¶
Instantiate the Butler.
butler = Butler("dp1", collections="LSSTComCam/DP1")
assert butler is not None
Set the display backend to Firefly and open frame 1.
afwDisplay.setDefaultBackend('firefly')
afw_display = afwDisplay.Display(frame=1)
2. Data access¶
It is recommended to use the Rubin data Butler
to retrieve image data within Jupyter Notebooks,
but they are also available via the TAP and SIA services (Table Access Protocol and Simple Image Access).
Recommended access method: Butler
2.1. Butler¶
Show that the dimensions for the raw
dataset type are the band, instrument, day, detector, group, filter, and exposure, and that the returned image will be of type Exposure
.
butler.get_dataset_type('raw')
DatasetType('raw', {band, instrument, day_obs, detector, group, physical_filter, exposure}, Exposure)
Show that only instrument, detector, and exposure (visit number) are required to uniquely identify a raw
image.
butler.get_dataset_type('raw').dimensions.required
{instrument, detector, exposure}
2.2. Retrieve a raw exposure¶
The most common motivation for accessing raw exposure will be to display and examine the raws for a given visit detector image.
In this use case, the visit and detector number are already known, so that is what is demonstrated here.
Define the exposure (visit) and detector identifiers.
use_exposure = 2024120700527
use_detector = 0
Query the Butler for dataset references that match.
dataset_refs = butler.query_datasets("raw", exposure=use_exposure,
detector=use_detector)
print(len(dataset_refs))
1
Retrieve the raw
exposure.
ref = dataset_refs[0]
raw = butler.get(ref)
2.3 Display a raw exposure¶
Display the raw
in the Firefly window. The .image
must be included, to send only the pixel data to the display window, or else Firefly will return an error upon finding there is no WCS included in the Exposure
.
afw_display.image(raw.image)
Retrieve the corresponding processed visit image and display it in another Firefly frame.
visit_image = butler.get("visit_image", visit=use_exposure,
detector=use_detector)
afw_display = afwDisplay.Display(frame=2)
afw_display.image(visit_image)
afw_display.setMaskTransparency(100)
Notice that the raw
exposure includes the overscan regions,
which give the impression of chip gaps between the amplifiers,
and also makes the raw
exposure have different pixel dimensions than the corresponding visit_image
.
Clean up.
del visit_image
3. Pixel data¶
The raw
exposures have only an image plane, with no variance or mask planes like the visit_images
, as those planes are a result of image processing and calibration.
3.1. Image plane¶
Sky pixel data in units of ADU (analog-digital units).
Extract the image
data from the raw
, and convert it to an array.
image = raw.getImage()
image_array = image.array
Print statistics on the image_array
.
print(image_array.min())
print(image_array.mean())
print(image_array.max())
19909.0 24732.4 137775.0
Clean up.
del image, image_array
metadata = raw.getMetadata()
Option to display the long list of metadata.
# metadata
Convert the metadata to a python dictionary.
md_dict = metadata.toDict()
Show any metadata key that contains the string "UNIT".
for key in md_dict.keys():
if key.find('UNIT') >= 0:
print(key)
BUNIT
Print the "BUNIT" from the dictionary (the flux units).
md_dict['BUNIT']
'adu'
Clean up.
del metadata, md_dict
4.2. Visit information¶
Information about the observation associated with this raw
,
such as pointing, airmass, and weather.
Get the visit info.
info = raw.getInfo().getVisitInfo()
print(info.getBoresightAirmass())
print(info.getBoresightParAngle())
print(info.getDate())
print(info.getExposureTime())
1.111051844859137 1.88672 rad DateTime("2024-12-08T07:50:12.484500321", TAI) 30.0
Get the weather information.
weather = info.getWeather()
print(weather.getAirPressure())
print(weather.getAirTemperature())
print(weather.getHumidity())
74000.0 7.699999809265137 14.824999809265137
del info, weather
4.3. World Coordinate System (WCS)¶
This is not an astrometric solution but rather an initial WCS generated from the telescope pointing and detector geometry.
Option to view the initial WCS estimate.
# wcs = raw.getWcs()
# wcs
4.4. Bounding box (corners)¶
The bounding box defines the extent (corners) of the image.
Get the bounding box.
bbox = raw.getBBox()
bbox
Box2I(corner=Point2I(0, 0), dimensions=Extent2I(4608, 4096))
Print the raw
corners in pixels and sky coordinates.
corners = (lsst.geom.Point2D(bbox.beginX, bbox.beginY),
lsst.geom.Point2D(bbox.beginX, bbox.endY),
lsst.geom.Point2D(bbox.endX, bbox.endY),
lsst.geom.Point2D(bbox.endX, bbox.beginY))
Print the area of the bounding box.
Note that the bounding box of a raw
exposure seems
larger than that of a visit_image
due to overscan.
print(bbox.area, 'square pixels')
18874368 square pixels
Check that the first set of pixel values are within the bounding box, and that the second set is not.
assert bbox.contains(100, 100) is True
print(bbox.contains(100, 100))
assert bbox.contains(10000, 10000) is False
print(bbox.contains(10000, 10000))
True False
Clean up.
del bbox, corners