Creating and Using Metrics¶
Metrics are scalar quantities that can be measured and monitored.
validate_drp
is designed to measure metrics from LPM-17, the LSST Science Requirements document.
LPM-17, for example, defines metrics that quantify photometric and astrometric measurement accuracy in the LSST Science Pipelines.
Each metric can be accompanied by several specification levels. Specifications are thresholds of a metric that define success or give some indication of algorithm development progress. LPM-17, for example, defines ‘minimum,’ ‘design,’ and ‘stretch’ specifications for each metric.
This page describes the schema and API for defining and using both metrics and specifications in validate_drp
.
This API can also be adopted by other validation and integration test packages.
A key feature of this API is that metrics and measurements can be submitted directly to the LSST DM quality assurance database and dashboard: SQUASH.
Defining Metrics and Specifications in YAML¶
The best way to define new metrics and specifications is in a metrics.yaml
file embedded in an EUPS package (Git repository).
metrics.yaml
in validate_drp
is a useful example for such a YAML file.
Metric objects in YAML¶
In metrics.yaml
, each metric is a separate key-value object.
For example, here’s the AM1 metric’s definition:
AM1:
reference:
doc: LPM-17
url: http://ls.st/lpm-17
page: 23
description: >
The maximum rms of the astrometric distance distribution for stellar pairs
with separations of D=5 arcmin (repeatability) (milliarcsec).
operator: "<="
dependencies:
- D: {value: 5.0, units: arcmin}
specs:
- level: design
value: 10.0
units: mmag
filters: [r, i]
- level: minimum
value: 20.0
units: mmag
filters: [r, i]
- level: stretch
value: 5.0
units: mmag
filters: [r, i]
Note that the key for this object is the name of the metric itself, ‘AM1.` Within the object are the following fields:
reference
- This field contains a dictionary of key-value pairs that document where this metric is formally defined.
In the AM1 example, the metric is defined in the
doc
‘LPM-17’ onpage
23. The URL of that document is also provided. This metadata is optional, and subsets of thedoc
,page
andurl
fields are allowed. description
- The description field is intended to provide a short summary that defines the metric. Details can be left for the referenced document.
operator
The operator field specifies what binary comparison operator should be used to check that a measurement of a metric fulfills a specification level. Comparisons are always done such that the measurement appears on the left hand side of the operator, while the specification level appears on the right hand side. If the comparison evaluates as true, the measurement passes the specification. The following operators are allowed:
>=
>
<
<=
==
!=
dependencies
Some metrics have specific quantities that measurement code must use. Dependencies are a way of specifying these quantities in a way that measurement classes can easily use. The
dependencies
field is a list of items. Each list item should be a one-itemdict
. The key specifies the name of the dependency (made available as an attribute of theMetric
), while the value is aDatum
with the following possible fields:value
: the scalar value of the dependency (typically a float, int or list/array).units
: anastropy.units
-compatible string describing the units ofvalue
.label
: the short label for this parameter (optional).description
: a sentence or two describing this parameter (optional).
specs
- This field contains a list of specification objects, keyed by the name of the specification.
In the
AM1
example above, specifications are defined for ‘design,’ ‘minimum’ and ‘stretch’ specification levels. The next section describes the schema for these specification YAML objects.
Defining specifications in YAML¶
This section describes the schema for specification objects, which are embedded in the specs
field of metric objects, described above.
First we describe required fields, followed by optional fields to deal with special circumstances.
level
- This field provides the name of the specification. In the LPM-17 Science Requirements Document, levels are one of design, minimum and stretch, which describe a set of algorithmic performance goals. One can define different a different system of levels, or even add a new set of specifications to existing metrics.
value
- This field is the scalar value (float or int) that defines the metric’s threshold level. The specification’s value placed on the right hand side of the metric’s comparison operator when being compared to a measurement.
units
This field annotates the level with units, such as
'mag'
or'arcsec'
. Units are described by astropy.units-compatible strings. See the astropy.units documentation for what units are available.If a value is unitless, such as a fraction or percent, the unit should be an empty string,
''
.
Defining filter-specific specifications¶
In some cases, a specification might be different depending on the optical filter used.
For example, in LPM-17, the PA1 metric has different specification levels for g, r and i filters than u, z and y filters.
This situation is accommodated by creating two separate specification objects for each set of filters.
Then each specification object defines what filters it applies to through a filters
field.
filters
should be an array (list) type, where each value is a string with the filter’s name.
Defining metrics that are dependent on the specification levels of other metrics¶
In LPM-17, some specification levels are dependent on the specification levels of other metrics. For example, PF1 is defined as:
The maximum fraction of magnitudes deviating by more than PA2 from the mean.
In order to measure PF1, we must use the specification levels of PA2 as a parameter of the measurement.
In YAML, we can describe this relationship by including the name of the other metric as a list item in the specification’s dependencies
field.
For example, the PF1 metric is written as:
PF1:
# ...
specs:
- level: design
value: 10.0
units: ''
dependencies:
- PA2
This dependency means that a measurement being compared against the ‘design’ specification of PF1 must use the PA2 ‘design’ specification level as a parameter.
Note that we only need to name the metric itself, the measurement framework will automatically find the equivalent specification in the dependent metric based on matching the level and filter.
Creating Metric Objects in Python¶
Within Python, metrics are represented by instances of the lsst.validate.drp.base.Metric
class.
A metric object is built from a YAML definition with the lsst.validate.drp.base.Metric.fromYaml()
class method.
fromYaml()
takes the metric name and either the path of a metric YAML file (yamlPath
keyword argument) or a pre-parsed YAML object (yamlDoc
keyword argument).
For example:
import os
from lsst.utils import getPackageDir
from lsst.validate.drp.base import Metric
yamlPath = os.path.join(getPackageDir('validate_drp'),
'metrics.yaml')
am1 = Metric.fromYaml('AM1', yamlPath=yamlPath)
Checking a Measurement Against a Specification¶
Ultimately, a metric object is most valuable in validating a measurement against a specification.
For this, use the lsst.validate.drp.base.Metric.checkSpec()
method:
measuredValue = 2. # hypothetical measured value
am1.checkSpec(measuredValue, 'design')
The last statement will return True
if the measured value fulfills the ‘design’ specification.
If a specification is bandpass dependent, the bandpass needs to be passed to the bandpass
keyword argument of checkSpec()
.
In Creating Measurement Classes we describe how to make measurements with the validate_drp
API.
Accessing Specification Objects of a Metric¶
Since some measurements need to know about the specification levels of a metric, metrics provide a getSpec()
method to resolve and retrieve a specification level.
For example:
designSpec = am1.getSpec('design')
If specification levels are bandpass-dependent, the bandpass can be provided with the bandpass
keyword argument.
The properties of a specification are retrieved through attributes:
designSpec.value
designSpec.units
designSpec.label
designSpec.bandpasses
designSpec.latex_units # units marked up as LaTeX math
designSpec.astropy_quanity # value and unit as an Astropy quantity
Dependencies of specification levels can be obtained as attributes corresponding to their labels.
Dependencies themselves are Datum
objects, with a value and units.
For example,
designSpec.d # the distance parameter
designSpec.d.value # value of distance parameter
designSpec.d.units # units of the distance parameter
In Creating Measurement Classes we provide examples of measurements that retrieve dependencies of metrics and their specification levels.