skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
wentorai/research-plugins129 installs

astrophysics-data-guide

Astronomical data processing with Astropy, FITS files, and sky surveys

How do I install this agent skill?

npx skills add https://github.com/wentorai/research-plugins --skill physics-skills
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    The physics-skills package is a comprehensive collection of educational resources and code samples for astrophysics, particle physics, quantum computing, and computational physics. It utilizes established scientific libraries and provides guidance for interacting with official research databases like the NASA Astrophysics Data System (ADS) using secure credential management practices. No malicious behaviors, obfuscation, or security vulnerabilities were detected.

  • Socketpass

    No alerts

  • Snykpass

    Risk: LOW · No issues

What does this agent skill do?

Astrophysics Data Guide

A skill for processing and analyzing astronomical data using standard astrophysics tools. Covers FITS file handling, coordinate transformations, photometric analysis, spectral analysis, catalog cross-matching, and accessing major sky survey archives.

Astronomical Data Formats

FITS Files

FITS (Flexible Image Transport System) is the standard data format in astronomy:

from astropy.io import fits
import numpy as np

def inspect_fits(filepath: str) -> dict:
    """
    Inspect the structure of a FITS file.
    Returns information about each HDU (Header/Data Unit).
    """
    with fits.open(filepath) as hdul:
        info = []
        for i, hdu in enumerate(hdul):
            entry = {
                "index": i,
                "name": hdu.name,
                "type": type(hdu).__name__,
            }
            if hdu.data is not None:
                entry["shape"] = hdu.data.shape
                entry["dtype"] = str(hdu.data.dtype)
            if hasattr(hdu, "columns") and hdu.columns is not None:
                entry["columns"] = [c.name for c in hdu.columns]
            info.append(entry)
        return {"filename": filepath, "n_hdus": len(hdul), "hdus": info}

def read_fits_image(filepath: str, hdu_index: int = 0) -> tuple:
    """Read a FITS image and its WCS (World Coordinate System)."""
    from astropy.wcs import WCS

    with fits.open(filepath) as hdul:
        data = hdul[hdu_index].data
        header = hdul[hdu_index].header
        wcs = WCS(header)

    return data, wcs, header

Working with FITS Tables

from astropy.table import Table

def read_fits_catalog(filepath: str, hdu: int = 1) -> Table:
    """Read a FITS binary table extension as an Astropy Table."""
    catalog = Table.read(filepath, hdu=hdu)
    print(f"Catalog: {len(catalog)} objects, {len(catalog.columns)} columns")
    print(f"Columns: {catalog.colnames}")
    return catalog

Coordinate Systems

Astronomical Coordinate Transformations

from astropy.coordinates import SkyCoord, EarthLocation, AltAz
from astropy.time import Time
import astropy.units as u

def coordinate_transforms(ra_deg: float, dec_deg: float) -> dict:
    """
    Transform between astronomical coordinate systems.
    ra_deg, dec_deg: right ascension and declination in degrees (ICRS/J2000)
    """
    coord = SkyCoord(ra=ra_deg * u.degree, dec=dec_deg * u.degree, frame="icrs")

    return {
        "icrs": {
            "ra": coord.ra.to_string(unit=u.hourangle, precision=2),
            "dec": coord.dec.to_string(unit=u.degree, precision=2),
        },
        "galactic": {
            "l": round(coord.galactic.l.degree, 4),
            "b": round(coord.galactic.b.degree, 4),
        },
        "ecliptic": {
            "lon": round(coord.geocentricmeanecliptic.lon.degree, 4),
            "lat": round(coord.geocentricmeanecliptic.lat.degree, 4),
        },
    }

def compute_altaz(ra_deg: float, dec_deg: float,
                   obs_time: str, location: tuple) -> dict:
    """
    Compute altitude and azimuth for a target from a given location and time.
    location: (latitude_deg, longitude_deg, elevation_m)
    """
    target = SkyCoord(ra=ra_deg * u.degree, dec=dec_deg * u.degree)
    time = Time(obs_time)
    loc = EarthLocation(
        lat=location[0] * u.degree,
        lon=location[1] * u.degree,
        height=location[2] * u.m,
    )
    altaz_frame = AltAz(obstime=time, location=loc)
    altaz = target.transform_to(altaz_frame)

    return {
        "altitude_deg": round(altaz.alt.degree, 2),
        "azimuth_deg": round(altaz.az.degree, 2),
        "airmass": round(altaz.secz.value, 3) if altaz.alt.degree > 0 else None,
        "is_observable": altaz.alt.degree > 10,
    }

Photometric Analysis

Aperture Photometry

from photutils.aperture import CircularAperture, CircularAnnulus
from photutils.aperture import aperture_photometry

