From 14bbac54cff2bbaeaed91ed2ae5294f82117fe4b Mon Sep 17 00:00:00 2001 From: fred3m Date: Thu, 4 May 2023 13:09:01 -0700 Subject: [PATCH] Create ImageSummary class --- include/lsst/afw/image/ImageSummary.h | 86 ++++++++++++++++++++ include/lsst/afw/table/BaseRecord.h | 2 +- python/lsst/afw/image/__init__.py | 1 + python/lsst/afw/image/_imageLib.cc | 2 + python/lsst/afw/image/_imageSummary.cc | 79 ++++++++++++++++++ src/image/ImageSummary.cc | 108 +++++++++++++++++++++++++ 6 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 include/lsst/afw/image/ImageSummary.h create mode 100644 python/lsst/afw/image/_imageSummary.cc create mode 100644 src/image/ImageSummary.cc 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