LSSTApplications  21.0.0+1b62c9342b,21.0.0+45a059f35e,21.0.0-1-ga51b5d4+ceb9cf20a3,21.0.0-10-g68cce58c5+c7d3cce47e,21.0.0-2-g103fe59+c1ca725317,21.0.0-2-g1367e85+a1c2f7fe71,21.0.0-2-g2909d54+45a059f35e,21.0.0-2-g45278ab+1b62c9342b,21.0.0-2-g4bc9b9f+b2e40a4e47,21.0.0-2-g5242d73+a1c2f7fe71,21.0.0-2-g54e2caa+c00cf99ed0,21.0.0-2-g66bcc37+27b9d7859a,21.0.0-2-g7f82c8f+203cf74700,21.0.0-2-g8dde007+b0df52bfdd,21.0.0-2-g8f08a60+73884b2cf5,21.0.0-2-ga326454+203cf74700,21.0.0-2-ga63a54e+eec04437aa,21.0.0-2-gc738bc1+59028256f4,21.0.0-2-gde069b7+5a8f2956b8,21.0.0-2-ge17e5af+a1c2f7fe71,21.0.0-2-ge712728+9ad031c87e,21.0.0-2-gecfae73+d3766aec80,21.0.0-2-gfc62afb+a1c2f7fe71,21.0.0-20-g4449a12+38dfb87bce,21.0.0-22-gf0532904+afb8e7912b,21.0.0-3-g4c5b185+a403cb96fd,21.0.0-3-g6d51c4a+27b9d7859a,21.0.0-3-g8076721+e873df194c,21.0.0-3-gaa929c8+df5d87f43a,21.0.0-3-gd222c45+afc8332dbe,21.0.0-4-g1383c07+27b9d7859a,21.0.0-4-g3300ddd+1b62c9342b,21.0.0-4-g5873dc9+9a92674037,21.0.0-4-g8a80011+f67daf2f53,21.0.0-5-gcff38f6+bce43c5818,21.0.0-6-g463d161+44134145d4,21.0.0-6-gd3283ba+df5d87f43a,21.0.0-8-g19111d86+d6551531e4,w.2021.04
LSSTDataManagementBasePackage
python.h
Go to the documentation of this file.
1 /*
2  * This file is part of afw.
3  *
4  * Developed for the LSST Data Management System.
5  * This product includes software developed by the LSST Project
6  * (https://www.lsst.org).
7  * See the COPYRIGHT file at the top-level directory of this distribution
8  * for details of code ownership.
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <https://www.gnu.org/licenses/>.
22  */
23 
24 #ifndef LSST_AFW_TYPEHANDLING_PYTHON_H
25 #define LSST_AFW_TYPEHANDLING_PYTHON_H
26 
27 #include "pybind11/pybind11.h"
28 
29 #include <string>
30 
36 
37 namespace lsst {
38 namespace afw {
39 namespace typehandling {
40 
53 template <class Base = Storable>
54 class StorableHelper : public Base {
55 public:
56  using Base::Base;
57 
70  template<typename... Args>
71  explicit StorableHelper<Base>(Args... args) : Base(args...) {}
72 
74  /* __deepcopy__ takes an optional dict, but PYBIND11_OVERLOAD_* won't
75  * compile unless you give it arguments that work for the C++ method
76  */
77  PYBIND11_OVERLOAD_NAME(std::shared_ptr<Storable>, Base, "__deepcopy__", cloneStorable, );
78  }
79 
80  std::string toString() const override {
81  PYBIND11_OVERLOAD_NAME(std::string, Base, "__repr__", toString, );
82  }
83 
84  std::size_t hash_value() const override {
85  PYBIND11_OVERLOAD_NAME(std::size_t, Base, "__hash__", hash_value, );
86  }
87 
88  bool equals(Storable const& other) const noexcept override {
89  PYBIND11_OVERLOAD_NAME(bool, Base, "__eq__", equals, other);
90  }
91 
92  bool isPersistable() const noexcept override {
93  PYBIND11_OVERLOAD(
94  bool, Base, isPersistable
95  );
96  }
97 
98  std::string getPersistenceName() const override {
99  PYBIND11_OVERLOAD_NAME(
100  std::string, Base, "_getPersistenceName", getPersistenceName
101  );
102  }
103 
104  std::string getPythonModule() const override {
105  PYBIND11_OVERLOAD_NAME(
106  std::string, Base, "_getPythonModule", getPythonModule
107  );
108  }
109 
110  void write(table::io::OutputArchiveHandle& handle) const override;
111 };
112 
113 std::string declareGenericMapRestrictions(std::string const& className, std::string const& keyName);
114 
130 namespace {
131 
132 class StorableHelperPersistenceHelper {
133 public:
134  table::Schema schema;
135  table::Key<table::Array<std::uint8_t>> bytes;
136 
137  static StorableHelperPersistenceHelper const &get() {
138  static StorableHelperPersistenceHelper instance;
139  return instance;
140  }
141 
142  // No copying
143  StorableHelperPersistenceHelper(StorableHelperPersistenceHelper const &) = delete;
144  StorableHelperPersistenceHelper &operator=(StorableHelperPersistenceHelper const &) = delete;
145 
146  // No moving
147  StorableHelperPersistenceHelper(StorableHelperPersistenceHelper &&) = delete;
148  StorableHelperPersistenceHelper &operator=(StorableHelperPersistenceHelper &&) = delete;
149 
150 private:
151  StorableHelperPersistenceHelper() :
152  schema(),
153  bytes(schema.addField<table::Array<std::uint8_t>>(
154  "bytes", "an opaque bytestring representation of a Storable", ""
155  ))
156  {}
157 };
158 
159 
160 class StorableHelperFactory : public table::io::PersistableFactory {
161 public:
162  StorableHelperFactory(std::string const &module, std::string const &name) :
163  table::io::PersistableFactory(name),
164  _module(module),
165  _name(name)
166  {}
167 
169  InputArchive const &archive,
170  CatalogVector const &catalogs
171  ) const override {
172  pybind11::gil_scoped_acquire gil;
173  auto const &keys = StorableHelperPersistenceHelper::get();
174  LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
175  LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
176  LSST_ARCHIVE_ASSERT(catalogs.front().getSchema() == keys.schema);
177  auto const &record = catalogs.front().front();
178  std::string stringRep = formatters::bytesToString(record.get(keys.bytes));
179  auto cls = pybind11::module::import(_module.c_str()).attr(_name.c_str());
180  auto pyobj = cls.attr("_read")(pybind11::bytes(stringRep));
181  return pyobj.cast<std::shared_ptr<Storable>>();
182  }
183 
184 private:
185  std::string _module;
186  std::string _name;
187 };
188 
189 } // namespace
190 
191 
192 template <typename Base>
194  pybind11::gil_scoped_acquire gil;
195  pybind11::function overload = pybind11::get_overload(static_cast<const Base *>(this), "_write");
196  if (!overload)
197  throw std::runtime_error("Cannot find StorableHelper _write overload");
198  auto o = overload().cast<std::string>();
199  auto const &keys = StorableHelperPersistenceHelper::get();
200  table::BaseCatalog cat = handle.makeCatalog(keys.schema);
202  record->set(keys.bytes, formatters::stringToBytes(o));
203  handle.saveCatalog(cat);
204 }
205 
206 } // namespace typehandling
207 } // namespace afw
208 } // namespace lsst
209 
210 #endif
lsst::afw::typehandling::declareGenericMapRestrictions
std::string declareGenericMapRestrictions(std::string const &className, std::string const &keyName)
Definition: python.cc:32
std::string
STL class.
std::shared_ptr
STL class.
lsst::meas::algorithms.psfSelectionFromMatchList.args
list args
Definition: psfSelectionFromMatchList.py:27
bytes
table::Key< table::Array< std::uint8_t > > bytes
Definition: python.h:135
lsst::afw::typehandling::StorableHelper::equals
bool equals(Storable const &other) const noexcept override
Compare this object to another Storable.
Definition: python.h:88
lsst::afw::typehandling::StorableHelper::getPersistenceName
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
Definition: python.h:98
Utils.h
lsst::afw::table::io::OutputArchiveHandle
An object passed to Persistable::write to allow it to persist itself.
Definition: OutputArchive.h:118
lsst::afw::typehandling::StorableHelper::hash_value
std::size_t hash_value() const override
Return a hash of this object (optional operation).
Definition: python.h:84
lsst::afw::table::io::OutputArchiveHandle::saveCatalog
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
Definition: OutputArchive.cc:211
lsst::afw
Definition: imageAlgorithm.dox:1
lsst::afw::typehandling::StorableHelper::getPythonModule
std::string getPythonModule() const override
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
Definition: python.h:104
astshim.keyMap.keyMapContinued.keys
def keys(self)
Definition: keyMapContinued.py:6
Persistable.cc
lsst::afw::typehandling::StorableHelper::write
void write(table::io::OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Definition: python.h:193
CatalogVector.h
lsst::afw::typehandling::Storable
Interface supporting iteration over heterogenous containers.
Definition: Storable.h:58
lsst::afw::geom.transform.transformContinued.name
string name
Definition: transformContinued.py:32
lsst::afw::typehandling::StorableHelper::toString
std::string toString() const override
Create a string representation of this object (optional operation).
Definition: python.h:80
lsst::afw::geom.transform.transformContinued.cls
cls
Definition: transformContinued.py:33
lsst::afw::table::io::OutputArchiveHandle::makeCatalog
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
Definition: OutputArchive.cc:207
lsst::afw::formatters::bytesToString
std::string bytesToString(ndarray::Array< std::uint8_t const, 1, 1 > const &bytes)
Decode a std::string from a vector of uint8 returned by stringToBytes.
Definition: Utils.cc:173
lsst::afw::typehandling::StorableHelper::cloneStorable
std::shared_ptr< Storable > cloneStorable() const override
Create a new object that is a copy of this one (optional operation).
Definition: python.h:73
std::string::c_str
T c_str(T... args)
other
ItemVariant const * other
Definition: Schema.cc:56
schema
table::Schema schema
Definition: python.h:134
std::runtime_error
STL class.
Storable.h
lsst::afw::typehandling::StorableHelper::isPersistable
bool isPersistable() const noexcept override
Return true if this particular object can be persisted using afw::table::io.
Definition: python.h:92
lsst
A base class for image defects.
Definition: imageAlgorithm.dox:1
lsst::afw::formatters::stringToBytes
ndarray::Array< std::uint8_t, 1, 1 > stringToBytes(std::string const &str)
Encode a std::string as a vector of uint8.
Definition: Utils.cc:162
std
STL namespace.
std::size_t
lsst::afw::table::CatalogT::addNew
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
Definition: Catalog.h:485
lsst::afw::typehandling::StorableHelper
"Trampoline" for Storable to let it be used as a base class in Python.
Definition: python.h:54
lsst::afw::table::CatalogT< BaseRecord >
LSST_ARCHIVE_ASSERT
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.h:48
lsst::meas::modelfit.psf.psfContinued.module
module
Definition: psfContinued.py:42
OutputArchive.h