LSSTApplications  18.0.0+106,18.0.0+50,19.0.0,19.0.0+1,19.0.0+10,19.0.0+11,19.0.0+13,19.0.0+17,19.0.0+2,19.0.0-1-g20d9b18+6,19.0.0-1-g425ff20,19.0.0-1-g5549ca4,19.0.0-1-g580fafe+6,19.0.0-1-g6fe20d0+1,19.0.0-1-g7011481+9,19.0.0-1-g8c57eb9+6,19.0.0-1-gb5175dc+11,19.0.0-1-gdc0e4a7+9,19.0.0-1-ge272bc4+6,19.0.0-1-ge3aa853,19.0.0-10-g448f008b,19.0.0-12-g6990b2c,19.0.0-2-g0d9f9cd+11,19.0.0-2-g3d9e4fb2+11,19.0.0-2-g5037de4,19.0.0-2-gb96a1c4+3,19.0.0-2-gd955cfd+15,19.0.0-3-g2d13df8,19.0.0-3-g6f3c7dc,19.0.0-4-g725f80e+11,19.0.0-4-ga671dab3b+1,19.0.0-4-gad373c5+3,19.0.0-5-ga2acb9c+2,19.0.0-5-gfe96e6c+2,w.2020.01
LSSTDataManagementBasePackage
Functions | Variables
lsst::afw::geom::detail Namespace Reference

Functions

std::shared_ptr< ast::FrameSetreadFitsWcs (daf::base::PropertySet &metadata, bool strip=true)
 Read a FITS convention WCS FrameSet from FITS metadata. More...
 
std::shared_ptr< ast::FrameDictreadLsstSkyWcs (daf::base::PropertySet &metadata, bool strip=true)
 Read an LSST celestial WCS FrameDict from a FITS header. More...
 
std::shared_ptr< daf::base::PropertyListgetPropertyListFromFitsChan (ast::FitsChan &fitsChan)
 Copy values from an AST FitsChan into a PropertyList. More...
 
ast::FitsChan getFitsChanFromPropertyList (daf::base::PropertySet &metadata, std::set< std::string > const &excludeNames={}, std::string options="")
 Construct AST FitsChan from PropertyList. More...
 
template<class Transform >
std::shared_ptr< TransformreadStream (std::istream &is)
 Deserialize a Transform from an input stream. More...
 
template<class Transform >
void writeStream (Transform const &transform, std::ostream &os)
 Serialize a Transform to an output stream. More...
 

Variables

constexpr int serializationVersion = 1
 version of serialization used when writing (older versions may also be supported when reading) More...
 

Function Documentation

◆ getFitsChanFromPropertyList()

ast::FitsChan lsst::afw::geom::detail::getFitsChanFromPropertyList ( daf::base::PropertySet metadata,
std::set< std::string > const &  excludeNames = {},
std::string  options = "" 
)

Construct AST FitsChan from PropertyList.

Parameters
[in]metadataMetadata to transfer; if this is a PropertyList then the order of items is preserved.
[in]excludeNamesNames of entries to exclude from the returned header string.
[in]optionsOptions string to pass to ast::FitsChan constructor.
Returns
an ast::FitsChan representing this PropertyList

Definition at line 321 of file frameSetUtils.cc.

