Skip to content

Commit

Permalink
Merge pull request #126 from lsst/tickets/DM-15244
Browse files Browse the repository at this point in the history
DM-15244: Change fluxSigma to fluxErr and similarly for apCorr and covariances
  • Loading branch information
r-owen committed Aug 7, 2018
2 parents fd796ef + 20268ce commit 6fe5e6a
Show file tree
Hide file tree
Showing 28 changed files with 217 additions and 216 deletions.
14 changes: 7 additions & 7 deletions include/lsst/meas/base/CentroidUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ namespace base {
struct CentroidResult {
CentroidElement x; ///< x (column) coordinate of the measured position
CentroidElement y; ///< y (row) coordinate of the measured position
ErrElement xSigma; ///< 1-Sigma uncertainty on x (sqrt of variance)
ErrElement ySigma; ///< 1-Sigma uncertainty on y (sqrt of variance)
ErrElement xErr; ///< standard deviation of x
ErrElement yErr; ///< standard deviation of y
ErrElement x_y_Cov; ///< x,y term in the uncertainty convariance matrix

/// Constructor; initializes everything to NaN.
Expand All @@ -52,13 +52,13 @@ struct CentroidResult {
explicit CentroidResult(CentroidElement x_, CentroidElement y_, CentroidCov const& matrix)
: x(x_),
y(y_),
xSigma(std::sqrt(matrix(0, 0))),
ySigma(std::sqrt(matrix(1, 1))),
xErr(std::sqrt(matrix(0, 0))),
yErr(std::sqrt(matrix(1, 1))),
x_y_Cov(matrix(0, 1)) {}

/// Constructor; initializes everything from values.
explicit CentroidResult(CentroidElement x_, CentroidElement y_, ErrElement xSigma_, ErrElement ySigma_)
: x(x_), y(y_), xSigma(xSigma_), ySigma(ySigma_), x_y_Cov(0.0) {}
explicit CentroidResult(CentroidElement x_, CentroidElement y_, ErrElement xErr_, ErrElement yErr_)
: x(x_), y(y_), xErr(xErr_), yErr(yErr_), x_y_Cov(0.0) {}

/// Return a Point object containing the measured x and y
Centroid const getCentroid() const;
Expand All @@ -76,7 +76,7 @@ struct CentroidResult {
void setCentroidErr(CentroidCov const& matrix);

/// Set the struct uncertainty fields from the sigma values
void setCentroidErr(ErrElement _xSigma, ErrElement _ySigma);
void setCentroidErr(ErrElement _xErr, ErrElement _yErr);
};

/**
Expand Down
34 changes: 17 additions & 17 deletions include/lsst/meas/base/FluxUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ namespace base {
*/
struct FluxResult {
Flux flux; ///< Measured flux in DN.
FluxErrElement fluxSigma; ///< 1-Sigma error (sqrt of variance) on flux in DN.
FluxErrElement fluxErr; ///< Standard deviation of flux in DN.

/// Default constructor; initializes everything to NaN.
FluxResult();

/// Constructor from flux and its uncertainty
explicit FluxResult(Flux flux_, FluxErrElement fluxSigma_) : flux(flux_), fluxSigma(fluxSigma_) {}
explicit FluxResult(Flux flux_, FluxErrElement fluxErr_) : flux(flux_), fluxErr(fluxErr_) {}
};

/**
Expand All @@ -58,10 +58,10 @@ struct FluxResult {
class FluxResultKey : public afw::table::FunctorKey<FluxResult> {
public:
/**
* Add a pair of _flux, _fluxSigma fields to a Schema, and return a FluxResultKey that points to them.
* Add a pair of _flux, _fluxErr fields to a Schema, and return a FluxResultKey that points to them.
*
* @param[in,out] schema Schema to add fields to.
* @param[in] name Name prefix for all fields; "_flux", "_fluxSigma" will be appended to this
* @param[in] name Name prefix for all fields; "_flux", "_fluxErr" will be appended to this
* to form the full field names.
* @param[in] doc String used as the documentation for the fields.
*
Expand All @@ -71,23 +71,23 @@ class FluxResultKey : public afw::table::FunctorKey<FluxResult> {
std::string const& doc);

/// Default constructor; instance will not be usuable unless subsequently assigned to.
FluxResultKey() : _flux(), _fluxSigma() {}
FluxResultKey() : _flux(), _fluxErr() {}

/// Construct from a pair of Keys
FluxResultKey(afw::table::Key<meas::base::Flux> const& flux, // namespace qualification to unconfuse swig
afw::table::Key<FluxErrElement> const& fluxSigma)
: _flux(flux), _fluxSigma(fluxSigma) {}
afw::table::Key<FluxErrElement> const& fluxErr)
: _flux(flux), _fluxErr(fluxErr) {}

/**
* @brief Construct from a subschema, assuming flux and fluxSigma subfields
* @brief Construct from a subschema, assuming flux and fluxErr subfields
*
* If a schema has "a_flux" and "a_fluxSigma" fields, this constructor allows you to construct
* If a schema has "a_flux" and "a_fluxErr" fields, this constructor allows you to construct
* a FluxResultKey via:
* @code
* FluxResultKey k(schema["a"]);
* @endcode
*/
FluxResultKey(afw::table::SubSchema const& s) : _flux(s["flux"]), _fluxSigma(s["fluxSigma"]) {}
FluxResultKey(afw::table::SubSchema const& s) : _flux(s["flux"]), _fluxErr(s["fluxErr"]) {}

/// Get a FluxResult from the given record
virtual FluxResult get(afw::table::BaseRecord const& record) const;
Expand All @@ -96,25 +96,25 @@ class FluxResultKey : public afw::table::FunctorKey<FluxResult> {
virtual void set(afw::table::BaseRecord& record, FluxResult const& other) const;

//@{
/// Compare the FunctorKey for equality with another, using the underlying flux and fluxSigma Keys
/// Compare the FunctorKey for equality with another, using the underlying flux and fluxErr Keys
bool operator==(FluxResultKey const& other) const {
return _flux == other._flux && _fluxSigma == other._fluxSigma;
return _flux == other._flux && _fluxErr == other._fluxErr;
}
bool operator!=(FluxResultKey const& other) const { return !(*this == other); }
//@}

/// Return True if both the flux and fluxSigma Keys are valid.
bool isValid() const { return _flux.isValid() && _fluxSigma.isValid(); }
/// Return True if both the flux and fluxErr Keys are valid.
bool isValid() const { return _flux.isValid() && _fluxErr.isValid(); }

/// Return the underlying flux Key
afw::table::Key<meas::base::Flux> getFlux() const { return _flux; }

/// Return the underlying fluxSigma Key
afw::table::Key<FluxErrElement> getFluxSigma() const { return _fluxSigma; }
/// Return the underlying fluxErr Key
afw::table::Key<FluxErrElement> getFluxErr() const { return _fluxErr; }

private:
afw::table::Key<Flux> _flux;
afw::table::Key<FluxErrElement> _fluxSigma;
afw::table::Key<FluxErrElement> _fluxErr;
};

/**
Expand Down
35 changes: 18 additions & 17 deletions include/lsst/meas/base/ShapeUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ namespace base {
* obfuscate the results of the measurement (i.e. use this one unless you have a good reason not to).
*/
struct ShapeResult {
ShapeElement xx; // image or model second moment for x^2
ShapeElement yy; // image or model second moment for y^2
ShapeElement xy; // image or model second moment for xy^2
ErrElement xxSigma; ///< 1-Sigma uncertainty on xx (sqrt of variance)
ErrElement yySigma; ///< 1-Sigma uncertainty on yy (sqrt of variance)
ErrElement xySigma; ///< 1-Sigma uncertainty on xy (sqrt of variance)
ShapeElement xx; ///< image or model second moment for x^2
ShapeElement yy; ///< image or model second moment for y^2
ShapeElement xy; ///< image or model second moment for xy^2
ErrElement xxErr; ///< standard deviation of xx
ErrElement yyErr; ///< standard deviation of yy
ErrElement xyErr; ///< standard deviation of xy
ErrElement xx_yy_Cov; ///< xx,yy term in the uncertainty convariance matrix
ErrElement xx_xy_Cov; ///< xx,xy term in the uncertainty convariance matrix
ErrElement yy_xy_Cov; ///< yy,xy term in the uncertainty convariance matrix
Expand All @@ -59,22 +59,22 @@ struct ShapeResult {
: xx(xx_),
yy(yy_),
xy(xy_),
xxSigma(std::sqrt(matrix(0, 0))),
yySigma(std::sqrt(matrix(1, 1))),
xySigma(std::sqrt(matrix(2, 2))),
xxErr(std::sqrt(matrix(0, 0))),
yyErr(std::sqrt(matrix(1, 1))),
xyErr(std::sqrt(matrix(2, 2))),
xx_yy_Cov(matrix(0, 1)),
xx_xy_Cov(matrix(0, 2)),
yy_xy_Cov(matrix(1, 2)) {}

/// Constructor; initializes everything from values.
explicit ShapeResult(ShapeElement xx_, ShapeElement yy_, ShapeElement xy_, ErrElement xxSigma_,
ErrElement yySigma_, ErrElement xySigma_)
explicit ShapeResult(ShapeElement xx_, ShapeElement yy_, ShapeElement xy_, ErrElement xxErr_,
ErrElement yyErr_, ErrElement xyErr_)
: xx(xx_),
yy(yy_),
xy(xy_),
xxSigma(xxSigma_),
yySigma(yySigma_),
xySigma(xySigma_),
xxErr(xxErr_),
yyErr(yyErr_),
xyErr(xyErr_),
xx_yy_Cov(0.0),
xx_xy_Cov(0.0),
yy_xy_Cov(0.0) {}
Expand All @@ -96,11 +96,12 @@ struct ShapeResult {
/// Return the 3x3 symmetric covariance matrix, with rows and columns ordered (xx, yy, xy)
ShapeCov const getShapeErr() const;

/// Set the struct uncertainty elements from the given matrix, with rows and columns ordered (xx, yy, xy)
/// Set the struct standard deviation elements from the given matrix,
/// with rows and columns ordered (xx, yy, xy)
void setShapeErr(ShapeCov const& matrix);

/// Set the struct uncertainty elements from the given values
void setShapeErr(ErrElement xxSigma, ErrElement yySigma, ErrElement xySigma);
/// Set the struct standard deviation elements from the given values
void setShapeErr(ErrElement xxErr, ErrElement yyErr, ErrElement xyErr);
};

/**
Expand Down
4 changes: 2 additions & 2 deletions python/lsst/meas/base/apCorrRegistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ def addApCorrName(name):
"""!Add to the set of field name prefixes for fluxes that should be aperture corrected
@param[in] name field name prefix for a flux that should be aperture corrected.
The corresponding field names are {name}_flux, {name}_fluxSigma and {name}_flag.
The corresponding field names are {name}_flux, {name}_fluxErr and {name}_flag.
For example name "base_PsfFlux" corresponds to fields base_PsfFlux_flux,
base_PsfFlux_fluxSigma and base_PsfFlux_flag.
base_PsfFlux_fluxErr and base_PsfFlux_flag.
"""
global _ApCorrNameSet
_ApCorrNameSet.add(str(name))
Expand Down
64 changes: 32 additions & 32 deletions python/lsst/meas/base/applyApCorr.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
# that over-estimates flux error (often grossly so) because it double-counts photon noise.
# This flag is intended to be temporary until we figure out a better way to compute
# the effects of aperture correction on flux uncertainty
UseNaiveFluxSigma = True
UseNaiveFluxErr = True

__all__ = ("ApplyApCorrConfig", "ApplyApCorrTask")

Expand All @@ -55,11 +55,11 @@ def __init__(self, schema, model, name=None):
@param[in,out] schema source catalog schema;
three fields are used to generate keys:
- {name}_flux
- {name}_fluxSigma
- {name}_fluxErr
- {name}_flag
three fields are added:
- {name}_apCorr (only if not already added by proxy)
- {name}_apCorrSigma (only if not already added by proxy)
- {name}_apCorrFlux (only if not already added by proxy)
- {name}_flag_apCorr
@param[in] model field name prefix for flux with aperture correction model, e.g. "base_PsfFlux"
@param[in] name field name prefix for flux needing aperture correction; may be None if it's the
Expand All @@ -68,27 +68,27 @@ def __init__(self, schema, model, name=None):
ApCorrInfo has the following attributes:
- name: field name prefix for flux needing aperture correction
- modelName: field name for aperture correction model for flux
- modelSigmaName: field name for aperture correction model for fluxSigma
- modelSigmaName: field name for aperture correction model for fluxErr
- doApCorrColumn: should we write the aperture correction values? (not if they're already being
written by a proxy)
- fluxName: name of flux field
- fluxSigmaName: name of flux sigma field
- fluxErrName: name of flux sigma field
- fluxKey: key to flux field
- fluxSigmaKey: key to flux sigma field
- fluxErrKey: key to flux sigma field
- fluxFlagKey: key to flux flag field
- apCorrKey: key to new aperture correction field
- apCorrSigmaKey: key to new aperture correction sigma field
- apCorrFluxKey: key to new aperture correction sigma field
- apCorrFlagKey: key to new aperture correction flag field
"""
if name is None:
name = model
self.name = name
self.modelName = model + "_flux"
self.modelSigmaName = model + "_fluxSigma"
self.modelSigmaName = model + "_fluxErr"
self.fluxName = name + "_flux"
self.fluxSigmaName = name + "_fluxSigma"
self.fluxErrName = name + "_fluxErr"
self.fluxKey = schema.find(self.fluxName).key
self.fluxSigmaKey = schema.find(self.fluxSigmaName).key
self.fluxErrKey = schema.find(self.fluxErrName).key
self.fluxFlagKey = schema.find(name + "_flag").key

# No need to write the same aperture corrections multiple times
Expand All @@ -99,17 +99,17 @@ def __init__(self, schema, model, name=None):
doc="aperture correction applied to %s" % (name,),
type=np.float64,
)
self.apCorrSigmaKey = schema.addField(
name + "_apCorrSigma",
self.apCorrFluxKey = schema.addField(
name + "_apCorrFlux",
doc="aperture correction applied to %s" % (name,),
type=np.float64,
)
else:
aliases = schema.getAliasMap()
aliases.set(name + "_apCorr", model + "_apCorr")
aliases.set(name + "_apCorrSigma", model + "_apCorrSigma")
aliases.set(name + "_apCorrFlux", model + "_apCorrFlux")
self.apCorrKey = schema.find(name + "_apCorr").key
self.apCorrSigmaKey = schema.find(name + "_apCorrSigma").key
self.apCorrFluxKey = schema.find(name + "_apCorrFlux").key

self.apCorrFlagKey = schema.addField(
name + "_flag_apCorr",
Expand Down Expand Up @@ -184,17 +184,17 @@ def run(self, catalog, apCorrMap):
aperture correction.
"""
self.log.info("Applying aperture corrections to %d flux fields", len(self.apCorrInfoDict))
if UseNaiveFluxSigma:
if UseNaiveFluxErr:
self.log.debug("Use naive flux sigma computation")
else:
self.log.debug("Use complex flux sigma computation that double-counts photon noise "
"and thus over-estimates flux uncertainty")
for apCorrInfo in self.apCorrInfoDict.values():
apCorrModel = apCorrMap.get(apCorrInfo.modelName)
apCorrSigmaModel = apCorrMap.get(apCorrInfo.modelSigmaName)
if None in (apCorrModel, apCorrSigmaModel):
apCorrFluxModel = apCorrMap.get(apCorrInfo.modelSigmaName)
if None in (apCorrModel, apCorrFluxModel):
missingNames = [(apCorrInfo.modelName, apCorrInfo.modelSigmaName)[i]
for i, model in enumerate((apCorrModel, apCorrSigmaModel)) if model is None]
for i, model in enumerate((apCorrModel, apCorrFluxModel)) if model is None]
self.log.warn("Cannot aperture correct %s because could not find %s in apCorrMap" %
(apCorrInfo.name, " or ".join(missingNames),))
for source in catalog:
Expand All @@ -211,39 +211,39 @@ def run(self, catalog, apCorrMap):
source.set(apCorrInfo.fluxFlagKey, True)

apCorr = 1.0
apCorrSigma = 0.0
apCorrFlux = 0.0
try:
apCorr = apCorrModel.evaluate(center)
if not UseNaiveFluxSigma:
apCorrSigma = apCorrSigmaModel.evaluate(center)
if not UseNaiveFluxErr:
apCorrFlux = apCorrFluxModel.evaluate(center)
except lsst.pex.exceptions.DomainError:
continue

if apCorrInfo.doApCorrColumn:
source.set(apCorrInfo.apCorrKey, apCorr)
source.set(apCorrInfo.apCorrSigmaKey, apCorrSigma)
source.set(apCorrInfo.apCorrFluxKey, apCorrFlux)

if apCorr <= 0.0 or apCorrSigma < 0.0:
if apCorr <= 0.0 or apCorrFlux < 0.0:
continue

flux = source.get(apCorrInfo.fluxKey)
fluxSigma = source.get(apCorrInfo.fluxSigmaKey)
fluxErr = source.get(apCorrInfo.fluxErrKey)
source.set(apCorrInfo.fluxKey, flux*apCorr)
if UseNaiveFluxSigma:
source.set(apCorrInfo.fluxSigmaKey, fluxSigma*apCorr)
if UseNaiveFluxErr:
source.set(apCorrInfo.fluxErrKey, fluxErr*apCorr)
else:
a = fluxSigma/flux
b = apCorrSigma/apCorr
source.set(apCorrInfo.fluxSigmaKey, abs(flux*apCorr)*math.sqrt(a*a + b*b))
a = fluxErr/flux
b = apCorrFlux/apCorr
source.set(apCorrInfo.fluxErrKey, abs(flux*apCorr)*math.sqrt(a*a + b*b))
source.set(apCorrInfo.apCorrFlagKey, False)
if self.config.doFlagApCorrFailures:
source.set(apCorrInfo.fluxFlagKey, oldFluxFlagState)

if self.log.getLevel() <= self.log.DEBUG:
# log statistics on the effects of aperture correction
apCorrArr = np.array([s.get(apCorrInfo.apCorrKey) for s in catalog])
apCorrSigmaArr = np.array([s.get(apCorrInfo.apCorrSigmaKey) for s in catalog])
apCorrFluxArr = np.array([s.get(apCorrInfo.apCorrFluxKey) for s in catalog])
self.log.debug("For flux field %r: mean apCorr=%s, stdDev apCorr=%s, "
"mean apCorrSigma=%s, stdDev apCorrSigma=%s for %s sources",
"mean apCorrFlux=%s, stdDev apCorrFlux=%s for %s sources",
apCorrInfo.name, apCorrArr.mean(), apCorrArr.std(),
apCorrSigmaArr.mean(), apCorrSigmaArr.std(), len(catalog))
apCorrFluxArr.mean(), apCorrFluxArr.std(), len(catalog))
12 changes: 6 additions & 6 deletions python/lsst/meas/base/centroidUtilities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ void declareCentroidResult(py::module &mod) {

cls.def_readwrite("x", &CentroidResult::x);
cls.def_readwrite("y", &CentroidResult::y);
cls.def_readwrite("xSigma", &CentroidResult::xSigma);
cls.def_readwrite("ySigma", &CentroidResult::ySigma);
cls.def_readwrite("xErr", &CentroidResult::xErr);
cls.def_readwrite("yErr", &CentroidResult::yErr);
cls.def_readwrite("x_y_Cov", &CentroidResult::x_y_Cov);

cls.def(py::init<>());
cls.def(py::init<CentroidElement, CentroidElement, CentroidCov const &>(), "x"_a, "y"_a, "matrix"_a);
cls.def(py::init<CentroidElement, CentroidElement, ErrElement, ErrElement>(), "x"_a, "y"_a, "xSigma"_a,
"ySigma"_a);
cls.def(py::init<CentroidElement, CentroidElement, ErrElement, ErrElement>(), "x"_a, "y"_a, "xErr"_a,
"yErr"_a);

cls.def("getCentroid", &CentroidResult::getCentroid);
cls.def("setCentroid", &CentroidResult::setCentroid, "centroid"_a);
Expand All @@ -64,8 +64,8 @@ void declareCentroidResult(py::module &mod) {
cls.def("setCentroidErr",
(void (CentroidResult::*)(CentroidCov const &)) & CentroidResult::setCentroidErr, "matrix"_a);
cls.def("setCentroidErr",
(void (CentroidResult::*)(ErrElement, ErrElement)) & CentroidResult::setCentroidErr, "xSigma"_a,
"ySigma"_a);
(void (CentroidResult::*)(ErrElement, ErrElement)) & CentroidResult::setCentroidErr, "xErr"_a,
"yErr"_a);
}

void declareCentroidResultKey(py::module &mod) {
Expand Down

0 comments on commit 6fe5e6a

Please sign in to comment.