Comet morphology tools for finding comet centers, stacking WCS-registered images, and producing enhanced and gridded visualizations. Designed to work with FITS from multiple facilities (VLT, LCO, JWST, SOAR, etc.) and with astrometry pipelines that produce *_wcs.fits files.
- Python ≥ 3.9
- astropy — FITS I/O, WCS, coordinates, time
- astroquery — JPL Horizons (ephemerides)
- photutils — centroid routines
- matplotlib — plotting
- numpy, scipy — arrays and fitting
Install (dependencies are declared in pyproject.toml):
pip install -e .From the repo root this installs the package in editable mode and pulls in astropy, astroquery, photutils, matplotlib, numpy, and scipy.
| Module | Purpose |
|---|---|
| centerpix | Find comet center: click-to-centroid or ephemeris-based; get_ephem, center_pix, click_center, ephem_center |
| mappings | Instrument → header keys, telescope codes, and JPL Horizons observatory locations (tel_hdr_keys, tel_translate, obs_location) |
| stacking | Stack *_wcs.fits in a directory by comet center; outputs median (or mean) stack and zoomed stack |
| enhancements | Azimuthal median subtraction, zoom, radial profile; enhance_img, azimedsub, image_zoom |
| plots | Grid plots of comet images with dates and scale bars; plot_grid, calculate_grid_size |
| fwhm | 2D Gaussian FWHM from image and position |
| radial_profile | Radial profile and power-law helpers |
| morph_plot | Grid morph plots from stacked FITS; call morph_plot(path, ...) or run as script with env vars |
Header and location handling is configured in comet_morph/mappings.py for:
- VLT (FORS2)
- LCO (0.4 m, 1 m)
- JWST
- SOAR (GHTS red/blue imager)
Add or edit entries in tel_hdr_keys, tel_translate, and obs_location as needed.
From a FITS file or an (image, header) tuple:
from comet_morph.centerpix import center_pix
# Ephemeris-based center (uses OBJECT/TARGET and date from header)
x, y = center_pix('path/to/image_wcs.fits', method='ephem')
# Or click on the image, then centroid
x, y = center_pix('path/to/image_wcs.fits', method='click', display=True)Expects a directory of *_wcs.fits files. Centers are taken from ephemeris (or click if click=True). Writes median stack and a zoomed stack.
from comet_morph.stacking import stack_date
stack_date('/path/to/date/dir/', tel='vlt', click=False, display=False)
# Writes med_stack.fits, med_stack_zoom.fits (or avg/single for 1–2 images)from comet_morph.enhancements import enhance_img
from astropy.io import fits
img, hdr = fits.getdata('path/to/image_wcs.fits', header=True)
zoomed, enhanced = enhance_img(img, hdr, size=400, method='azimedsub')Grid of enhanced (or raw) FITS with dates and scale:
from comet_morph.plots import plot_grid
plot_grid(
objname='C/2014 UN271',
tel='vlt',
datadir='/path/to/enhanced/',
output_file='morph_grid.pdf',
enhanced=True,
)from comet_morph.fwhm import measure_fwhm
fwhm_x, fwhm_y = measure_fwhm(image, x0, y0)Batch FWHM over many comets (expects base_dir/monthly_stacks/<comet>/ with *_r.fits and *_g.fits):
from comet_morph.fwhm import run_fwhm_batch
run_fwhm_batch('/path/to/your/morphology/root/')Or from the shell: set COMET_MORPH_FWHM_BASE to that root, then python -m comet_morph.fwhm.
from comet_morph.morph_plot import morph_plot
morph_plot(
path='/path/to/data/', # dir containing date subdirs with med_stack_zoom.fits
objname='C/2014 UN271',
tel='vlt',
output_zoom='zoom_grid.pdf',
output_full='full_grid.pdf',
)Or run as a script: set COMET_MORPH_DATA_DIR, and optionally COMET_MORPH_OUTPUT_ZOOM and COMET_MORPH_OUTPUT_FULL, then python -m comet_morph.morph_plot.
MIT License. See LICENSE for details.
Carrie E. Holt, Las Cumbres Observatory cholt@lco.global