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);
367 boost::format(
"Found NaN in metadata item '%s'") %
name);
372 if (str.
size() <= 68) {
table::Key< std::string > name
#define LSST_EXCEPT(type,...)
#define LOGLS_WARN(logger, message)
std::string getCardComm() const
FoundValue< std::string > getFitsS(std::string const &name="", std::string defval="") const
FoundValue< bool > getFitsL(std::string const &name="", bool defval=false) const
std::string getCardName() const
FoundValue< int > getFitsI(std::string const &name="", int defval=0) const
CardType getCardType() const
FoundValue< double > getFitsF(std::string const &name="", double defval=0) const
FoundValue< std::string > getFitsCN(std::string const &name="", std::string defval="") const
static constexpr int CURRENT
static constexpr int NOFRAME
std::vector< std::string > getOrderedNames() const
std::string getAsString(std::string const &name) const
virtual void remove(std::string const &name)
bool exists(std::string const &name) const
std::vector< std::string > paramNames(bool topLevelOnly=true) const
void set(std::string const &name, T const &value)
double getAsDouble(std::string const &name) const
std::type_info const & typeOf(std::string const &name) const
T get(std::string const &name) const
virtual char const * what(void) const noexcept
T make_move_iterator(T... args)
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
A base class for image defects.
T set_difference(T... args)