def perform_aperture_photometry(image: np.ndarray,
                                  positions: list[tuple],
                                  aperture_radius: float = 5.0,
                                  annulus_inner: float = 10.0,
                                  annulus_outer: float = 15.0) -> list[dict]:
    """
    Perform aperture photometry with local background subtraction.
    image: 2D numpy array (flux/counts)
    positions: list of (x, y) pixel coordinates of sources
    """
    apertures = CircularAperture(positions, r=aperture_radius)
    annuli = CircularAnnulus(positions, r_in=annulus_inner, r_out=annulus_outer)

    # Measure flux in aperture and annulus
    phot_table = aperture_photometry(image, [apertures, annuli])

    results = []
    for row in phot_table:
        # Background per pixel from annulus
        annulus_area = np.pi * (annulus_outer**2 - annulus_inner**2)
        bkg_per_pixel = row["aperture_sum_1"] / annulus_area

        # Background-subtracted flux
        aperture_area = np.pi * aperture_radius**2
        net_flux = row["aperture_sum_0"] - bkg_per_pixel * aperture_area

        # Instrumental magnitude
        if net_flux > 0:
            inst_mag = -2.5 * np.log10(net_flux)
        else:
            inst_mag = float("nan")

        results.append({
            "x": float(row["xcenter"]),
            "y": float(row["ycenter"]),
            "raw_flux": float(row["aperture_sum_0"]),
            "net_flux": round(float(net_flux), 2),
            "bkg_per_pixel": round(float(bkg_per_pixel), 2),
            "inst_mag": round(inst_mag, 4),
        })

    return results

Source Detection

from photutils.detection import DAOStarFinder
from astropy.stats import sigma_clipped_stats

def detect_sources(image: np.ndarray, fwhm: float = 3.0,
                    threshold_sigma: float = 5.0) -> Table:
    """
    Detect point sources in an astronomical image using DAOFind algorithm.
    """
    mean, median, std = sigma_clipped_stats(image, sigma=3.0)
    daofind = DAOStarFinder(fwhm=fwhm, threshold=threshold_sigma * std)
    sources = daofind(image - median)

    if sources is not None:
        sources.sort("flux", reverse=True)
        print(f"Detected {len(sources)} sources")
    return sources

Spectral Analysis

Processing 1D Spectra

from specutils import Spectrum1D, SpectralRegion
from specutils.analysis import line_flux, equivalent_width, centroid
import astropy.units as u

def analyze_spectrum(wavelength: np.ndarray,
                      flux: np.ndarray,
                      line_center: float,
                      line_width: float = 10.0) -> dict:
    """
    Analyze an emission or absorption line in a 1D spectrum.
    wavelength: array in Angstroms
    flux: array in erg/s/cm2/Angstrom
    line_center: expected line center in Angstroms
    line_width: width of spectral region to analyze
    """
    spectrum = Spectrum1D(
        spectral_axis=wavelength * u.Angstrom,
        flux=flux * u.Unit("erg / (s cm2 Angstrom)"),
    )

    region = SpectralRegion(
        (line_center - line_width) * u.Angstrom,
        (line_center + line_width) * u.Angstrom,
    )

    measured_flux = line_flux(spectrum, regions=region)
    ew = equivalent_width(spectrum, regions=region)
    center = centroid(spectrum, region)

    # Redshift from line center offset
    rest_wavelength = line_center  # assumed rest frame
    z = (center.value - rest_wavelength) / rest_wavelength

    return {
        "line_flux": f"{measured_flux:.4e}",
        "equivalent_width": f"{ew:.2f}",
        "measured_center_A": round(center.value, 2),
        "redshift": round(z, 6),
        "velocity_km_s": round(z * 299792.458, 1),
    }

Survey Data Access

Querying Major Archives

from astroquery.vizier import Vizier
from astroquery.simbad import Simbad
from astroquery.sdss import SDSS

def query_simbad(object_name: str) -> dict:
    """Query SIMBAD for basic object information."""
    result = Simbad.query_object(object_name)
    if result is None:
        return {"found": False}

    return {
        "found": True,
        "name": object_name,
        "ra": str(result["RA"][0]),
        "dec": str(result["DEC"][0]),
        "object_type": str(result["OTYPE"][0]),
    }

def cone_search_vizier(ra_deg: float, dec_deg: float,
                        radius_arcmin: float = 1.0,
                        catalog: str = "II/246") -> Table:
    """
    Cone search in a VizieR catalog.
    Default catalog II/246 = 2MASS Point Source Catalog.
    """
    coord = SkyCoord(ra=ra_deg * u.degree, dec=dec_deg * u.degree)
    result = Vizier.query_region(
        coord, radius=radius_arcmin * u.arcmin, catalog=catalog
    )
    return result[0] if result else None

Key Sky Surveys

SurveyBandCoverageResolutionKey Science
SDSSugriz14,555 sq deg1.3"Galaxy evolution, QSOs
2MASSJHKAll-sky2"Stellar populations, MW structure
WISE3.4-22 umAll-sky6-12"Brown dwarfs, AGN, dusty galaxies
Gaia DR3G, BP, RPAll-sky0.1 masAstrometry, stellar parameters
DESISpectroscopic14,000 sq degFiberDark energy, BAO
JWST0.6-28 umPointed0.03-0.1"Early universe, exoplanets

Tools and Software

  • Astropy: Core Python library for astronomy (coordinates, FITS, tables, units)
  • photutils: Photometry tools (detection, aperture/PSF photometry)
  • specutils: Spectral analysis (line fitting, equivalent widths)
  • astroquery: Unified interface to astronomical databases
  • reproject: Image reprojection between WCS frames
  • ccdproc: CCD image reduction pipeline
  • SAOImageDS9: Interactive FITS image viewer
  • TOPCAT: Interactive catalog cross-matching and visualization

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/wentorai/research-plugins/physics-skills">View astrophysics-data-guide on skillZs</a>