323  {
324  // Create FitsChan to receive each of the parameters
325  auto stream = ast::StringStream("");
326  auto fc = ast::FitsChan(stream, options);
327 
328  // Get the parameter names (in order if necessary)
329  daf::base::PropertyList const *pl = dynamic_cast<daf::base::PropertyList const *>(&metadata);
330  std::vector<std::string> allParamNames;
331  if (pl) {
332  allParamNames = pl->getOrderedNames();
333  } else {
334  allParamNames = metadata.paramNames(false);
335  }
336 
337  // Loop over the names and add them to the FitsChan if not excluded
338  for (auto const &fullName : allParamNames) {
339  if (excludeNames.count(fullName) == 0) {
340  std::size_t lastPeriod = fullName.rfind(char('.'));
341  auto name = (lastPeriod == std::string::npos) ? fullName : fullName.substr(lastPeriod + 1);
342  std::type_info const &type = metadata.typeOf(name);
343 
344  if (name.size() > 8) {
345  continue; // The name is too long for a FITS keyword; skip this item
346  }
347 
348  if (type == typeid(bool)) {
349  fc.setFitsL(name, metadata.get<bool>(name));
350  } else if (type == typeid(std::uint8_t)) {
351  fc.setFitsI(name, static_cast<int>(metadata.get<std::uint8_t>(name)));
352  } else if (type == typeid(int)) {
353  fc.setFitsI(name, metadata.get<int>(name));
354  } else if (type == typeid(double) || type == typeid(float)) {
355  double value;
356  if (type == typeid(double)) {
357  value = metadata.get<double>(name);
358  } else {
359  value = static_cast<double>(metadata.get<float>(name));
360  }
361  // NaN is not allowed in a FitsChan (or in FITS)
362  if (!std::isnan(value)) {
363  fc.setFitsF(name, value);
364  } else {
365  // Treat it like an undefined value but warn about it
366  LOGLS_WARN("afw.geom.frameSetUtils",
367  boost::format("Found NaN in metadata item '%s'") % name);
368  }
369  } else if (type == typeid(std::string)) {
370  std::string str = metadata.get<std::string>(name);
371  // No support for long strings yet so skip those
372  if (str.size() <= 68) {
373  fc.setFitsS(name, metadata.get<std::string>(name));
374  }
375  }
376  }
377  }
378  // Rewind the channel
379  fc.setCard(0);
380  return fc;
381 }
#define LOGLS_WARN(logger, message)
Log a warn-level message using an iostream-based interface.
Definition: Log.h:648
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
A specialized form of Channel which reads and writes FITS header cards.
Definition: FitsChan.h:202
STL class.
table::Key< int > type
Definition: Detector.cc:163
T count(T... args)
T size(T... args)
String-based source and sink for channels.
Definition: Stream.h:180
T isnan(T... args)

◆ getPropertyListFromFitsChan()

std::shared_ptr< daf::base::PropertyList > lsst::afw::geom::detail::getPropertyListFromFitsChan ( ast::FitsChan fitsChan)

Copy values from an AST FitsChan into a PropertyList.

Warning
COMMENT and HISTORY cards are treated as string values
Exceptions
lsst::pex::exceptions::TypeErrorif fitsChan contains cards whose type is not supported by PropertyList: complex numbers, or cards with no value

Definition at line 256 of file frameSetUtils.cc.

