spizzle: drizzle as a sparse linear operator
spizzle resamples images with the square kernel of
drizzle, written out as an
explicit sparse matrix W. It builds W once per exposure and applies
it to the science data, the weights and every variance plane, in float64
and in parallel. With W in hand it also gives the noise covariance that
drizzling introduces, so that mosaics come with correct uncertainties for
sums over areas typical in aperture photometry.
What is here
pixel_map |
the pixel map of an exposure onto an output grid, from the two WCS; fast, by splines through a coarse grid |
drizzle_operator |
the square-kernel operator W of one exposure, an Operator on the exposure's region of the output grid |
Coadd |
the weighted mean of exposures: science, weights, variance planes and, if asked for, context, summed in float64 |
Covariance |
the covariance between neighboring output pixels, the noise factor, and a correlation file |
NoiseFactor |
the noise factor alone, in a second pass over the exposures, with little memory |
blot |
a mosaic interpolated back onto an exposure's pixels, as drizzle's bilinear blot_image |
StcalVariance |
the variance planes and ERR as the JWST pipeline computes them, to compare with it |
corners, jacobian, overlap_triplets and build_operator are the
steps of drizzle_operator, to keep the geometry and re-weight it.
Installation
pip install spizzle
Install extras pip install "spizzle[jwst]" adds jwst for comparing
spizzle with the JWST pipeline (benchmarks/compare_stcal.py).
Getting started
import numpy as np
from spizzle import Coadd, NoiseFactor, drizzle_operator, pixel_map
# exposures: (data, var, weights, wcs) of each exposure; wcs_out, out_shape: the output grid
coadd = Coadd(out_shape, n_var=1)
ops = []
for data, var, weights, wcs in exposures:
pixmap = pixel_map(wcs, wcs_out, shape=data.shape)
op = drizzle_operator(pixmap, out_shape, pixfrac=0.8, weights=weights)
coadd.add(op, data, variances=[var])
ops.append(op)
image, weight, variance = coadd.out_img, coadd.out_wht, coadd.out_var[0]
# the noise factor, in a second pass with the weight sums of the first
# (keep the operators, as here, or build them again)
nf = NoiseFactor(coadd.out_wht)
for op, (data, var, weights, wcs) in zip(ops, exposures):
nf.add(op, var)
error = np.sqrt(variance * nf.noise_factor) # for sums over areas
sqrt(variance) is the uncertainty of a single pixel; drizzling correlates
neighboring pixels, so the uncertainty of a sum over an area is larger by
the square root of the noise factor, about 1.5 for NIRCam at its native
scale. To compare an exposure with a mosaic, as outlier detection does,
blot(median, pixmap) interpolates the mosaic back onto the exposure's
pixels, with the exposure's pixel map onto the mosaic.
The documentation describes the pixel maps, the operator, the covariance and blot in more detail, and how the results compare with drizzle and with the JWST pipeline.
Speed
One NIRCam exposure (2048x2048, three variance planes) onto a mosaic of
eight, on an Apple M3 Pro with 11 threads (benchmarks/speed_table.py):
| step | drizzle | spizzle | faster |
|---|---|---|---|
| pixel map from the WCS | 0.77 s | 0.020 s | 38x |
| drizzle the science data and 3 variance planes | 0.51 s | 0.24 s | 2x |
| blot a median and its error | 0.039 s | 0.0058 s | 7x |
jwst ResampleImage of the eight exposures |
20 s | 4.8 s | 4x |
The results agree with drizzle computing in float64 to about 1e-15, and
with the JWST pipeline to float32 round-off. In the last row spizzle
computes the variance as the pipeline does (StcalVariance), with the
data already in memory.
How it differs from drizzle
- Square kernel only.
- Every input pixel with a valid pixel map is drizzled; drizzle skips input pixels whose centers fall outside the output frame, so the outer output pixels get less weight from drizzle than from spizzle.
blotaccepts positions over the image's extent,[-0.5, n - 0.5); drizzle accepts[0, n), half a pixel off.- Fill values are numbers, NaN by default.
Development
The tests compare spizzle with drizzle, which must accept float64 output arrays. Until that is in a drizzle release, install it from the branch:
pip install -e ".[test]"
pip install "drizzle @ git+https://github.com/jdavies-st/drizzle.git@float64-phase2-c-accepts-float64"
pytest tests
benchmarks/ has the timings and the comparisons with drizzle, the JWST
pipeline and noise realizations.
Citing spizzle
The citation information is in CITATION.cff.
License
BSD 3-clause, see LICENSE. The overlap geometry in spizzle.geometry
and the bilinear interpolation of blot are ported from drizzle,
Copyright (C) 2011,2014 Association of Universities for Research in
Astronomy (AURA), under the BSD 3-clause license in
licenses/DRIZZLE_LICENSE.rst.
Metadata
Release files for spizzle 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| spizzle-0.2.1.tar.gz | 98.9 kB | With provenance | Details for spizzle-0.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| spizzle-0.2.1-py3-none-any.whl | Python 3 | none | any | Details for spizzle-0.2.1-py3-none-any.whl |
Total release size: 130.0 kB
Release files / spizzle-0.2.1.tar.gz
| Download URL | spizzle-0.2.1.tar.gz |
|---|---|
| Size | 98.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a4426105cfdaf20a28a3f75d8ac08e96b90390c271195823f4e39d0684ad1648
|
|
BLAKE2b-256 checksum How to use checksums |
c189776b15248b1951f555e25ee182bf019bd88243c00f3d4d6dc2a4b6b7c830
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logRelease files / spizzle-0.2.1-py3-none-any.whl
| Download URL | spizzle-0.2.1-py3-none-any.whl |
|---|---|
| Size | 31.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d98039d761c2da3e4c51b972156b82e152f4a256d7ab8f905668e88a499788fa
|
|
BLAKE2b-256 checksum How to use checksums |
b0e87722e4d2aed3a6be72e866dff3f7e04fc889027191a4d173ce802c1eb881
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logSecurity for spizzle 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for spizzle-0.2.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.