LSSTApplications  16.0+42,16.0-1-gce273f5+8,16.0-10-g230e10e+1,16.0-11-g9fe0e56+17,16.0-11-gce733cf+17,16.0-12-g5ad1ebf+9,16.0-12-gc85596e+2,16.0-13-gde155d7+2,16.0-14-g9428de4d,16.0-14-gc1cf4a94+2,16.0-15-g8e16a51+14,16.0-2-g0febb12+7,16.0-2-g839ba83+32,16.0-2-g9d5294e+22,16.0-2-gab3db49+7,16.0-2-gf41ba6b+6,16.0-2-gf4e7cdd+5,16.0-3-g6923fb6+15,16.0-3-g8e51203+2,16.0-3-g9645794+6,16.0-3-gcfd6c53+20,16.0-35-g34c7dfe62+1,16.0-4-g03cf288+11,16.0-4-g32d12de,16.0-4-g5f3a788+7,16.0-4-g7690030+30,16.0-4-g8a0f11a+16,16.0-4-ga5d8928+16,16.0-5-g0da18be+7,16.0-5-g4940a70,16.0-5-g563880a+2,16.0-5-g7742071+2,16.0-5-gb3f8a4b+26,16.0-6-g3610b4f+5,16.0-6-gf0acd13+14,16.0-8-g4dec96c+7,16.0-8-gc315727+16,16.0-9-g1de645c+7,16.0-9-gcc4efb7+6,w.2018.36
LSSTDataManagementBasePackage
ImageFormatter.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
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 LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
25 /*
26  * Implementation of ImageFormatter class
27  */
28 
29 #ifndef __GNUC__
30 #define __attribute__(x) /*NOTHING*/
31 #endif
32 static char const* SVNid __attribute__((unused)) = "$Id$";
33 
34 #include <cstdint>
35 #include <memory>
36 #include <string>
37 #include "boost/serialization/shared_ptr.hpp"
38 #include "boost/serialization/binary_object.hpp"
39 #include "boost/serialization/nvp.hpp"
40 
41 #include <boost/archive/text_oarchive.hpp>
42 #include <boost/archive/text_iarchive.hpp>
43 #include <boost/archive/binary_oarchive.hpp>
44 #include <boost/archive/binary_iarchive.hpp>
45 
46 #include "lsst/daf/base.h"
47 #include "lsst/daf/persistence.h"
48 #include "lsst/log/Log.h"
50 #include "lsst/afw/image/Image.h"
51 #include "lsst/afw/fits.h"
52 
53 namespace {
54 LOG_LOGGER _log = LOG_GET("afw.ImageFormatter");
55 }
56 
57 using boost::serialization::make_nvp;
64 
65 namespace afwImg = lsst::afw::image;
66 
67 namespace lsst {
68 namespace afw {
69 namespace formatters {
70 
71 template <typename ImagePixelT>
73 public:
74  static std::string name();
75 };
76 
77 template <>
79  static std::string name = "ImageU";
80  return name;
81 }
82 template <>
84  static std::string name = "ImageI";
85  return name;
86 }
87 template <>
89  static std::string name = "ImageF";
90  return name;
91 }
92 template <>
94  static std::string name = "ImageD";
95  return name;
96 }
97 template <>
99  static std::string name = "ImageL";
100  return name;
101 }
102 
103 template <typename ImagePixelT>
106 
107 template <typename ImagePixelT>
109  : lsst::daf::persistence::Formatter(typeid(this)) {}
110 
111 template <typename ImagePixelT>
113 
114 namespace {
115 namespace dafBase = lsst::daf::base;
116 namespace afwImage = lsst::afw::image;
117 } // namespace
118 
119 template <typename ImagePixelT>
123  LOGL_DEBUG(_log, "ImageFormatter write start");
124  Image<ImagePixelT> const* ip = dynamic_cast<Image<ImagePixelT> const*>(persistable);
125  if (ip == 0) {
126  throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError, "Persisting non-Image");
127  }
128  // TODO: Replace this with something better in DM-10776
130  if (boost) {
131  LOGL_DEBUG(_log, "ImageFormatter write BoostStorage");
132  boost->getOArchive() & *ip;
133  LOGL_DEBUG(_log, "ImageFormatter write end");
134  return;
135  }
136  auto xml = std::dynamic_pointer_cast<XmlStorage>(storage);
137  if (xml) {
138  LOGL_DEBUG(_log, "ImageFormatter write XmlStorage");
139  xml->getOArchive() & make_nvp("img", *ip);
140  LOGL_DEBUG(_log, "ImageFormatter write end");
141  return;
142  }
143  auto fits = std::dynamic_pointer_cast<FitsStorage>(storage);
144  if (fits) {
145  LOGL_DEBUG(_log, "ImageFormatter write FitsStorage");
146 
148  if (additionalData) {
149  try {
150  options = fits::ImageWriteOptions(*additionalData->getAsPropertySetPtr("image"));
151  } catch (std::exception const& exc) {
152  LOGLS_WARN(_log, "Unable to construct image write options ("
153  << exc.what() << "); writing with default options");
154  }
155  }
156 
157  ip->writeFits(fits->getPath(), options);
158  // @todo Do something with these fields?
159  // int _X0;
160  // int _Y0;
161  LOGL_DEBUG(_log, "ImageFormatter write end");
162  return;
163  }
164  throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError, "Unrecognized FormatterStorage for Image");
165 }
166 
167 template <typename ImagePixelT>
170  LOGL_DEBUG(_log, "ImageFormatter read start");
171  // TODO: Replace this with something better in DM-10776
173  if (boost) {
174  LOGL_DEBUG(_log, "ImageFormatter read BoostStorage");
176  boost->getIArchive() & *ip;
177  LOGL_DEBUG(_log, "ImageFormatter read end");
178  return ip;
179  }
180  auto xml = std::dynamic_pointer_cast<XmlStorage>(storage);
181  if (xml) {
182  LOGL_DEBUG(_log, "ImageFormatter read XmlStorage");
184  xml->getIArchive() & make_nvp("img", *ip);
185  LOGL_DEBUG(_log, "ImageFormatter read end");
186  return ip;
187  }
188  auto fits = std::dynamic_pointer_cast<FitsStorage>(storage);
189  if (fits) {
190  LOGL_DEBUG(_log, "ImageFormatter read FitsStorage");
192  if (additionalData->exists("llcX")) {
193  int llcX = additionalData->get<int>("llcX");
194  int llcY = additionalData->get<int>("llcY");
195  int width = additionalData->get<int>("width");
196  int height = additionalData->get<int>("height");
197  box = lsst::geom::Box2I(lsst::geom::Point2I(llcX, llcY), lsst::geom::Extent2I(width, height));
198  }
200  if (additionalData->exists("imageOrigin")) {
201  std::string originStr = additionalData->get<std::string>("imageOrigin");
202  if (originStr == "LOCAL") {
203  origin = afwImg::LOCAL;
204  } else if (originStr == "PARENT") {
205  origin = afwImg::PARENT;
206  } else {
208  (boost::format("Unknown ImageOrigin type %s specified in additional"
209  "data for retrieving Image from fits") %
210  originStr)
211  .str());
212  }
213  }
215 
216  Image<ImagePixelT>* ip =
217  new Image<ImagePixelT>(fits->getPath(), fits->getHdu(),
219  // @note We're throwing away the metadata
220  // @todo Do something with these fields?
221  // int _X0;
222  // int _Y0;
223  LOGL_DEBUG(_log, "ImageFormatter read end");
224  return ip;
225  }
226  throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError, "Unrecognized FormatterStorage for Image");
227 }
228 
229 template <typename ImagePixelT>
232  throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError, "Unexpected call to update for Image");
233 }
234 
235 template <typename ImagePixelT>
236 template <class Archive>
238  LOGL_DEBUG(_log, "ImageFormatter delegateSerialize start");
239  Image<ImagePixelT>* ip = dynamic_cast<Image<ImagePixelT>*>(persistable);
240  if (ip == 0) {
241  throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError, "Serializing non-Image");
242  }
243  int width, height;
244  if (Archive::is_saving::value) {
245  width = ip->getWidth();
246  height = ip->getHeight();
247  }
248  ar& make_nvp("width", width) & make_nvp("height", height);
249  if (Archive::is_loading::value) {
251  typename Image<ImagePixelT>::Array array = ni->getArray();
252  ar& make_nvp("array", boost::serialization::make_array(array.getData(), array.getNumElements()));
253  ip->swap(*ni);
254  } else {
255  ndarray::Array<ImagePixelT, 2, 2> array = ndarray::dynamic_dimension_cast<2>(ip->getArray());
256  if (array.empty()) array = ndarray::copy(ip->getArray());
257  ar& make_nvp("array", boost::serialization::make_array(array.getData(), array.getNumElements()));
258  }
259 }
260 
261 template <typename ImagePixelT>
265 }
266 
267 #define InstantiateFormatter(ImagePixelT) \
268  template class ImageFormatter<ImagePixelT>; \
269  template void ImageFormatter<ImagePixelT>::delegateSerialize(boost::archive::text_oarchive&, int const, \
270  Persistable*); \
271  template void ImageFormatter<ImagePixelT>::delegateSerialize(boost::archive::text_iarchive&, int const, \
272  Persistable*); \
273  template void ImageFormatter<ImagePixelT>::delegateSerialize(boost::archive::xml_oarchive&, int const, \
274  Persistable*); \
275  template void ImageFormatter<ImagePixelT>::delegateSerialize(boost::archive::xml_iarchive&, int const, \
276  Persistable*); \
277  template void ImageFormatter<ImagePixelT>::delegateSerialize(boost::archive::binary_oarchive&, \
278  int const, Persistable*); \
279  template void ImageFormatter<ImagePixelT>::delegateSerialize(boost::archive::binary_iarchive&, \
280  int const, Persistable*);
281 
284 InstantiateFormatter(float);
285 InstantiateFormatter(double);
287 
288 #undef InstantiateSerializer
289 } // namespace formatters
290 } // namespace afw
291 } // namespace lsst
#define LOGLS_WARN(logger, message)
Log a warn-level message using an iostream-based interface.
Definition: Log.h:657
Abstract base class for FormatterStorage implementations.
#define LOG_LOGGER
Definition: Log.h:712
Class for XML file storage.
Definition: XmlStorage.h:58
Definition: Span.h:36
void write(lsst::daf::base::Persistable const *persistable, std::shared_ptr< lsst::daf::persistence::FormatterStorage > storage, std::shared_ptr< lsst::daf::base::PropertySet > additionalData) override
int getHeight() const
Return the number of rows in the image.
Definition: ImageBase.h:321
Options for writing an image to FITS.
Definition: fits.h:218
lsst::daf::base::Persistable * read(std::shared_ptr< lsst::daf::persistence::FormatterStorage > storage, std::shared_ptr< lsst::daf::base::PropertySet > additionalData) override
#define __attribute__(x)
void writeFits(std::string const &fileName, std::shared_ptr< lsst::daf::base::PropertySet const > metadata=std::shared_ptr< lsst::daf::base::PropertySet const >(), std::string const &mode="w") const
Write an image to a regular FITS file.
tuple options
Definition: lsstimport.py:47
static void delegateSerialize(Archive &ar, int const version, lsst::daf::base::Persistable *persistable)
Construct a static instance of this helper class to register a Formatter subclass in the FormatterReg...
Definition: Formatter.h:138
Class for FITS file storage.
Definition: FitsStorage.h:52
daf_persistence package header file
#define LOGL_DEBUG(logger, message...)
Log a debug-level message using a varargs/printf style interface.
Definition: Log.h:513
Fits * fits
Definition: FitsWriter.cc:90
STL class.
LSST DM logging module built on log4cxx.
A base class for image defects.
Definition: cameraGeom.dox:3
T what(T... args)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:129
void update(lsst::daf::base::Persistable *persistable, std::shared_ptr< lsst::daf::persistence::FormatterStorage > storage, std::shared_ptr< lsst::daf::base::PropertySet > additionalData) override
#define InstantiateFormatter(ImagePixelT)
T dynamic_pointer_cast(T... args)
Class implementing persistence and retrieval for Images.
Abstract base class for all formatters.
Definition: Formatter.h:79
STL class.
T get(T... args)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:47
STL class.
static std::shared_ptr< lsst::daf::persistence::Formatter > createInstance(std::shared_ptr< lsst::pex::policy::Policy > policy)
int getWidth() const
Return the number of columns in the image.
Definition: ImageBase.h:319
afw::table::Key< afw::table::Array< ImagePixelT > > image
Class for boost::serialization storage.
Definition: BoostStorage.h:59
Base class for all persistable classes.
Definition: Persistable.h:73
#define LOG_GET(logger)
Returns a Log object associated with logger.
Definition: Log.h:83
An integer coordinate rectangle.
Definition: Box.h:54
void swap(Image &rhs)
Definition: Image.cc:466
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:67
ImageFormatter(ImageFormatter const &)=default
Reports errors that are due to events beyond the control of the program.
Definition: Runtime.h:104