256  {
257  int const numCards = fitsChan.getNCard();
258  auto metadata = std::make_shared<daf::base::PropertyList>();
259  for (int cardNum = 1; cardNum <= numCards; ++cardNum) {
260  fitsChan.setCard(cardNum);
261  auto const cardType = fitsChan.getCardType();
262  auto const cardName = fitsChan.getCardName();
263  auto const cardComment = fitsChan.getCardComm();
264  switch (cardType) {
265  case ast::CardType::FLOAT: {
266  auto foundValue = fitsChan.getFitsF();
267  setMetadataFromFoundValue(*metadata, cardName, foundValue, cardComment);
268  break;
269  }
270  case ast::CardType::INT: {
271  auto foundValue = fitsChan.getFitsI();
272  setMetadataFromFoundValue(*metadata, cardName, foundValue, cardComment);
273  break;
274  }
275  case ast::CardType::STRING: {
276  auto foundValue = fitsChan.getFitsS();
277  setMetadataFromFoundValue(*metadata, cardName, foundValue, cardComment);
278  break;
279  }
280  case ast::CardType::LOGICAL: {
281  auto foundValue = fitsChan.getFitsL();
282  setMetadataFromFoundValue(*metadata, cardName, foundValue, cardComment);
283  break;
284  }
285  case ast::CardType::UNDEF: {
286  if (cardComment.empty()) {
287  metadata->set(cardName, nullptr);
288  } else {
289  metadata->set(cardName, nullptr, cardComment);
290  }
291  break;
292  }
294  auto foundValue = fitsChan.getFitsCN();
295  setMetadataFromFoundValue(*metadata, cardName, foundValue, cardComment);
296  break;
297  }
299  // Drop HISTORY and COMMENT cards
300  break;
303  // PropertyList supports neither complex numbers nor cards with no value
305  os << "Card " << cardNum << " with name \"" << cardName << "\" has type "
306  << static_cast<int>(cardType) << ", which is not supported by PropertyList";
308  }
309  case ast::CardType::NOTYPE: {
310  // This should only occur if cardNum is invalid, and that should be impossible
312  os << "Bug! Card " << cardNum << " with name \"" << cardName
313  << "\" has type NOTYPE, which should not be possible";
315  }
316  }
317  }
318  return metadata;
319 }
FoundValue< std::string > getFitsCN(std::string const &name="", std::string defval="") const
Get the value of a CONTINUE card.
Definition: FitsChan.cc:69
complex integer
complex floating point
CardType getCardType() const
Get CardType: data type of the current FITS card.
Definition: FitsChan.h:501
std::string getCardComm() const
Get CardComm: the comment of the current card.
Definition: FitsChan.h:491
std::string getCardName() const
Get CardName: the keyword name of the current card.
Definition: FitsChan.h:496
int getNCard() const
Get NCard: the number of cards.
Definition: FitsChan.h:555
FoundValue< int > getFitsI(std::string const &name="", int defval=0) const
Get the value of a int card.
Definition: FitsChan.cc:84
void setCard(int ind)
Set Card: the index of the current card, where 1 is the first card.
Definition: FitsChan.h:1036
card is a comment-style card with no "=" (COMMENT, HISTORY, ...)
FoundValue< std::string > getFitsS(std::string const &name="", std::string defval="") const
Get the value of a string card.
Definition: FitsChan.cc:98
T str(T... args)
FoundValue< double > getFitsF(std::string const &name="", double defval=0) const
Get the value of a double card.
Definition: FitsChan.cc:77
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
card has no value
Reports errors from accepting an object of an unexpected or inappropriate type.
Definition: Runtime.h:167
std::ostream * os
Definition: Schema.cc:746
card does not exist (card number invalid)
FoundValue< bool > getFitsL(std::string const &name="", bool defval=false) const
Get the value of a bool card.
Definition: FitsChan.cc:91

◆ readFitsWcs()

std::shared_ptr< ast::FrameSet > lsst::afw::geom::detail::readFitsWcs ( daf::base::PropertySet metadata,
bool  strip = true 
)

Read a FITS convention WCS FrameSet from FITS metadata.

The resulting FrameSet may be any kind of WCS supported by FITS; if it is a celestial WCS then 1,1 will be the lower left corner of the image (the FITS convention, not the LSST convention).

This routine replaces RADECSYS with RADESYS if the former is present and the latter is not, since that is a common misspelling in FITS headers.

The returned FrameSet will have an IWC (intermediate world coordinate system) frame.

Parameters
[in,out]metadataFITS header cards
[in]stripIf true: strip items from metadata used to create the WCS, such as RADESYS, EQUINOX, CTYPE12, CRPIX12, CRVAL12, etc. Always keep keywords that might be wanted for other purpposes, including NAXIS12 and date-related keywords such as "DATE-OBS" and "TIMESYS" (but not "EQUINOX").
Exceptions
pex::exceptions::TypeErrorif the metadata does not contain a FITS-WCS

Definition at line 87 of file frameSetUtils.cc.

