<commit_before>"""sys_test_adapters.py
Contains classes to wrap Stile systematics tests with functions necessary to run the tests via the
HSC/LSST pipeline.
"""
import lsst.pex.config
from lsst.pex.exceptions import LsstCppException
from .. import sys_tests
import numpy

adapter_registry = lsst.pex.config.makeRegistry("Stile test outputs")


# We need to mask the data to particular object types; these pick out the flags we need to do that.
def MaskGalaxy(data, config):
    """
    Given `data`, an LSST source catalog, return a NumPy boolean array describing which rows
    correspond to galaxies.
    """
    # Will have to be more careful/clever about this when classification.extendedness is continuous.
    # These arrays are generally contiguous in memory--so we can just index them like a NumPy
    # recarray.
    try:
        return data['classification.extendedness']==1
    except LsstCppException:
        # But sometimes we've already masked the array--this will work in that case (but is slower
        # than above if the above is possible).
        key = data.schema.find('classification.extendedness').key
        return numpy.array([src[key]==1 for src in data])

def MaskStar(data, config):
    """
    Given `data`, an LSST source catalog, return a NumPy boolean array describing which rows
    correspond to stars.
    """
    try:
        return data['classification.extendedness']==0
    except LsstCppException:
        key = data.schema.find('classification.extendedness').key
        return numpy.array([src[key]==0 for src in data])

def MaskBrightStar(data, config):
    """
    Given `data`, an LSST source catalog, return a NumPy boolean array describing which rows
    correspond to bright stars according to a given S/N cutoff set by
    `config.bright_star_sn_cutoff`.
    """
    star_mask = MaskStar(data, config)
    key_psf = data.schema.find('flux.psf').key
    key_psf_err = data.schema.find('flux.psf.err').key
    bright_mask = (numpy.array([src[key_psf]/src[key_psf_err] for src in data]) >
                   config.bright_star_sn_cutoff)
    return numpy.logical_and(star_mask, bright_mask)

def MaskPSFStar(data, config):
    """
    Given `data`, an LSST source catalog, return a NumPy boolean array describing which rows
    correspond to the stars used to determine the PSF.
    """
    try:
        return data['calib.psf.used']==True
    except LsstCppException:
        try:
            key = data.schema.find('calib.psf.used').key
        except KeyError:
            key = data.schema.find('calib.psf.used.any').key
        return numpy.array([src.get(key)==True for src in data])

# Map the object type strings onto the above functions.
mask_dict = {'galaxy': MaskGalaxy,
             'galaxy lens': MaskGalaxy,  # should do something different here!
             'star': MaskStar,
             'star bright': MaskBrightStar,
             'star PSF': MaskPSFStar}


class BaseSysTestAdapter(object):
    """
    This is an abstract class, implementing a couple of useful masking and column functions for
    reuse in child classes.

    The basic function of a SysTestAdapter is to wrap a Stile SysTest object in a way that makes it
    easy to use with the LSST drivers found in base_tasks.py.  It should always have: an<commit_msg>Remove PSF stars with shape.sdss.flags (#74)<commit_after>"""sys_test_adapters.py
Contains classes to wrap Stile systematics tests with functions necessary to run the tests via the
HSC/LSST pipeline.
"""
import lsst.pex.config
from lsst.pex.exceptions import LsstCppException
from .. import sys_tests
import numpy

adapter_registry = lsst.pex.config.makeRegistry("Stile test outputs")


# We need to mask the data to particular object types; these pick out the flags we need to do that.
def MaskGalaxy(data, config):
    """
    Given `data`, an LSST source catalog, return a NumPy boolean array describing which rows
    correspond to galaxies.
    """
    # Will have to be more careful/clever about this when classification.extendedness is continuous.
    # These arrays are generally contiguous in memory--so we can just index them like a NumPy
    # recarray.
    try:
        return data['classification.extendedness']==1
    except LsstCppException:
        # But sometimes we've already masked the array--this will work in that case (but is slower
        # than above if the above is possible).
        key = data.schema.find('classification.extendedness').key
        return numpy.array([src[key]==1 for src in data])

def MaskStar(data, config):
    """
    Given `data`, an LSST source catalog, return a NumPy boolean array describing which rows
    correspond to stars.
    """
    try:
        return data['classification.extendedness']==0
    except LsstCppException:
        key = data.schema.find('classification.extendedness').key
        return numpy.array([src[key]==0 for src in data])

def MaskBrightStar(data, config):
    """
    Given `data`, an LSST source catalog, return a NumPy boolean array describing which rows
    correspond to bright stars according to a given S/N cutoff set by
    `config.bright_star_sn_cutoff`.
    """
    star_mask = MaskStar(data, config)
    key_psf = data.schema.find('flux.psf').key
    key_psf_err = data.schema.find('flux.psf.err').key
    bright_mask = (numpy.array([src[key_psf]/src[key_psf_err] for src in data]) >
                   config.bright_star_sn_cutoff)
    return numpy.logical_and(star_mask, bright_mask)

def MaskPSFStar(data, config):
    """
    Given `data`, an LSST source catalog, return a NumPy boolean array describing which rows
    correspond to the stars used to determine the PSF.
    """
    try:
        return data['calib.psf.used']==True
    except LsstCppException:
        try:
            key = data.schema.find('calib.psf.used').key
        except KeyError:
            key = data.schema.find('calib.psf.used.any').key
        key_shape = data.schema.find('shape.sdss.flags').key
        return numpy.logical_and(numpy.array([src.get(key)==True for src in data]), numpy.array([src.get(key_shape)==False for src in data]))

# Map the object type strings onto the above functions.
mask_dict = {'galaxy': MaskGalaxy,
             'galaxy lens': MaskGalaxy,  # should do something different here!
             'star': MaskStar,
             'star bright': MaskBrightStar,
             'star PSF': MaskPSFStar}


class BaseSysTestAdapter(object):
    """
    This is an abstract class, implementing a couple of useful masking and column functions for
    reuse in child classes.

    The basic function of a SysTestAdapter is to wrap a Stile SysTest object in a way that makes it
    easy to use with the LSST drivers found in base_tasks.py.  It should always have: an
{'fraction_non_alphanumeric': 0.08902384831876758, 'fraction_numerical': 0.0014812620352540364, 'mean_word_length': 3.1782178217821784, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '338550', 'n_tokens_mistral': 1975, 'n_tokens_neox': 1905, 'n_words': 699}