diff --git a/include/lsst/afw/image/ImageSummary.h b/include/lsst/afw/image/ImageSummary.h
new file mode 100644
index 0000000000..25efef8aef
--- /dev/null
+++ b/include/lsst/afw/image/ImageSummary.h
@@ -0,0 +1,86 @@
+// -*- LSST-C++ -*-
+/*
+ * LSST Data Management System
+ * Copyright 2008-2014 LSST Corporation.
+ *
+ * This product includes software developed by the
+ * LSST Project (http://www.lsst.org/).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the LSST License Statement and
+ * the GNU General Public License along with this program. If not,
+ * see .
+ */
+
+#ifndef LSST_AFW_IMAGE_IMAGE_SUMMARY_H_INCLUDED
+#define LSST_AFW_IMAGE_IMAGE_SUMMARY_H_INCLUDED
+
+#include
+
+#include "lsst/afw/table/io/Persistable.h"
+#include "lsst/afw/typehandling/Storable.h"
+#include "lsst/afw/table/BaseRecord.h"
+
+namespace lsst {
+namespace afw {
+namespace image {
+
+/**
+
+ */
+class ImageSummary final : public table::io::PersistableFacade, public typehandling::Storable {
+ using Internal = std::shared_ptr;
+
+public:
+ ImageSummary(table::Schema const&);
+ ImageSummary(ImageSummary const&);
+ ImageSummary(ImageSummary&&) = default;
+ ImageSummary& operator=(ImageSummary const&);
+ ImageSummary& operator=(ImageSummary&&) = default;
+ ~ImageSummary() override = default;
+
+ /// Whether the map is persistable (true IFF all contained BoundedFields are persistable).
+ bool isPersistable() const noexcept override;
+
+ /// Create a new ImageSummary that is a copy of this one.
+ std::shared_ptr cloneStorable() const override;
+
+ table::Schema getSchema() const {
+ return _internal->getSchema();
+ }
+
+ template
+ typename table::Field::Value getKey(table::Key const& key) const {
+ return _internal->get(key);
+ }
+
+ void setBool(std::string const& key, bool value);
+ void setInt64(std::string const& key, std::int64_t value);
+ void setDouble(std::string const& key, double value);
+ void setInternal(table::BaseRecord const & other){
+ _internal->assign(other);
+ }
+
+private:
+ std::string getPersistenceName() const override;
+
+ std::string getPythonModule() const override;
+
+ void write(OutputArchiveHandle& handle) const override;
+
+ Internal _internal;
+};
+} // namespace image
+} // namespace afw
+} // namespace lsst
+
+#endif // !LSST_AFW_IMAGE_IMAGE_SUMMARY_H_INCLUDED
diff --git a/include/lsst/afw/table/BaseRecord.h b/include/lsst/afw/table/BaseRecord.h
index 14f9b91eb1..370077671b 100644
--- a/include/lsst/afw/table/BaseRecord.h
+++ b/include/lsst/afw/table/BaseRecord.h
@@ -80,7 +80,7 @@ class BaseRecord {
Schema getSchema() const { return _table->getSchema(); }
/// Return the table this record is associated with.
- std::shared_ptr getTable() const { return _table; }
+ std::shared_ptr getTable() const { return _table; }
/**
* Return a pointer to the underlying elements of a field (non-const).
diff --git a/python/lsst/afw/image/__init__.py b/python/lsst/afw/image/__init__.py
index 4fb853daf2..c2872489a7 100644
--- a/python/lsst/afw/image/__init__.py
+++ b/python/lsst/afw/image/__init__.py
@@ -21,6 +21,7 @@
from ._imageLib import *
from . import pixel
from ._image import *
+from ._imageSummary import *
from ._apCorrMap import *
from ._maskedImage import *
from ._visitInfo import * # just here to support deprecation
diff --git a/python/lsst/afw/image/_imageLib.cc b/python/lsst/afw/image/_imageLib.cc
index 25937cc897..1f58661ba9 100644
--- a/python/lsst/afw/image/_imageLib.cc
+++ b/python/lsst/afw/image/_imageLib.cc
@@ -35,6 +35,7 @@ void wrapExposure(lsst::utils::python::WrapperCollection &);
void wrapExposureInfo(lsst::utils::python::WrapperCollection &);
void wrapFilterLabel(lsst::utils::python::WrapperCollection &);
void wrapImagePca(lsst::utils::python::WrapperCollection &);
+void wrapImageSummary(lsst::utils::python::WrapperCollection &);
void wrapImageUtils(lsst::utils::python::WrapperCollection &);
void wrapPhotoCalib(lsst::utils::python::WrapperCollection &);
void wrapReaders(lsst::utils::python::WrapperCollection &);
@@ -50,6 +51,7 @@ PYBIND11_MODULE(_imageLib, mod) {
wrapExposureInfo(wrappers);
wrapFilterLabel(wrappers);
wrapImagePca(wrappers);
+ wrapImageSummary(wrappers);
wrapImageUtils(wrappers);
wrapPhotoCalib(wrappers);
wrapReaders(wrappers);
diff --git a/python/lsst/afw/image/_imageSummary.cc b/python/lsst/afw/image/_imageSummary.cc
new file mode 100644
index 0000000000..a8bd33405a
--- /dev/null
+++ b/python/lsst/afw/image/_imageSummary.cc
@@ -0,0 +1,79 @@
+/*
+ * This file is part of afw.
+ *
+ * Developed for the LSST Data Management System.
+ * This product includes software developed by the LSST Project
+ * (https://www.lsst.org).
+ * See the COPYRIGHT file at the top-level directory of this distribution
+ * for details of code ownership.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "pybind11/pybind11.h"
+#include "pybind11/stl.h"
+#include "lsst/utils/python.h"
+
+#include
+#include
+
+#include "lsst/afw/table/io/python.h" // for addPersistableMethods
+#include "lsst/afw/typehandling/Storable.h"
+#include "lsst/afw/image/ImageSummary.h"
+
+namespace py = pybind11;
+using namespace pybind11::literals;
+
+namespace lsst {
+namespace afw {
+namespace image {
+namespace {
+
+using PyImageSummary = py::class_, typehandling::Storable>;
+
+void wrapImageSummary(lsst::utils::python::WrapperCollection &wrappers) {
+ wrappers.wrapType(PyImageSummary(wrappers.module, "ImageSummary"), [](auto &mod, auto &cls) {
+ cls.def(py::init(), "schema"_a);
+ cls.def(py::init(), "imageSummary"_a);
+
+ table::io::python::addPersistableMethods(cls);
+
+ /* Members */
+ cls.def("__setitem__", &ImageSummary::setBool);
+ cls.def("__setitem__", &ImageSummary::setInt64);
+ cls.def("__setitem__", &ImageSummary::setDouble);
+
+ cls.def("__getitem__", [] (ImageSummary const& self, std::string const& key){
+ py::object result;
+ self.getSchema().findAndApply(key, [&self, &key, &result](auto const& item){
+ result = py::cast(self.getKey(item.key));
+ });
+ return result;
+ });
+ });
+}
+
+PYBIND11_MODULE(_imageSummary, mod) {
+ lsst::utils::python::WrapperCollection wrappers(mod, "lsst.afw.image");
+ wrappers.addSignatureDependency("lsst.afw.table"); // for Schema
+ wrappers.addInheritanceDependency("lsst.afw.table.io");
+ wrappers.addInheritanceDependency("lsst.afw.typehandling");
+ wrapImageSummary(wrappers);
+ wrappers.finish();
+ /* Declare CRTP base class. */
+}
+} // namespace
+} // namespace image
+} // namespace afw
+} // namespace lsst
diff --git a/src/image/ImageSummary.cc b/src/image/ImageSummary.cc
new file mode 100644
index 0000000000..309a391029
--- /dev/null
+++ b/src/image/ImageSummary.cc
@@ -0,0 +1,108 @@
+// -*- LSST-C++ -*-
+/*
+ * LSST Data Management System
+ * Copyright 2008-2014 LSST Corporation.
+ *
+ * This product includes software developed by the
+ * LSST Project (http://www.lsst.org/).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the LSST License Statement and
+ * the GNU General Public License along with this program. If not,
+ * see .
+ */
+
+#include
+
+#include "lsst/afw/image/ImageSummary.h"
+#include "lsst/afw/table/io/InputArchive.h"
+#include "lsst/afw/table/io/OutputArchive.h"
+#include "lsst/afw/table/io/CatalogVector.h"
+#include "lsst/afw/table/io/Persistable.cc"
+
+namespace lsst {
+namespace afw {
+
+template std::shared_ptr table::io::PersistableFacade::dynamicCast(
+ std::shared_ptr const&);
+
+namespace image {
+
+ImageSummary::ImageSummary(table::Schema const& schema) {
+ auto tbl = table::BaseTable::make(schema);
+ _internal = tbl->makeRecord();
+}
+
+ImageSummary::ImageSummary(ImageSummary const& other) {
+ _internal = other._internal->getTable()->copyRecord(*other._internal);
+}
+
+ImageSummary& ImageSummary::operator=(ImageSummary const& other) {
+ _internal->assign(*other._internal);
+ return *this;
+}
+
+
+namespace {
+
+class ImageSummaryFactory : public table::io::PersistableFactory {
+public:
+ std::shared_ptr read(InputArchive const& archive,
+ CatalogVector const& catalogs) const override {
+ LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
+ LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
+ std::shared_ptr result = std::make_shared(catalogs.front().getSchema());
+ result->setInternal(catalogs.front().front());
+ return result;
+ }
+
+ ImageSummaryFactory(std::string const& name) : afw::table::io::PersistableFactory(name) {}
+};
+
+std::string getImageSummaryPersistenceName() { return "ImageSummary"; }
+
+ImageSummaryFactory registration(getImageSummaryPersistenceName());
+
+} // namespace
+
+bool ImageSummary::isPersistable() const noexcept {return true;}
+
+std::string ImageSummary::getPersistenceName() const { return getImageSummaryPersistenceName(); }
+
+std::string ImageSummary::getPythonModule() const { return "lsst.afw.image"; }
+
+void ImageSummary::write(OutputArchiveHandle& handle) const {
+ table::BaseCatalog catalog = handle.makeCatalog(_internal->getSchema());
+ std::shared_ptr record = catalog.addNew();
+ record->assign(*_internal);
+ handle.saveCatalog(catalog);
+}
+
+std::shared_ptr ImageSummary::cloneStorable() const {
+ return std::make_unique(*this);
+}
+
+void ImageSummary::setBool(std::string const& key, bool value) {
+ _internal->set(_internal->getSchema().find(key).key, value);
+}
+
+void ImageSummary::setInt64(std::string const& key, std::int64_t value) {
+ _internal->set(_internal->getSchema().find(key).key, value);
+}
+
+void ImageSummary::setDouble(std::string const& key, double value) {
+ _internal->set(_internal->getSchema().find(key).key, value);
+}
+
+} // namespace image
+} // namespace afw
+} // namespace lsst