87  {
88  // Exclude WCS A keywords because LSST uses them to store XY0
89  auto wcsANames = createTrivialWcsMetadata("A", lsst::geom::Point2I(0, 0))->names();
90  std::set<std::string> excludeNames(wcsANames.begin(), wcsANames.end());
91  // Ignore NAXIS1, NAXIS2 because if they are zero then AST will fail to read a WCS
92  // Ignore LTV1/2 because LSST adds it and this code should ignore it and not strip it
93  // Exclude comments and history to reduce clutter
94  std::set<std::string> moreNames{"NAXIS1", "NAXIS2", "LTV1", "LTV2", "COMMENT", "HISTORY"};
95  excludeNames.insert(moreNames.begin(), moreNames.end());
96 
97  // Replace RADECSYS with RADESYS if only the former is present
98  if (metadata.exists("RADECSYS") && !metadata.exists("RADESYS")) {
99  metadata.set("RADESYS", metadata.getAsString("RADECSYS"));
100  metadata.remove("RADECSYS");
101  }
102 
103  auto channel = getFitsChanFromPropertyList(metadata, excludeNames,
104  "Encoding=FITS-WCS, IWC=1, SipReplace=0, ReportLevel=3");
105  auto const initialNames = strip ? setFromVector(channel.getAllCardNames()) : std::set<std::string>();
107  try {
108  obj = channel.read();
109  } catch (std::runtime_error const&) {
110  throw LSST_EXCEPT(pex::exceptions::TypeError, "The metadata does not describe an AST object");
111  }
112 
114  if (!frameSet) {
115  throw LSST_EXCEPT(pex::exceptions::TypeError,
116  "metadata describes a " + obj->getClassName() + ", not a FrameSet");
117  }
118  if (strip) {
119  auto const finalNames = setFromVector(channel.getAllCardNames());
120 
121  // FITS keywords that FitsChan stripped
122  std::set<std::string> namesChannelStripped;
123  std::set_difference(initialNames.begin(), initialNames.end(), finalNames.begin(), finalNames.end(),
124  std::inserter(namesChannelStripped, namesChannelStripped.begin()));
125 
126  // FITS keywords that FitsChan may strip that we want to keep in `metadata`
127  std::set<std::string> const namesToKeep = {"DATE-OBS", "MJD-OBS"};
128 
129  std::set<std::string> namesToStrip; // names to strip from metadata
130  std::set_difference(namesChannelStripped.begin(), namesChannelStripped.end(), namesToKeep.begin(),
131  namesToKeep.end(), std::inserter(namesToStrip, namesToStrip.begin()));
132  for (auto const& name : namesToStrip) {
133  metadata.remove(name);
134  }
135  }
136  return frameSet;
137 }
table::Key< table::Array< std::uint8_t > > frameSet
T end(T... args)
ast::FitsChan getFitsChanFromPropertyList(daf::base::PropertySet &metadata, std::set< std::string > const &excludeNames={}, std::string options="")
Construct AST FitsChan from PropertyList.
std::shared_ptr< daf::base::PropertyList > createTrivialWcsMetadata(std::string const &wcsName, lsst::geom::Point2I const &xy0)
Definition: wcsUtils.cc:51
T dynamic_pointer_cast(T... args)
T insert(T... args)
STL class.
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
T begin(T... args)
T inserter(T... args)
T set_difference(T... args)
A FrameSet consists of a set of one or more Frames (which describe coordinate systems), connected together by Mappings (which describe how the coordinate systems are inter-related).
Definition: FrameSet.h:99
bool strip
Definition: fits.cc:901

◆ readLsstSkyWcs()

std::shared_ptr< ast::FrameDict > lsst::afw::geom::detail::readLsstSkyWcs ( daf::base::PropertySet metadata,
bool  strip = true 
)

Read an LSST celestial WCS FrameDict from a FITS header.

Calls getImageXY0FromMetadata to determine image XY0.

Saves CRVAL by setting the output SkyFrame's SkyRef to CRVAL and SkyRefIs="Ignore" (so SkyRef is not treated as an offset).

Warning
Does not compensate for the offset between a subimage and its parent image; callers must do that manually, e.g. by calling SkyWcs::copyAtShiftedPosition.
the general SkyWcs generated by LSST software cannot be exactly represented using standard WCS FITS cards, and so this function cannot read those. This function is intended for two purposes:
  • Read the standard FITS WCS found in raw data and other images from non-LSST observatories and convert it to the LSST pixel convention.
  • Read the approximate FITS WCS that LSST writes to FITS images (for use by non-LSST code).

