LSSTApplications  11.0-22-g33de520,13.0+153,14.0+52,14.0+57,14.0-1-g013352c+36,14.0-1-g13ef843+9,14.0-1-g4b114ac+14,14.0-1-g7257b6a+12,14.0-1-g8b7e855+51,14.0-13-g7a60b79+2,14.0-14-g87d16e8+10,14.0-14-gbf7a6f8a,14.0-17-g4f4ea82+5,14.0-2-g319577b+11,14.0-2-ga5af9b6+10,14.0-22-gc48c03f+3,14.0-3-g20413be+3,14.0-46-g76222d5f+3,14.0-47-g0a51fac97,14.0-5-g744ff5f+2,14.0-5-g86eb1bd+31,14.0-6-gd5b81a9+6,14.0-6-ge2c9487+42,14.0-8-g7f6dd6b+6,14.0-8-gb81b6e9+4,14.0-9-g11010eb,14.0-9-g330837b+5
LSSTDataManagementBasePackage
TanWcsFormatter.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 TanWcsFormatter class
27  */
28 
29 #ifndef __GNUC__
30 #define __attribute__(x) /*NOTHING*/
31 #endif
32 static char const* SVNid __attribute__((unused)) = "$Id$";
33 
34 #include <string>
35 
36 //#include "boost/serialization/shared_ptr.hpp"
37 #include <boost/archive/binary_iarchive.hpp>
38 #include <boost/archive/binary_oarchive.hpp>
39 #include <boost/archive/text_iarchive.hpp>
40 #include <boost/archive/text_oarchive.hpp>
41 
42 #include "wcslib/wcs.h"
43 
44 #include "lsst/daf/base.h"
45 #include "lsst/daf/persistence.h"
47 #include "lsst/pex/exceptions.h"
48 #include "lsst/log/Log.h"
52 #include "lsst/afw/image/TanWcs.h"
53 #include "lsst/afw/fits.h"
54 
55 namespace {
56 LOG_LOGGER _log = LOG_GET("afw.TanWcsFormatter");
57 }
58 
59 namespace lsst {
60 namespace afw {
61 namespace formatters {
62 
63 namespace dafBase = lsst::daf::base;
65 namespace pexPolicy = lsst::pex::policy;
67 
69  createInstance);
70 
72 
77 
79 
83  LOGL_DEBUG(_log, "TamWcsFormatter write start");
84  image::TanWcs const* ip = dynamic_cast<image::TanWcs const*>(persistable);
85  if (ip == 0) {
86  throw LSST_EXCEPT(pexExcept::RuntimeError, "Persisting non-TanWcs");
87  }
88  // TODO: Replace this with something better in DM-10776
90  if (boost) {
91  LOGL_DEBUG(_log, "TanWcsFormatter write BoostStorage");
92  boost->getOArchive() & *ip;
93  LOGL_DEBUG(_log, "TanWcsFormatter write end");
94  return;
95  }
96  throw LSST_EXCEPT(pexExcept::RuntimeError, "Unrecognized FormatterStorage for TanWcs");
97 }
98 
100  std::shared_ptr<dafBase::PropertySet> additionalData) {
101  LOGL_DEBUG(_log, "TanWcsFormatter read start");
102  // TODO: Replace this with something better in DM-10776
104  if (boost) {
105  image::TanWcs* ip = new image::TanWcs;
106  LOGL_DEBUG(_log, "TanWcsFormatter read BoostStorage");
107  boost->getIArchive() & *ip;
108  LOGL_DEBUG(_log, "TanWcsFormatter read end");
109  return ip;
110  }
112  if (fits) {
113  LOGL_DEBUG(_log, "TanWcsFormatter read FitsStorage");
114  int hdu = additionalData->get<int>("hdu", fits::DEFAULT_HDU);
116  image::TanWcs* ip = new image::TanWcs(md);
117  LOGL_DEBUG(_log, "TanWcsFormatter read end");
118  return ip;
119  }
120  throw LSST_EXCEPT(pexExcept::RuntimeError, "Unrecognized FormatterStorage for TanWcs");
121 }
122 
125  throw LSST_EXCEPT(pexExcept::RuntimeError, "Unexpected call to update for TanWcs");
126 }
127 
129 template <class Archive>
130 void serializeEigenArray(Archive& ar, Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>& m) {
131  int rows = m.rows();
132  int cols = m.cols();
133  ar& rows& cols;
134  if (Archive::is_loading::value) {
135  m = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>(rows, cols);
136  }
137  for (int j = 0; j < m.cols(); ++j) {
138  for (int i = 0; i < m.rows(); ++i) {
139  ar& m(i, j);
140  }
141  }
142 }
143 
144 static void encodeSipHeader(std::shared_ptr<daf::base::PropertySet> wcsProps,
145  std::string const& which,
146  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> const& m) {
147  int order = m.rows();
148  if (m.cols() != order) {
149  throw LSST_EXCEPT(pexExcept::DomainError, "sip" + which + " matrix is not square");
150  }
151  if (order > 0) {
152  order -= 1; // match SIP convention
153  wcsProps->add(which + "_ORDER", static_cast<int>(order));
154  for (int i = 0; i <= order; ++i) {
155  for (int j = 0; j <= order; ++j) {
156  double val = m(i, j);
157  if (val != 0.0) {
158  wcsProps->add((boost::format("%1%_%2%_%3%") % which % i % j).str(), val);
159  }
160  }
161  }
162  }
163 }
164 
166  // Only generates properties for the first wcsInfo.
168 
169  if (wcs._wcsInfo == NULL) { // nothing to add
170  return wcsProps;
171  }
172 
173  wcsProps->add("NAXIS", wcs._wcsInfo[0].naxis, "number of data axes");
174  // EQUINOX is "not relevant" (FITS definition, version 3.0, page 30) when
175  // dealing with ICRS, and may confuse readers. Don't write it.
176  if (strncmp(wcs._wcsInfo[0].radesys, "ICRS", 4) != 0) {
177  wcsProps->add("EQUINOX", wcs._wcsInfo[0].equinox, "Equinox of coordinates");
178  }
179  wcsProps->add("RADESYS", std::string(wcs._wcsInfo[0].radesys), "Coordinate system for equinox");
180  wcsProps->add("CRPIX1", wcs._wcsInfo[0].crpix[0], "WCS Coordinate reference pixel");
181  wcsProps->add("CRPIX2", wcs._wcsInfo[0].crpix[1], "WCS Coordinate reference pixel");
182  wcsProps->add("CD1_1", wcs._wcsInfo[0].cd[0], "WCS Coordinate scale matrix");
183  wcsProps->add("CD1_2", wcs._wcsInfo[0].cd[1], "WCS Coordinate scale matrix");
184  wcsProps->add("CD2_1", wcs._wcsInfo[0].cd[2], "WCS Coordinate scale matrix");
185  wcsProps->add("CD2_2", wcs._wcsInfo[0].cd[3], "WCS Coordinate scale matrix");
186  wcsProps->add("CRVAL1", wcs._wcsInfo[0].crval[0], "WCS Ref value (RA in decimal degrees)");
187  wcsProps->add("CRVAL2", wcs._wcsInfo[0].crval[1], "WCS Ref value (DEC in decimal degrees)");
188  wcsProps->add("CUNIT1", std::string(wcs._wcsInfo[0].cunit[0]));
189  wcsProps->add("CUNIT2", std::string(wcs._wcsInfo[0].cunit[1]));
190 
191  // Hack. Because wcslib4.3 gets confused when it's passed RA---TAN-SIP,
192  // we set the value of ctypes to just RA---TAN, regardless of whether
193  // the SIP types are present. But when we persist to a file, we need to
194  // check whether the SIP polynomials were actually there and correct
195  // ctypes if necessary. Bad things will happen if someone tries to
196  // use a system other than RA---TAN and DEC--TAN
197  std::string ctype1(wcs._wcsInfo[0].ctype[0]);
198  std::string ctype2(wcs._wcsInfo[0].ctype[1]);
199 
200  if (wcs._hasDistortion) {
201  if (ctype1.rfind("-SIP") == std::string::npos) {
202  ctype1 += "-SIP";
203  }
204  if (ctype2.rfind("-SIP") == std::string::npos) {
205  ctype2 += "-SIP";
206  }
207  encodeSipHeader(wcsProps, "A", wcs._sipA);
208  encodeSipHeader(wcsProps, "B", wcs._sipB);
209  encodeSipHeader(wcsProps, "AP", wcs._sipAp);
210  encodeSipHeader(wcsProps, "BP", wcs._sipBp);
211  }
212  wcsProps->add("CTYPE1", ctype1, "WCS Coordinate type");
213  wcsProps->add("CTYPE2", ctype2, "WCS Coordinate type");
214 
215  return wcsProps;
216 }
217 
218 template <class Archive>
220  LOGL_DEBUG(_log, "TanWcsFormatter delegateSerialize start");
221  image::TanWcs* ip = dynamic_cast<image::TanWcs*>(persistable);
222  if (ip == 0) {
223  throw LSST_EXCEPT(pexExcept::RuntimeError, "Serializing non-TanWcs");
224  }
225 
226  // Serialize most fields normally
227  ar & ip->_nWcsInfo & ip->_relax;
228  ar & ip->_wcsfixCtrl & ip->_wcshdrCtrl & ip->_nReject;
229  ar & ip->_coordSystem;
230 
231  ar & ip->_hasDistortion;
232 
233  if (ip->_hasDistortion) {
234  serializeEigenArray(ar, ip->_sipA);
235  serializeEigenArray(ar, ip->_sipAp);
236  serializeEigenArray(ar, ip->_sipB);
237  serializeEigenArray(ar, ip->_sipBp);
238  }
239 
240  // If we are loading, create the array of Wcs parameter structs
241  if (Archive::is_loading::value) {
242  ip->_wcsInfo = reinterpret_cast<wcsprm*>(malloc(ip->_nWcsInfo * sizeof(wcsprm)));
243  }
244 
245  for (int i = 0; i < ip->_nWcsInfo; ++i) {
246  // If we are loading, initialize the struct first
247  if (Archive::is_loading::value) {
248  ip->_wcsInfo[i].flag = -1;
249  wcsini(1, 2, &(ip->_wcsInfo[i]));
250  }
251 
252  // Serialize only critical Wcs parameters
253  ar & ip->_wcsInfo[i].naxis;
254  ar & ip->_wcsInfo[i].equinox;
255  ar & ip->_wcsInfo[i].radesys;
256  ar & ip->_wcsInfo[i].crpix[0];
257  ar & ip->_wcsInfo[i].crpix[1];
258  ar & ip->_wcsInfo[i].cd[0];
259  ar & ip->_wcsInfo[i].cd[1];
260  ar & ip->_wcsInfo[i].cd[2];
261  ar & ip->_wcsInfo[i].cd[3];
262  ar & ip->_wcsInfo[i].crval[0];
263  ar & ip->_wcsInfo[i].crval[1];
264  ar & ip->_wcsInfo[i].cunit[0];
265  ar & ip->_wcsInfo[i].cunit[1];
266  ar & ip->_wcsInfo[i].ctype[0];
267  ar & ip->_wcsInfo[i].ctype[1];
268  ar & ip->_wcsInfo[i].altlin;
269 
270  // If we are loading, compute intermediate values given those above
271  if (Archive::is_loading::value) {
272  ip->_wcsInfo[i].flag = 0;
273  wcsset(&(ip->_wcsInfo[i]));
274  }
275  }
276  LOGL_DEBUG(_log, "TanWcsFormatter delegateSerialize end");
277 }
278 
279 // Explicit template specializations confuse Doxygen, tell it to ignore them
281 template void TanWcsFormatter::delegateSerialize(boost::archive::text_oarchive&, int, dafBase::Persistable*);
282 template void TanWcsFormatter::delegateSerialize(boost::archive::text_iarchive&, int, dafBase::Persistable*);
283 template void TanWcsFormatter::delegateSerialize(boost::archive::binary_oarchive&, int,
285 template void TanWcsFormatter::delegateSerialize(boost::archive::binary_iarchive&, int,
288 
292 }
293 }
294 }
295 } // end lsst::afw::formatters
#define LOG_LOGGER
Definition: Log.h:712
static void delegateSerialize(Archive &ar, int const version, lsst::daf::base::Persistable *persistable)
Definition: Span.h:37
Class for storing ordered metadata with comments.
Definition: PropertyList.h:73
Eigen::MatrixXd _sipAp
Definition: TanWcs.h:201
T rfind(T... args)
static lsst::daf::persistence::FormatterRegistration registration
static std::shared_ptr< lsst::daf::persistence::Formatter > createInstance(std::shared_ptr< lsst::pex::policy::Policy > policy)
virtual lsst::daf::base::Persistable * read(std::shared_ptr< lsst::daf::persistence::FormatterStorage > storage, std::shared_ptr< lsst::daf::base::PropertySet > additionalData)
TanWcsFormatter & operator=(TanWcsFormatter const &)
tbl::Key< int > wcs
#define __attribute__(x)
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
table::Key< std::string > ctype2
Definition: Wcs.cc:938
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
virtual void update(lsst::daf::base::Persistable *persistable, std::shared_ptr< lsst::daf::persistence::FormatterStorage > storage, std::shared_ptr< lsst::daf::base::PropertySet > additionalData)
STL class.
LSST DM logging module built on log4cxx.
std::shared_ptr< daf::base::PropertyList > readMetadata(std::string const &fileName, int hdu=DEFAULT_HDU, bool strip=false)
Read FITS header.
Definition: Utils.h:64
A base class for image defects.
Definition: cameraGeom.dox:3
Implementation of the WCS standard for the special case of the Gnomonic (tangent plane) projection...
Definition: TanWcs.h:68
Interface for PropertySetFormatter class.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:134
virtual void write(lsst::daf::base::Persistable const *persistable, std::shared_ptr< lsst::daf::persistence::FormatterStorage > storage, std::shared_ptr< lsst::daf::base::PropertySet > additionalData)
Include files required for standard LSST Exception handling.
T dynamic_pointer_cast(T... args)
Eigen::MatrixXd _sipB
Definition: TanWcs.h:201
T get(T... args)
#define LSST_EXCEPT(type,...)
Create an exception with a given type and message and optionally other arguments (dependent on the ty...
Definition: Exception.h:46
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:450
TanWcsFormatter(TanWcsFormatter const &)
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:448
Eigen::MatrixXd _sipA
Definition: TanWcs.h:201
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:449
Class for boost::serialization storage.
Definition: BoostStorage.h:59
Base class for all persistable classes.
Definition: Persistable.h:74
void serializeEigenArray(Archive &ar, Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > &m)
#define LOG_GET(logger)
Returns a Log object associated with logger.
Definition: Log.h:83
static std::shared_ptr< lsst::daf::base::PropertyList > generatePropertySet(lsst::afw::image::TanWcs const &wcs)
ImageT val
Definition: CR.cc:158
table::Key< std::string > ctype1
Definition: Wcs.cc:937
struct wcsprm * _wcsInfo
Definition: Wcs.h:446
coord::CoordSystem _coordSystem
Definition: Wcs.h:452
Class implementing persistence and retrieval for TanWcs objects.
Eigen::MatrixXd _sipBp
Definition: TanWcs.h:201
const int DEFAULT_HDU
Specify that the default HDU should be read.
Definition: fitsDefaults.h:18