32 #include "boost/format.hpp"
73 void setMetadataFromFoundValue(daf::base::PropertyList& metadata,
std::string const&
name,
75 if (!foundValue.
found) {
76 throw LSST_EXCEPT(pex::exceptions::LogicError,
"Bug! FitsChan card \"" +
name +
"\" not found");
78 if (comment.empty()) {
81 metadata.set(
name, foundValue.
value, comment);
95 excludeNames.
insert(moreNames.begin(), moreNames.end());
98 if (metadata.
exists(
"RADECSYS") && !metadata.
exists(
"RADESYS")) {
100 metadata.
remove(
"RADECSYS");
104 "Encoding=FITS-WCS, IWC=1, SipReplace=0, ReportLevel=3");
108 obj = channel.read();
113 auto frameSet = std::dynamic_pointer_cast<ast::FrameSet>(obj);
116 "metadata describes a " + obj->getClassName() +
", not a FrameSet");
119 auto const finalNames = setFromVector(channel.getAllCardNames());
123 std::set_difference(initialNames.begin(), initialNames.end(), finalNames.begin(), finalNames.end(),
132 for (
auto const&
name : namesToStrip) {
154 auto const initialBaseIndex = rawFrameSet->getBase();
158 if (rawFrameSet->findFrame(
ast::Frame(2,
"Domain=GRID"))) {
159 gridIndex = rawFrameSet->getCurrent();
163 auto const baseFrame = rawFrameSet->getFrame(initialBaseIndex,
false);
164 auto const baseClassName = rawFrameSet->getClassName();
165 if (baseFrame->getClassName() !=
"Frame") {
167 "The base frame is of type " + baseFrame->getClassName() +
168 "instead of Frame; cannot read metadata as a SkyWcs");
170 if (baseFrame->getNAxes() != 2) {
173 " axes instead of 2; cannot read metadata as a SkyWcs");
175 if (baseFrame->getDomain() !=
"") {
177 "The base frame has domain \"" + baseFrame->getDomain() +
178 "\" instead of blank or GRID; cannot read metadata as a SkyWcs");
182 gridIndex = initialBaseIndex;
186 if (!rawFrameSet->findFrame(
ast::Frame(2,
"Domain=IWC"))) {
189 auto const iwcIndex = rawFrameSet->getCurrent();
190 auto const iwcFrame = rawFrameSet->getFrame(iwcIndex);
195 auto const stdSkyFrameTemplate =
ast::SkyFrame(
"System=ICRS");
202 if (!rawFrameSet->findFrame(stdSkyFrameTemplate)) {
204 "Could not find a SkyFrame; cannot read metadata as a SkyWcs");
206 auto initialSkyIndex = rawFrameSet->getCurrent();
212 rawFrameSet->setBase(initialSkyIndex);
213 auto stdSkyFrameSet = rawFrameSet->findFrame(stdSkyFrameTemplate);
214 if (!stdSkyFrameSet) {
216 "Bug: found a SkyFrame the first time, but not the second time");
223 rawFrameSet->addFrame(initialSkyIndex, *stdSkyFrameSet->getMapping()->simplified(),
225 auto const stdSkyIndex = rawFrameSet->getCurrent();
226 auto const stdSkyFrame = rawFrameSet->getFrame(stdSkyIndex,
false);
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);
239 auto frameDict = std::make_shared<ast::FrameDict>(
ast::Frame(2,
"Domain=PIXELS"), *pixelToIwc, *iwcFrame);
240 frameDict->addFrame(
"IWC", *iwcToStdSky, *stdSkyFrame);
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));
250 skyFrame->setSkyRefIs(
"Ignored");
251 skyFrame->setSkyRef(crvalRad);
257 int const numCards = fitsChan.
getNCard();
258 auto metadata = std::make_shared<daf::base::PropertyList>();
259 for (
int cardNum = 1; cardNum <= numCards; ++cardNum) {
266 auto foundValue = fitsChan.
getFitsF();
267 setMetadataFromFoundValue(*metadata, cardName, foundValue, cardComment);
271 auto foundValue = fitsChan.
getFitsI();
272 setMetadataFromFoundValue(*metadata, cardName, foundValue, cardComment);
276 auto foundValue = fitsChan.
getFitsS();
277 setMetadataFromFoundValue(*metadata, cardName, foundValue, cardComment);
281 auto foundValue = fitsChan.
getFitsL();
282 setMetadataFromFoundValue(*metadata, cardName, foundValue, cardComment);
286 if (cardComment.empty()) {
287 metadata->set(cardName,
nullptr);
289 metadata->set(cardName,
nullptr, cardComment);
295 setMetadataFromFoundValue(*metadata, cardName, foundValue, cardComment);
305 os <<
"Card " << cardNum <<
" with name \"" << cardName <<
"\" has type "
306 <<
static_cast<int>(cardType) <<
", which is not supported by PropertyList";
312 os <<
"Bug! Card " << cardNum <<
" with name \"" << cardName
313 <<
"\" has type NOTYPE, which should not be possible";
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);
344 if (
name.size() > 8) {
348 if (
type ==
typeid(
bool)) {
352 }
else if (
type ==
typeid(
int)) {
354 }
else if (
type ==
typeid(
double) ||
type ==
typeid(float)) {
356 if (
type ==
typeid(
double)) {
357 value = metadata.
get<
double>(
name);
359 value =
static_cast<double>(metadata.
get<
float>(
name));
363 fc.setFitsF(
name, value);
372 if (str.
size() <= 68) {
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
LSST DM logging module built on log4cxx.
#define LOGLS_WARN(logger, message)
Log a warn-level message using an iostream-based interface.
A specialized form of Channel which reads and writes FITS header cards.
std::string getCardComm() const
Get CardComm: the comment of the current card.
FoundValue< std::string > getFitsS(std::string const &name="", std::string defval="") const
Get the value of a string card.
void setCard(int ind)
Set Card: the index of the current card, where 1 is the first card.
FoundValue< bool > getFitsL(std::string const &name="", bool defval=false) const
Get the value of a bool card.
std::string getCardName() const
Get CardName: the keyword name of the current card.
FoundValue< int > getFitsI(std::string const &name="", int defval=0) const
Get the value of a int card.
CardType getCardType() const
Get CardType: data type of the current FITS card.
int getNCard() const
Get NCard: the number of cards.
FoundValue< double > getFitsF(std::string const &name="", double defval=0) const
Get the value of a double card.
FoundValue< std::string > getFitsCN(std::string const &name="", std::string defval="") const
Get the value of a CONTINUE card.
A value and associated validity flag.
T value
The found value; ignore if found is false.
bool found
Was the value found?
Frame is used to represent a coordinate system.
static constexpr int CURRENT
index of current frame
static constexpr int NOFRAME
an invalid frame index
ShiftMap is a linear Mapping which shifts each axis by a specified constant value.
SkyFrame is a specialised form of Frame which describes celestial longitude/latitude coordinate syste...
String-based source and sink for channels.
Class for storing ordered metadata with comments.
std::vector< std::string > getOrderedNames() const
Get the list of property names, in the order they were added.
Class for storing generic metadata.
std::string getAsString(std::string const &name) const
Get the last value for a string property name (possibly hierarchical).
virtual void remove(std::string const &name)
Remove all values for a property name (possibly hierarchical).
bool exists(std::string const &name) const
Determine if a name (possibly hierarchical) exists.
std::vector< std::string > paramNames(bool topLevelOnly=true) const
A variant of names that excludes the names of subproperties.
void set(std::string const &name, T const &value)
Replace all values for a property name (possibly hierarchical) with a new scalar value.
double getAsDouble(std::string const &name) const
Get the last value for any arithmetic property name (possibly hierarchical).
std::type_info const & typeOf(std::string const &name) const
Get the type of values for a property name (possibly hierarchical).
T get(std::string const &name) const
Get the last value for a property name (possibly hierarchical).
virtual char const * what(void) const noexcept
Return a character string summarizing this exception.
Reports errors in the logical structure of the program.
Reports attempts to access elements using an invalid key.
Reports errors from accepting an object of an unexpected or inappropriate type.
T make_move_iterator(T... args)
@ NOTYPE
card does not exist (card number invalid)
@ COMPLEXI
complex integer
@ COMPLEXF
complex floating point
@ COMMENT
card is a comment-style card with no "=" (COMMENT, HISTORY, ...)
std::shared_ptr< ast::FrameSet > readFitsWcs(daf::base::PropertySet &metadata, bool strip=true)
Read a FITS convention WCS FrameSet from FITS metadata.
ast::FitsChan getFitsChanFromPropertyList(daf::base::PropertySet &metadata, std::set< std::string > const &excludeNames={}, std::string options="")
Construct AST FitsChan from PropertyList.
std::shared_ptr< ast::FrameDict > readLsstSkyWcs(daf::base::PropertySet &metadata, bool strip=true)
Read an LSST celestial WCS FrameDict from a FITS header.
std::shared_ptr< daf::base::PropertyList > getPropertyListFromFitsChan(ast::FitsChan &fitsChan)
Copy values from an AST FitsChan into a PropertyList.
std::shared_ptr< daf::base::PropertyList > createTrivialWcsMetadata(std::string const &wcsName, lsst::geom::Point2I const &xy0)
lsst::geom::Point2I getImageXY0FromMetadata(daf::base::PropertySet &metadata, std::string const &wcsName, bool strip=false)
std::string const wcsNameForXY0
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
A base class for image defects.
T set_difference(T... args)