The frames of the returned WCS will be as follows:

  • "PIXELS" (base frame): pixel frame with 0,0 the lower left corner of the image (LSST convention)
  • "IWC": FITS WCS intermediate world coordinate system
  • "SKY" (current frame): an ast::SkyFrame with domain "SKY": ICRS RA, Dec

All frames are instances of ast::Frame except the SKY frame. All have 2 axes.

Parameters
[in,out]metadataFITS header cards
[in]stripIf true: strip items from metadata used to create the WCS, such as RADESYS, EQUINOX, CTYPE12, CRPIX12, CRVAL12, etc. Always keep keywords that might be wanted for other purpposes, including NAXIS12 and date-related keywords such as "DATE-OBS" and "TIMESYS" (but not "EQUINOX").
Exceptions
lsst::pex::exceptions::TypeErrorif the metadata does not describe a celestial WCS.

Definition at line 139 of file frameSetUtils.cc.

139  {
140  // Record CRPIX in GRID coordinates
141  // so we can compute CRVAL after standardizing the SkyFrame to ICRS
142  // (that standardization is why we don't simply save CRVAL now)
143  std::vector<double> crpixGrid(2);
144  try {
145  crpixGrid[0] = metadata.getAsDouble("CRPIX1");
146  crpixGrid[1] = metadata.getAsDouble("CRPIX2");
148  // std::string used because e.what() returns a C string and two C strings cannot be added
150  e.what() + std::string("; cannot read metadata as a SkyWcs"));
151  }
152 
153  auto rawFrameSet = readFitsWcs(metadata, strip);
154  auto const initialBaseIndex = rawFrameSet->getBase();
155 
156  // Find the GRID frame
157  auto gridIndex = ast::FrameSet::NOFRAME;
158  if (rawFrameSet->findFrame(ast::Frame(2, "Domain=GRID"))) {
159  gridIndex = rawFrameSet->getCurrent();
160  } else {
161  // No appropriate GRID frame found; if the original base frame is of type Frame
162  // with 2 axes and a blank domain then use that, else give up
163  auto const baseFrame = rawFrameSet->getFrame(initialBaseIndex, false);
164  auto const baseClassName = rawFrameSet->getClassName();
165  if (baseFrame->getClassName() != "Frame") {
166  throw LSST_EXCEPT(pex::exceptions::TypeError,
167  "The base frame is of type " + baseFrame->getClassName() +
168  "instead of Frame; cannot read metadata as a SkyWcs");
169  }
170  if (baseFrame->getNAxes() != 2) {
171  throw LSST_EXCEPT(pex::exceptions::TypeError,
172  "The base frame has " + std::to_string(baseFrame->getNAxes()) +
173  " axes instead of 2; cannot read metadata as a SkyWcs");
174  }
175  if (baseFrame->getDomain() != "") {
176  throw LSST_EXCEPT(pex::exceptions::TypeError,
177  "The base frame has domain \"" + baseFrame->getDomain() +
178  "\" instead of blank or GRID; cannot read metadata as a SkyWcs");
179  }
180  // Original base frame has a blank Domain, is of type Frame, and has 2 axes, so
181  // Set its domain to GRID, and set some other potentially useful attributes.
182  gridIndex = initialBaseIndex;
183  }
184 
185  // Find the IWC frame
186  if (!rawFrameSet->findFrame(ast::Frame(2, "Domain=IWC"))) {
187  throw LSST_EXCEPT(pex::exceptions::TypeError, "No IWC frame found; cannot read metadata as a SkyWcs");
188  }
189  auto const iwcIndex = rawFrameSet->getCurrent();
190  auto const iwcFrame = rawFrameSet->getFrame(iwcIndex);
191 
192  // Create a standard sky frame: ICRS with axis order RA, Dec
193 
194  // Create the a template for the standard sky frame
195  auto const stdSkyFrameTemplate = ast::SkyFrame("System=ICRS");
196 
197  // Locate a Frame in the target FrameSet that looks like the template
198  // and hence can be used as the original sky frame.
199  // We ignore the frame set returned by findFrame because that goes from pixels to sky,
200  // and using it would add an unwanted extra branch to our WCS; instead, later on,
201  // we compute a mapping from the old sky frame to the new sky frame and add that.
202  if (!rawFrameSet->findFrame(stdSkyFrameTemplate)) {
203  throw LSST_EXCEPT(pex::exceptions::TypeError,
204  "Could not find a SkyFrame; cannot read metadata as a SkyWcs");
205  }
206  auto initialSkyIndex = rawFrameSet->getCurrent();
207 
208  // Compute a frame set that maps from the original sky frame to our desired sky frame template;
209  // this contains the mapping and sky frame we will insert into the frame set.
210  // (Temporarily set the base frame to the sky frame, because findFrame
211  // produces a mapping from base to the found frame).
212  rawFrameSet->setBase(initialSkyIndex);
213  auto stdSkyFrameSet = rawFrameSet->findFrame(stdSkyFrameTemplate);
214  if (!stdSkyFrameSet) {
215  throw LSST_EXCEPT(pex::exceptions::LogicError,
216  "Bug: found a SkyFrame the first time, but not the second time");
217  }
218 
219  // Add the new mapping into rawFrameSet, connecting it to the original SkyFrame.
220  // Note: we use stdSkyFrameSet as the new frame (meaning stdSkyFrameSet's current frame),
221  // because, unlike stdSkyFrameTemplate, stdSkyFrameSet's current frame has inherited some
222  // potentially useful attributes from the old sky frame, such as epoch.
223  rawFrameSet->addFrame(initialSkyIndex, *stdSkyFrameSet->getMapping()->simplified(),
224  *stdSkyFrameSet->getFrame(ast::FrameSet::CURRENT));
225  auto const stdSkyIndex = rawFrameSet->getCurrent();
226  auto const stdSkyFrame = rawFrameSet->getFrame(stdSkyIndex, false);
227 
228  // Compute a mapping from PIXELS (0-based in parent coordinates)
229  // to GRID (1-based in local coordinates)
231  std::vector<double> pixelToGridArray = {1.0 - xy0[0], 1.0 - xy0[1]}; // 1.0 for FITS vs LSST convention
232  auto pixelToGrid = ast::ShiftMap(pixelToGridArray);
233 
234  // Now construct the returned FrameDict
235  auto const gridToIwc = rawFrameSet->getMapping(gridIndex, iwcIndex)->simplified();
236  auto const pixelToIwc = pixelToGrid.then(*gridToIwc).simplified();
237  auto const iwcToStdSky = rawFrameSet->getMapping(iwcIndex, stdSkyIndex);
238 
239  auto frameDict = std::make_shared<ast::FrameDict>(ast::Frame(2, "Domain=PIXELS"), *pixelToIwc, *iwcFrame);
240  frameDict->addFrame("IWC", *iwcToStdSky, *stdSkyFrame);
241 
242  // Record CRVAL as SkyRef in the SkyFrame so it can easily be obtained later;
243  // set SkyRefIs = "Ignored" (the default) so SkyRef value is ignored instead of used as an offset
244  auto crpixPixels = pixelToGrid.applyInverse(crpixGrid);
245  auto crvalRad = frameDict->applyForward(crpixPixels);
246  auto skyFrame = std::dynamic_pointer_cast<ast::SkyFrame>(frameDict->getFrame("SKY", false));
247  if (!skyFrame) {
248  throw LSST_EXCEPT(pex::exceptions::LogicError, "SKY frame is not a SkyFrame");
249  }
250  skyFrame->setSkyRefIs("Ignored");
251  skyFrame->setSkyRef(crvalRad);
252 
253  return frameDict;
254 }
T to_string(T... args)
static int constexpr CURRENT
index of current frame
Definition: FrameSet.h:105
STL class.
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
virtual char const * what(void) const noexcept
Return a character string summarizing this exception.
Definition: Exception.cc:99
SkyFrame is a specialised form of Frame which describes celestial longitude/latitude coordinate syste...
Definition: SkyFrame.h:66
Frame is used to represent a coordinate system.
Definition: Frame.h:157
static int constexpr NOFRAME
an invalid frame index
Definition: FrameSet.h:106
T dynamic_pointer_cast(T... args)
ShiftMap is a linear Mapping which shifts each axis by a specified constant value.
Definition: ShiftMap.h:40
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
lsst::geom::Point2I getImageXY0FromMetadata(daf::base::PropertySet &metadata, std::string const &wcsName, bool strip=false)
Definition: wcsUtils.cc:98
std::shared_ptr< ast::FrameSet > readFitsWcs(daf::base::PropertySet &metadata, bool strip=true)
Read a FITS convention WCS FrameSet from FITS metadata.
Reports errors from accepting an object of an unexpected or inappropriate type.
Definition: Runtime.h:167
std::string const wcsNameForXY0
Definition: ImageBase.h:70
bool strip
Definition: fits.cc:901

