Transient detection and filtering

Transients may be detected either on initial science image as described in Object detection and measurement, or on the difference image after image subtraction. For the latter, you may also make use of a difference image noise model, as returned by stdpipe.subtraction.run_hotpants() with get_noise=True - it will reduce the amount of subtraction artefacts at the position of brighter objects.

# Get PSF model of and store it to temporary file
psf_model = psf.run_psfex(image, mask=mask, order=0, gain=gain, psffile='/tmp/psf.psf', verbose=True)

# Run SExtractor on difference image with custom noise model,
# using both image and template masks for masking
sobj = photometry.get_objects_sextractor(diff, mask=mask|tmask, err=ediff,
             edge=10, wcs=wcs, aper=5.0, psf='/tmp/psf.psf', verbose=True)

# Perform forced aperture photometry in a circular aperture with 1.0*FWHM radius,
# measuring local backround in an annulus between 5.0*FWHM and 7.0*FWHM,
# and again with custom noise model and forced to zero global background level
sobj = photometry.measure_objects(sobj, diff, mask=mask|tmask, fwhm=fwhm, aper=1.0, bkgann=[5, 7],
             sn=3, verbose=True, bg=0, err=ediff)

# The difference is in original image normalization, so we know photometric zero point
sobj['mag_calib'] = sobj['mag'] + m['zero_fn'](sobj['x'], sobj['y'])
sobj['mag_calib_err'] = np.hypot(sobj['magerr'], m['zero_fn'](sobj['x'], sobj['y'], get_err=True))

# We may immediately reject flagged objects as they correspond to imaging artefacts (masked regions)
sobj = sobj[sobj['flags'] == 0]

print(len(sobj), 'transient candidates found in difference image')

The transient candidates detected by such a routine will require some filtering in order to reject the subtraction artefacts, probably filter out known variable stars and maybe catalogued stars, also filter out known minor planets, etc. We have a convenience high-level routine stdpipe.pipeline.filter_transient_candidates() that uses a number of lower-level ones (stdpipe.catalogs.xmatch_objects(), stdpipe.catalogs.xmatch_skybot(), stdpipe.catalogs.xmatch_ned()). High-level routine is able to either filter out the “bad” objects from the list of candidates, or just mark the ones that should be rejected for various reasons (if remove=False).

# Filter out all candidates that match the objects from Pan-STARRS DR1 or AAVSO VSX catalogues
# Also filter out all Solar System minor planets known to IMCCE SkyBoT service
# Also, filter out all entries having flags 0x100 or 0x200 (thus, corresponding to objects
# with masked pixels in their footprints
candidates = pipeline.filter_transient_candidates(sobj, sr=2/3600,
             flagged=True, vizier=['ps1', 'vsx'], skybot=True, time=time, verbose=True)

# ...or, we may do the same without removing the candidates:
candidates = pipeline.filter_transient_candidates(sobj, sr=2/3600, remove=False,
             flagged=True, vizier=['ps1', 'vsx'], skybot=True, time=time, verbose=True)
# and remove them later manually
candidates = candidates[candidates['candidate_good']==True]

# and now just print all the remaining candidates
for i,cand in enumerate(candidates):
     print('Candidate %d with mag = %.2f +/- %.2f at x/y = %.1f %.1d and RA/Dec = %.4f %.4f' %
             (i, cand['mag_calib'], cand['mag_calib_err'], cand['x'], cand['y'], cand['ra'], cand['dec']))
stdpipe.pipeline.filter_transient_candidates(obj, sr=None, pixscale=None, fwhm=None, time=None, obj_col_ra='ra', obj_col_dec='dec', cat=None, cat_col_ra='RAJ2000', cat_col_dec='DEJ2000', vizier=[], skybot=True, ned=False, flagged=True, flagmask=32512, col_id=None, vizier_checker_fn=None, get_candidates=True, remove=True, verbose=False)[source]

Higher-level transient candidate filtering routine.

Optionally filters out the following classes of objects:

  • flagged ones (obj['flags'] != 0)

  • positionally coincident with stars from a provided reference catalogue

  • positionally coincident with stars from Vizier catalogues

  • positionally and temporally coincident with Solar System objects from SkyBoT

  • positionally and temporally coincident with NED objects

The original object list is never modified; a filtered or annotated copy is returned.

If get_candidates=False, returns only a boolean mask of objects surviving all filters. If get_candidates=True and remove=False, all objects are returned but annotated with candidate_* columns indicating which filters matched each object, plus a candidate_good column that is True for objects surviving all filters.

Parameters:
objastropy.table.Table

Input object list.

srfloat, optional

Matching radius in degrees. Defaults to half FWHM (if pixscale is set) or 1 arcsec.

pixscalefloat, optional

Pixel scale in degrees/pixel. Used to compute the default matching radius.

fwhmfloat, optional

FWHM in pixels. Estimated from unflagged objects if not provided.

timeastropy.time.Time or datetime.datetime, optional

Observation time; required for SkyBoT cross-matching.

obj_col_rastr, optional

Column name for object Right Ascension.

obj_col_decstr, optional

Column name for object Declination.

catastropy.table.Table, optional

Reference catalogue for spatial cross-matching.

cat_col_rastr, optional

Column name for catalogue Right Ascension.

cat_col_decstr, optional

Column name for catalogue Declination.

vizierlist of str, optional

Vizier catalogue identifiers (or short names) to cross-match against.

skybotbool, optional

If True, cross-match with SkyBoT Solar System object positions.

nedbool, optional

If True, cross-match with NED database entries.

flaggedbool, optional

If True, filter out objects where (obj['flags'] & flagmask) != 0.

flagmaskint, optional

Bitmask applied to obj['flags'] for flag filtering.

col_idstr, optional

Column name for a unique object identifier. A stdpipe_id column is created automatically if not specified.

vizier_checker_fncallable, optional

Function fn(obj, xcat, catname) -> bool array to apply additional conditions on Vizier cross-matches before they are considered true matches.

get_candidatesbool, optional

If True (default), return the filtered/annotated object list. If False, return only a boolean mask over the original list.

removebool, optional

If True (default), remove filtered entries from the returned list. If False, keep all objects and add candidate_* annotation columns.

verbosebool or callable, optional

Whether to show verbose messages. May be boolean or a print-like callable.

Returns:
astropy.table.Table or ndarray of bool

Filtered/annotated copy of the object list, or (if get_candidates=False) a boolean mask of the same length as the input.