◆ readStream()

template<class Transform >
std::shared_ptr< Transform > lsst::afw::geom::detail::readStream ( std::istream is)

Deserialize a Transform from an input stream.

Template Parameters
Transformthe Transform class; can be Transform<FromEndpoint, ToEndpoint>, SkyWcs, or any other compatible class, i.e. it must support the following (see Transform.h for details):
  • a constructor that takes an ast::FrameSet
  • static method getShortClassName
  • method getMapping
Parameters
[in]isinput stream from which to deserialize this Transform

Definition at line 79 of file transformUtils.h.

79  {
80  int version;
81  is >> version;
82  if (version != 1) {
83  throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
84  "Unsupported version " + std::to_string(version));
85  }
86  std::string shortClassName;
87  is >> shortClassName;
88  if (shortClassName != Transform::getShortClassName()) {
90  os << "Class name in stream " << shortClassName << " != " << Transform::getShortClassName();
91  throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, os.str());
92  }
93  auto astStream = ast::Stream(&is, nullptr);
94  auto astObjectPtr = ast::Channel(astStream).read();
95  auto mapping = std::dynamic_pointer_cast<ast::Mapping>(astObjectPtr);
96  if (!mapping) {
98  os << "The AST serialization was read as a " << astObjectPtr->getClassName()
99  << " instead of a Mapping";
100  throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, os.str());
101  }
102 
103  return std::make_shared<Transform>(*mapping);
104 }
T to_string(T... args)
Channel provides input/output of AST objects.
Definition: Channel.h:60
An abstract base class for objects which transform one set of coordinates to another.
Definition: Mapping.h:59
STL class.
T str(T... args)
T dynamic_pointer_cast(T... args)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
table::Key< int > version
Definition: PhotoCalib.cc:374
std::ostream * os
Definition: Schema.cc:746
std::shared_ptr< Object > read()
Read an object from a channel.
Definition: Channel.cc:52
A stream for ast::Channel.
Definition: Stream.h:41

◆ writeStream()

template<class Transform >
void lsst::afw::geom::detail::writeStream ( Transform const &  transform,
std::ostream os 
)

Serialize a Transform to an output stream.

Version 1 format is as follows:

  • The version number (an integer)
  • A space
  • The short class name, as obtained from getShortClassName
  • A space
  • The contained ast::FrameSet written using FrameSet.show(os, false)
Parameters
[out]osoutput stream to which to serialize this Transform
[in]transformTransform to serialize

Definition at line 107 of file transformUtils.h.

107  {
108  os << serializationVersion << " " << Transform::getShortClassName();
109  transform.getMapping()->show(os, false); // false = do not write comments
110 }
constexpr int serializationVersion
version of serialization used when writing (older versions may also be supported when reading) ...

Variable Documentation

◆ serializationVersion

constexpr int lsst::afw::geom::detail::serializationVersion = 1

version of serialization used when writing (older versions may also be supported when reading)

Definition at line 42 of file transformUtils.h.