LSST Applications g00d0e8bbd7+edbf708997,g03191d30f7+9ce8016dbd,g1955dfad08+0bd186d245,g199a45376c+5137f08352,g1fd858c14a+a888a50aa2,g262e1987ae+45f9aba685,g29ae962dfc+1c7d47a24f,g2cef7863aa+73c82f25e4,g35bb328faa+edbf708997,g3fd5ace14f+eed17d2c67,g47891489e3+6dc8069a4c,g53246c7159+edbf708997,g64539dfbff+c4107e45b5,g67b6fd64d1+6dc8069a4c,g74acd417e5+f452e9c21a,g786e29fd12+af89c03590,g7ae74a0b1c+a25e60b391,g7aefaa3e3d+2025e9ce17,g7cc15d900a+2d158402f9,g87389fa792+a4172ec7da,g89139ef638+6dc8069a4c,g8d4809ba88+c4107e45b5,g8d7436a09f+e96c132b44,g8ea07a8fe4+db21c37724,g98df359435+aae6d409c1,ga2180abaac+edbf708997,gac66b60396+966efe6077,gb632fb1845+88945a90f8,gbaa8f7a6c5+38b34f4976,gbf99507273+edbf708997,gca7fc764a6+6dc8069a4c,gd7ef33dd92+6dc8069a4c,gda68eeecaf+7d1e613a8d,gdab6d2f7ff+f452e9c21a,gdbb4c4dda9+c4107e45b5,ge410e46f29+6dc8069a4c,ge41e95a9f2+c4107e45b5,geaed405ab2+e194be0d2b,w.2025.47
LSST Data Management Base Package
Loading...
Searching...
No Matches
lsst::afw::fits::Fits Class Reference

A simple struct that combines the two arguments that must be passed to most cfitsio routines and contains thin and/or templated wrappers around common cfitsio routines. More...

#include <fits.h>

Public Types

enum  BehaviorFlags { AUTO_CLOSE = 0x01 , AUTO_CHECK = 0x02 }
 

Public Member Functions

std::string getFileName () const
 Return the file name associated with the FITS object or "<unknown>" if there is none.
 
int getHdu ()
 Return the current HDU (0-indexed; 0 is the Primary HDU).
 
void setHdu (int hdu, bool relative=false)
 Set the current HDU.
 
void setHdu (std::string const &name, HduType hdutype=HduType::ANY, int hduver=0)
 Set the current HDU using its name, version and type.
 
int countHdus ()
 Return the number of HDUs in the file.
 
template<typename T>
void updateKey (std::string const &key, T const &value, std::string const &comment)
 Set a FITS header key, editing if it already exists and appending it if not.
 
void updateKey (std::string const &key, char const *value, std::string const &comment)
 
template<typename T>
void updateKey (std::string const &key, T const &value)
 
void updateKey (std::string const &key, char const *value)
 
template<typename T>
void writeKey (std::string const &key, T const &value, std::string const &comment)
 Add a FITS header key to the bottom of the header.
 
void writeKey (std::string const &key, char const *value, std::string const &comment)
 
template<typename T>
void writeKey (std::string const &key, T const &value)
 
void writeKey (std::string const &key, char const *value)
 
template<typename T>
void updateColumnKey (std::string const &prefix, int n, T const &value, std::string const &comment)
 Update a key of the form XXXXXnnn, where XXXXX is the prefix and nnn is a column number.
 
void updateColumnKey (std::string const &prefix, int n, char const *value, std::string const &comment)
 
template<typename T>
void updateColumnKey (std::string const &prefix, int n, T const &value)
 
void updateColumnKey (std::string const &prefix, int n, char const *value)
 
template<typename T>
void writeColumnKey (std::string const &prefix, int n, T const &value, std::string const &comment)
 Write a key of the form XXXXXnnn, where XXXXX is the prefix and nnn is a column number.
 
void writeColumnKey (std::string const &prefix, int n, char const *value, std::string const &comment)
 
template<typename T>
void writeColumnKey (std::string const &prefix, int n, T const &value)
 
void writeColumnKey (std::string const &prefix, int n, char const *value)
 
void writeMetadata (daf::base::PropertySet const &metadata)
 Read a FITS header into a PropertySet or PropertyList.
 
void readMetadata (daf::base::PropertySet &metadata, bool strip=false)
 Read a FITS header into a PropertySet or PropertyList.
 
template<typename T>
void readKey (std::string const &key, T &value)
 Read a FITS header key into the given reference.
 
void forEachKey (HeaderIterationFunctor &functor)
 Call a polymorphic functor for every key in the header.
 
void createEmpty ()
 Create an empty image HDU with NAXIS=0 at the end of the file.
 
template<typename PixelT>
void createImage (long x, long y)
 Create a 2-d image with pixel type provided by the given explicit PixelT template parameter.
 
template<typename T, int N, int C>
void writeImage (ndarray::Array< T const, N, C > const &array)
 Write an ndarray::Array to a FITS image HDU.
 
template<typename T>
void writeImage (image::ImageBase< T > const &image, CompressionOptions const *compression=nullptr, daf::base::PropertySet const *header=nullptr, image::Mask< image::MaskPixel > const *mask=nullptr)
 Write an image to FITS.
 
int getImageDim ()
 Return the number of dimensions in the current HDU.
 
template<int N>
ndarray::Vector< ndarray::Size, N > getImageShape ()
 Return the shape of the current (image) HDU.
 
template<typename T>
bool checkImageType ()
 Return true if the current HDU is compatible with the given pixel type.
 
std::string getImageDType ()
 Return the numpy dtype equivalent of the image pixel type (e.g.
 
template<typename T, int N>
void readImage (ndarray::Array< T, N, N > const &array, ndarray::Vector< int, N > const &offset)
 Read an array from a FITS image.
 
void createTable ()
 Create a new binary table extension.
 
template<typename T>
int addColumn (std::string const &ttype, int size, std::string const &comment)
 Add a column to a table.
 
template<typename T>
int addColumn (std::string const &ttype, int size)
 Add a column to a table.
 
std::size_t addRows (std::size_t nRows)
 Append rows to a table, and return the index of the first new row.
 
std::size_t countRows ()
 Return the number of row in a table.
 
template<typename T>
void writeTableArray (std::size_t row, int col, int nElements, T const *value)
 Write an array value to a binary table.
 
template<typename T>
void writeTableScalar (std::size_t row, int col, T value)
 Write a scalar value to a binary table.
 
void writeTableScalar (std::size_t row, int col, std::string const &value)
 Write a string to a binary table.
 
template<typename T>
void readTableArray (std::size_t row, int col, int nElements, T *value)
 Read an array value from a binary table.
 
template<typename T>
void readTableScalar (std::size_t row, int col, T &value)
 Read an array scalar from a binary table.
 
void readTableScalar (std::size_t row, int col, std::string &value, bool isVariableLength)
 Read a string from a binary table.
 
long getTableArraySize (int col)
 Return the size of an array column.
 
long getTableArraySize (std::size_t row, int col)
 Return the size of an variable-length array field.
 
 Fits ()
 Default constructor; set all data members to 0.
 
 Fits (std::string const &filename, std::string const &mode, int behavior)
 Open or create a FITS file from disk.
 
 Fits (MemFileManager &manager, std::string const &mode, int behavior)
 Open or create a FITS file from an in-memory file.
 
void closeFile ()
 Close a FITS file.
 
bool checkCompressedImagePhu ()
 Go to the first image header in the FITS file.
 
 ~Fits ()
 
 Fits (const Fits &)=delete
 
Fitsoperator= (const Fits &)=delete
 
 Fits (Fits &&)=delete
 
Fitsoperator= (Fits &&)=delete
 
template<typename PixelT, int N>
void createImage (ndarray::Vector< ndarray::Size, N > const &shape)
 Create an image with pixel type provided by the given explicit PixelT template parameter and shape defined by an ndarray index.
 
template<int N>
void createImage (int bitpix, ndarray::Vector< ndarray::Size, N > const &shape)
 Create an image with pixel type provided by the given explicit PixelT template parameter and shape defined by an ndarray index.
 

Public Attributes

void * fptr
 
int status
 
int behavior
 

Detailed Description

A simple struct that combines the two arguments that must be passed to most cfitsio routines and contains thin and/or templated wrappers around common cfitsio routines.

This is NOT intended to be an object-oriented C++ wrapper around cfitsio; it's simply a thin layer that saves a lot of repetition, const/reinterpret casts, and replaces void pointer args and type codes with templates and overloads.

Like a cfitsio pointer, a Fits object always considers one HDU the "active" one, and most operations will be applied to that HDU.

All member functions are non-const because they may modify the 'status' data member.

Note
All functions that take a row or column number below are 0-indexed; the internal cfitsio calls are all 1-indexed.

Definition at line 242 of file fits.h.

Member Enumeration Documentation

◆ BehaviorFlags

Enumerator
AUTO_CLOSE 
AUTO_CHECK 

Definition at line 251 of file fits.h.

251 {
252 AUTO_CLOSE = 0x01, // Close files when the Fits object goes out of scope if fptr != NULL
253 AUTO_CHECK = 0x02 // Call LSST_FITS_CHECK_STATUS after every cfitsio call
254 };

Constructor & Destructor Documentation

◆ Fits() [1/5]

lsst::afw::fits::Fits::Fits ( )
inline

Default constructor; set all data members to 0.

Definition at line 567 of file fits.h.

567: fptr(nullptr), status(0), behavior(0) {}

◆ Fits() [2/5]

lsst::afw::fits::Fits::Fits ( std::string const & filename,
std::string const & mode,
int behavior )

Open or create a FITS file from disk.

Definition at line 1707 of file fits.cc.

1708 : fptr(nullptr), status(0), behavior(behavior_) {
1709 if (mode == "r" || mode == "rb") {
1710 fits_open_file(reinterpret_cast<fitsfile **>(&fptr), const_cast<char *>(filename.c_str()), READONLY,
1711 &status);
1712 } else if (mode == "w" || mode == "wb") {
1713 std::filesystem::remove(filename); // cfitsio doesn't like over-writing files
1714 fits_create_file(reinterpret_cast<fitsfile **>(&fptr), const_cast<char *>(filename.c_str()), &status);
1715 } else if (mode == "a" || mode == "ab") {
1716 fits_open_file(reinterpret_cast<fitsfile **>(&fptr), const_cast<char *>(filename.c_str()), READWRITE,
1717 &status);
1718 int nHdu = 0;
1719 fits_get_num_hdus(reinterpret_cast<fitsfile *>(fptr), &nHdu, &status);
1720 fits_movabs_hdu(reinterpret_cast<fitsfile *>(fptr), nHdu, nullptr, &status);
1721 if ((behavior & AUTO_CHECK) && (behavior & AUTO_CLOSE) && (status) && (fptr)) {
1722 // We're about to throw an exception, and the destructor won't get called
1723 // because we're in the constructor, so cleanup here first.
1724 int tmpStatus = 0;
1725 fits_close_file(reinterpret_cast<fitsfile *>(fptr), &tmpStatus);
1726 }
1727 } else {
1728 throw LSST_EXCEPT(
1729 FitsError,
1730 (boost::format("Invalid mode '%s' given when opening file '%s'") % mode % filename).str());
1731 }
1732 if (behavior & AUTO_CHECK) {
1733 LSST_FITS_CHECK_STATUS(*this, boost::format("Opening file '%s' with mode '%s'") % filename % mode);
1734 }
1735}
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
#define LSST_FITS_CHECK_STATUS(fitsObj,...)
Throw a FitsError exception if the status of the given Fits object is nonzero.
Definition fits.h:112

◆ Fits() [3/5]

lsst::afw::fits::Fits::Fits ( MemFileManager & manager,
std::string const & mode,
int behavior )

Open or create a FITS file from an in-memory file.

Definition at line 1737 of file fits.cc.

1738 : fptr(nullptr), status(0), behavior(behavior_) {
1739 using Reallocator = void *(*)(void *, std::size_t);
1740 // It's a shame this logic is essentially a duplicate of above, but the innards are different enough
1741 // we can't really reuse it.
1742 if (mode == "r" || mode == "rb") {
1743 fits_open_memfile(reinterpret_cast<fitsfile **>(&fptr), "unused", READONLY, &manager._ptr,
1744 &manager._len, 0, nullptr, // no reallocator or deltasize necessary for READONLY
1745 &status);
1746 } else if (mode == "w" || mode == "wb") {
1747 Reallocator reallocator = nullptr;
1748 if (manager._managed) reallocator = &std::realloc;
1749 fits_create_memfile(reinterpret_cast<fitsfile **>(&fptr), &manager._ptr, &manager._len, 0,
1750 reallocator, // use default deltasize
1751 &status);
1752 } else if (mode == "a" || mode == "ab") {
1753 Reallocator reallocator = nullptr;
1754 if (manager._managed) reallocator = &std::realloc;
1755 fits_open_memfile(reinterpret_cast<fitsfile **>(&fptr), "unused", READWRITE, &manager._ptr,
1756 &manager._len, 0, reallocator, &status);
1757 int nHdu = 0;
1758 fits_get_num_hdus(reinterpret_cast<fitsfile *>(fptr), &nHdu, &status);
1759 fits_movabs_hdu(reinterpret_cast<fitsfile *>(fptr), nHdu, nullptr, &status);
1760 if ((behavior & AUTO_CHECK) && (behavior & AUTO_CLOSE) && (status) && (fptr)) {
1761 // We're about to throw an exception, and the destructor won't get called
1762 // because we're in the constructor, so cleanup here first.
1763 int tmpStatus = 0;
1764 fits_close_file(reinterpret_cast<fitsfile *>(fptr), &tmpStatus);
1765 }
1766 } else {
1767 throw LSST_EXCEPT(FitsError,
1768 (boost::format("Invalid mode '%s' given when opening memory file at '%s'") % mode %
1769 manager._ptr)
1770 .str());
1771 }
1772 if (behavior & AUTO_CHECK) {
1774 *this, boost::format("Opening memory file at '%s' with mode '%s'") % manager._ptr % mode);
1775 }
1776}
decltype(sizeof(void *)) size_t
Definition doctest.h:524
T realloc(T... args)

◆ ~Fits()

lsst::afw::fits::Fits::~Fits ( )
inline

Definition at line 587 of file fits.h.

587 {
588 if ((fptr) && (behavior & AUTO_CLOSE)) closeFile();
589 }
void closeFile()
Close a FITS file.
Definition fits.cc:1778

◆ Fits() [4/5]

lsst::afw::fits::Fits::Fits ( const Fits & )
delete

◆ Fits() [5/5]

lsst::afw::fits::Fits::Fits ( Fits && )
delete

Member Function Documentation

◆ addColumn() [1/2]

template<typename T>
int lsst::afw::fits::Fits::addColumn ( std::string const & ttype,
int size )

Add a column to a table.

If size <= 0, the field will be a variable length array, with max set by (-size), or left unknown if size == 0.

Definition at line 1118 of file fits.cc.

1118 {
1119 int nCols = 0;
1120 fits_get_num_cols(reinterpret_cast<fitsfile *>(fptr), &nCols, &status);
1121 std::string tform = makeColumnFormat<T>(size);
1122 fits_insert_col(reinterpret_cast<fitsfile *>(fptr), nCols + 1, const_cast<char *>(ttype.c_str()),
1123 const_cast<char *>(tform.c_str()), &status);
1124 if (behavior & AUTO_CHECK) {
1125 LSST_FITS_CHECK_STATUS(*this, boost::format("Adding column '%s' with size %d") % ttype % size);
1126 }
1127 return nCols;
1128}
T c_str(T... args)

◆ addColumn() [2/2]

template<typename T>
int lsst::afw::fits::Fits::addColumn ( std::string const & ttype,
int size,
std::string const & comment )

Add a column to a table.

If size <= 0, the field will be a variable length array, with max set by (-size), or left unknown if size == 0.

Definition at line 1131 of file fits.cc.

1131 {
1132 int nCols = addColumn<T>(ttype, size);
1133 updateColumnKey("TTYPE", nCols, ttype, comment);
1134 if (behavior & AUTO_CHECK) {
1135 LSST_FITS_CHECK_STATUS(*this, boost::format("Adding column '%s' with size %d") % ttype % size);
1136 }
1137 return nCols;
1138}
void updateColumnKey(std::string const &prefix, int n, T const &value, std::string const &comment)
Update a key of the form XXXXXnnn, where XXXXX is the prefix and nnn is a column number.
Definition fits.cc:675
int addColumn(std::string const &ttype, int size, std::string const &comment)
Add a column to a table.
Definition fits.cc:1131

◆ addRows()

std::size_t lsst::afw::fits::Fits::addRows ( std::size_t nRows)

Append rows to a table, and return the index of the first new row.

Definition at line 1140 of file fits.cc.

1140 {
1141 long first = 0;
1142 fits_get_num_rows(reinterpret_cast<fitsfile *>(fptr), &first, &status);
1143 fits_insert_rows(reinterpret_cast<fitsfile *>(fptr), first, nRows, &status);
1144 if (behavior & AUTO_CHECK) {
1145 LSST_FITS_CHECK_STATUS(*this, boost::format("Adding %d rows to binary table") % nRows);
1146 }
1147 return first;
1148}

◆ checkCompressedImagePhu()

bool lsst::afw::fits::Fits::checkCompressedImagePhu ( )

Go to the first image header in the FITS file.

If a single image is written compressed, it appears as an extension, rather than the primary HDU (PHU). This method is useful before reading an image, as it checks whether we are positioned on an empty PHU and if the next HDU is a compressed image; if so, it leaves the file pointer on the compressed image, ready for reading.

Definition at line 1902 of file fits.cc.

1902 {
1903 auto fits = reinterpret_cast<fitsfile *>(fptr);
1904 if (getHdu() != 0 || countHdus() == 1) {
1905 return false; // Can't possibly be the PHU leading a compressed image
1906 }
1907 // Check NAXIS = 0
1908 int naxis;
1909 fits_get_img_dim(fits, &naxis, &status);
1910 if (behavior & AUTO_CHECK) {
1911 LSST_FITS_CHECK_STATUS(*this, "Checking NAXIS of PHU");
1912 }
1913 if (naxis != 0) {
1914 return false;
1915 }
1916 // Check first extension (and move back there when we're done if we're not compressed)
1917 HduMoveGuard move(*this, 1);
1918 bool isCompressed = fits_is_compressed_image(fits, &status);
1919 if (behavior & AUTO_CHECK) {
1920 LSST_FITS_CHECK_STATUS(*this, "Checking compression");
1921 }
1922 if (isCompressed) {
1923 move.disable();
1924 }
1925 return isCompressed;
1926}
int countHdus()
Return the number of HDUs in the file.
Definition fits.cc:518
int getHdu()
Return the current HDU (0-indexed; 0 is the Primary HDU).
Definition fits.cc:483
T move(T... args)

◆ checkImageType()

template<typename T>
bool lsst::afw::fits::Fits::checkImageType ( )

Return true if the current HDU is compatible with the given pixel type.

This takes into account the BSCALE and BZERO keywords, which can allow integer images to be interpreted as floating point.

Definition at line 1652 of file fits.cc.

1652 {
1653 int imageType = get_actual_cfitsio_bitpix(*this);
1654 if (std::numeric_limits<T>::is_integer) {
1655 if (imageType < 0) {
1656 return false; // can't represent floating-point with integer
1657 }
1658 bool is_compressed = fits_is_compressed_image(reinterpret_cast<fitsfile*>(fptr), &status);
1659 if (behavior & AUTO_CHECK) LSST_FITS_CHECK_STATUS(*this, "Checking pixel type compatibility");
1660 if (is_compressed && sizeof(T) == 8) {
1661 // CFITSIO can't decompress into [u]int64, at least on some
1662 // platforms, so we don't support it.
1663 return false;
1664 }
1665 if (std::numeric_limits<T>::is_signed) {
1666 if (isFitsImageTypeSigned(imageType)) {
1667 return cfitsio_bitpix<T> >= imageType;
1668 } else {
1669 // need extra bits to safely convert unsigned to signed
1670 return cfitsio_bitpix<T> > imageType;
1671 }
1672 } else {
1673 if (!isFitsImageTypeSigned(imageType)) {
1674 return cfitsio_bitpix<T> >= imageType;
1675 } else {
1676 return false;
1677 }
1678 }
1679 }
1680 // we allow all conversions to float and double, even if they lose precision
1681 return true;
1682}

◆ closeFile()

void lsst::afw::fits::Fits::closeFile ( )

Close a FITS file.

Definition at line 1778 of file fits.cc.

1778 {
1779 fits_close_file(reinterpret_cast<fitsfile *>(fptr), &status);
1780 fptr = nullptr;
1781}

◆ countHdus()

int lsst::afw::fits::Fits::countHdus ( )

Return the number of HDUs in the file.

Definition at line 518 of file fits.cc.

518 {
519 int n = 0;
520 fits_get_num_hdus(reinterpret_cast<fitsfile *>(fptr), &n, &status);
521 if (behavior & AUTO_CHECK) {
522 LSST_FITS_CHECK_STATUS(*this, "Getting number of HDUs in file.");
523 }
524 return n;
525}

◆ countRows()

std::size_t lsst::afw::fits::Fits::countRows ( )

Return the number of row in a table.

Definition at line 1150 of file fits.cc.

1150 {
1151 long r = 0;
1152 fits_get_num_rows(reinterpret_cast<fitsfile *>(fptr), &r, &status);
1153 if (behavior & AUTO_CHECK) {
1154 LSST_FITS_CHECK_STATUS(*this, "Checking how many rows are in table");
1155 }
1156 return r;
1157}

◆ createEmpty()

void lsst::afw::fits::Fits::createEmpty ( )

Create an empty image HDU with NAXIS=0 at the end of the file.

This is primarily useful to force the first "real" HDU to be an extension HDU by creating an empty Primary HDU. The new HDU is set as the active one.

Definition at line 1534 of file fits.cc.

1534 {
1535 long naxes = 0;
1536 fits_create_img(reinterpret_cast<fitsfile *>(fptr), 8, 0, &naxes, &status);
1537 if (behavior & AUTO_CHECK) {
1538 LSST_FITS_CHECK_STATUS(*this, "Creating empty image HDU");
1539 }
1540}

◆ createImage() [1/3]

template<int N>
void lsst::afw::fits::Fits::createImage ( int bitpix,
ndarray::Vector< ndarray::Size, N > const & shape )
inline

Create an image with pixel type provided by the given explicit PixelT template parameter and shape defined by an ndarray index.

Note
The shape parameter is ordered fastest-dimension last (i.e. [y, x]) as is conventional with ndarray.

The new image will be in a new HDU at the end of the file, which may be the Primary HDU if the FITS file is empty.

Definition at line 406 of file fits.h.

406 {
407 ndarray::Vector<long, N> nAxes(shape.reverse());
408 createImageImpl(bitpix, N, nAxes.elems);
409 }

◆ createImage() [2/3]

template<typename PixelT>
void lsst::afw::fits::Fits::createImage ( long x,
long y )
inline

Create a 2-d image with pixel type provided by the given explicit PixelT template parameter.

The new image will be in a new HDU at the end of the file, which may be the Primary HDU if the FITS file is empty.

Definition at line 419 of file fits.h.

419 {
420 long naxes[2] = {x, y};
421 createImageImpl(getBitPix<PixelT>(), 2, naxes);
422 }
int getBitPix()
Return the cfitsio integer BITPIX code for the given data type.
Definition fits.cc:466

◆ createImage() [3/3]

template<typename PixelT, int N>
void lsst::afw::fits::Fits::createImage ( ndarray::Vector< ndarray::Size, N > const & shape)
inline

Create an image with pixel type provided by the given explicit PixelT template parameter and shape defined by an ndarray index.

Note
The shape parameter is ordered fastest-dimension last (i.e. [y, x]) as is conventional with ndarray.

The new image will be in a new HDU at the end of the file, which may be the Primary HDU if the FITS file is empty.

Definition at line 400 of file fits.h.

400 {
401 ndarray::Vector<long, N> nAxes(shape.reverse());
402 createImageImpl(getBitPix<PixelT>(), N, nAxes.elems);
403 }

◆ createTable()

void lsst::afw::fits::Fits::createTable ( )

Create a new binary table extension.

Definition at line 1108 of file fits.cc.

1108 {
1109 char *ttype = nullptr;
1110 char *tform = nullptr;
1111 fits_create_tbl(reinterpret_cast<fitsfile *>(fptr), BINARY_TBL, 0, 0, &ttype, &tform, nullptr, nullptr, &status);
1112 if (behavior & AUTO_CHECK) {
1113 LSST_FITS_CHECK_STATUS(*this, "Creating binary table");
1114 }
1115}

◆ forEachKey()

void lsst::afw::fits::Fits::forEachKey ( HeaderIterationFunctor & functor)

Call a polymorphic functor for every key in the header.

Each value is passed in as a string, and the single quotes that mark an actual string value are not removed (neither are extra spaces). However, long strings that make use of the CONTINUE keyword are concatenated to look as if they were on a single line.

Definition at line 765 of file fits.cc.

765 {
766 char key[81]; // allow for terminating NUL
767 char value[81];
768 char comment[81];
769 int nKeys = 0;
770 fits_get_hdrspace(reinterpret_cast<fitsfile *>(fptr), &nKeys, nullptr, &status);
771 std::string keyStr;
772 std::string valueStr;
773 std::string commentStr;
774 int i = 1;
775 while (i <= nKeys) {
776 fits_read_keyn(reinterpret_cast<fitsfile *>(fptr), i, key, value, comment, &status);
777 // fits_read_keyn does not convert the key case on read, like other fits methods in cfitsio>=3.38
778 // We uppercase to try to be more consistent.
779 std::string upperKey(key);
780 boost::to_upper(upperKey);
781 if (upperKey.compare(key) != 0){
782 LOGLS_DEBUG("lsst.afw.fits",
783 boost::format("In %s, standardizing key '%s' to uppercase '%s' on read.") %
784 BOOST_CURRENT_FUNCTION % key % upperKey);
785 }
786 keyStr = upperKey;
787 valueStr = value;
788 commentStr = comment;
789 ++i;
790 while (valueStr.size() > 2 && valueStr[valueStr.size() - 2] == '&' && i <= nKeys) {
791 // we're using key to hold the entire record here; the actual key is safe in keyStr
792 fits_read_record(reinterpret_cast<fitsfile *>(fptr), i, key, &status);
793 if (strncmp(key, "CONTINUE", 8) != 0) {
794 // require both trailing '&' and CONTINUE to invoke long-string handling
795 break;
796 }
797 std::string card = key;
798 valueStr.erase(valueStr.size() - 2);
799 std::size_t firstQuote = card.find('\'');
800 if (firstQuote == std::string::npos) {
801 throw LSST_EXCEPT(
802 FitsError,
804 fptr, status,
805 boost::format("Invalid CONTINUE at header key %d: \"%s\".") % i % card));
806 }
807 std::size_t lastQuote = card.find('\'', firstQuote + 1);
808 if (lastQuote == std::string::npos) {
809 throw LSST_EXCEPT(
810 FitsError,
812 fptr, status,
813 boost::format("Invalid CONTINUE at header key %d: \"%s\".") % i % card));
814 }
815 valueStr += card.substr(firstQuote + 1, lastQuote - firstQuote);
816 std::size_t slash = card.find('/', lastQuote + 1);
817 if (slash != std::string::npos) {
818 commentStr += strip(card.substr(slash + 1));
819 }
820 ++i;
821 }
822 if (behavior & AUTO_CHECK) {
823 LSST_FITS_CHECK_STATUS(*this, boost::format("Reading key '%s'") % keyStr);
824 }
825 functor(keyStr, valueStr, commentStr);
826 }
827}
#define LOGLS_DEBUG(logger, message)
Log a debug-level message using an iostream-based interface.
Definition Log.h:619
T erase(T... args)
T find(T... args)
std::string makeErrorMessage(std::string const &fileName="", int status=0, std::string const &msg="")
Return an error message reflecting FITS I/O errors.
Definition fits.cc:396
T size(T... args)
T strncmp(T... args)
T substr(T... args)

◆ getFileName()

std::string lsst::afw::fits::Fits::getFileName ( ) const

Return the file name associated with the FITS object or "<unknown>" if there is none.

Definition at line 474 of file fits.cc.

474 {
475 std::string fileName = "<unknown>";
476 fitsfile *fd = reinterpret_cast<fitsfile *>(fptr);
477 if (fd != nullptr && fd->Fptr != nullptr && fd->Fptr->filename != nullptr) {
478 fileName = fd->Fptr->filename;
479 }
480 return fileName;
481}

◆ getHdu()

int lsst::afw::fits::Fits::getHdu ( )

Return the current HDU (0-indexed; 0 is the Primary HDU).

Definition at line 483 of file fits.cc.

483 {
484 int n = 1;
485 fits_get_hdu_num(reinterpret_cast<fitsfile *>(fptr), &n);
486 return n - 1;
487}

◆ getImageDim()

int lsst::afw::fits::Fits::getImageDim ( )

Return the number of dimensions in the current HDU.

Definition at line 1639 of file fits.cc.

1639 {
1640 int nAxis = 0;
1641 fits_get_img_dim(reinterpret_cast<fitsfile *>(fptr), &nAxis, &status);
1642 if (behavior & AUTO_CHECK) LSST_FITS_CHECK_STATUS(*this, "Getting NAXIS");
1643 return nAxis;
1644}

◆ getImageDType()

std::string lsst::afw::fits::Fits::getImageDType ( )

Return the numpy dtype equivalent of the image pixel type (e.g.

"uint16", "float64").

Definition at line 1684 of file fits.cc.

1684 {
1685 int bitpix = get_actual_cfitsio_bitpix(*this);
1686 if (bitpix < 0) {
1687 return "float" + std::to_string(-bitpix);
1688 }
1689 switch (bitpix) {
1690 case BYTE_IMG: return "uint8";
1691 case SBYTE_IMG: return "int8";
1692 case SHORT_IMG: return "int16";
1693 case USHORT_IMG: return "uint16";
1694 case LONG_IMG: return "int32";
1695 case ULONG_IMG: return "uint32";
1696 case LONGLONG_IMG: return "int64";
1697 case ULONGLONG_IMG: return "uint64";
1698 }
1699 throw LSST_EXCEPT(
1700 FitsError,
1701 (boost::format("Unrecognized BITPIX value: %d") % bitpix).str()
1702 );
1703}
T to_string(T... args)

◆ getImageShape()

template<int N>
ndarray::Vector< ndarray::Size, N > lsst::afw::fits::Fits::getImageShape ( )
inline

Return the shape of the current (image) HDU.

The order of dimensions is reversed from the FITS ordering, reflecting the usual (y,x) ndarray convention.

The template parameter must match the actual number of dimension in the image.

Definition at line 470 of file fits.h.

470 {
471 ndarray::Vector<long, N> nAxes(1);
472 getImageShapeImpl(N, nAxes.elems);
473 ndarray::Vector<ndarray::Size, N> shape;
474 for (int i = 0; i < N; ++i) shape[i] = nAxes[N - i - 1];
475 return shape;
476 }

◆ getTableArraySize() [1/2]

long lsst::afw::fits::Fits::getTableArraySize ( int col)

Return the size of an array column.

Definition at line 1208 of file fits.cc.

1208 {
1209 int typecode = 0;
1210 long result = 0;
1211 long width = 0;
1212 fits_get_coltype(reinterpret_cast<fitsfile *>(fptr), col + 1, &typecode, &result, &width, &status);
1213 if (behavior & AUTO_CHECK) {
1214 LSST_FITS_CHECK_STATUS(*this, boost::format("Looking up array size for column %d") % col);
1215 }
1216 return result;
1217}

◆ getTableArraySize() [2/2]

long lsst::afw::fits::Fits::getTableArraySize ( std::size_t row,
int col )

Return the size of an variable-length array field.

Definition at line 1219 of file fits.cc.

1219 {
1220 long result = 0;
1221 long offset = 0;
1222 fits_read_descript(reinterpret_cast<fitsfile *>(fptr), col + 1, row + 1, &result, &offset, &status);
1223 if (behavior & AUTO_CHECK) {
1224 LSST_FITS_CHECK_STATUS(*this, boost::format("Looking up array size for cell (%d, %d)") % row % col);
1225 }
1226 return result;
1227}

◆ operator=() [1/2]

Fits & lsst::afw::fits::Fits::operator= ( const Fits & )
delete

◆ operator=() [2/2]

Fits & lsst::afw::fits::Fits::operator= ( Fits && )
delete

◆ readImage()

template<typename T, int N>
void lsst::afw::fits::Fits::readImage ( ndarray::Array< T, N, N > const & array,
ndarray::Vector< int, N > const & offset )
inline

Read an array from a FITS image.

Parameters
[out]arrayArray to be filled. Must already be allocated to the desired shape.
[in]offsetIndices of the first pixel to be read from the image.

Definition at line 499 of file fits.h.

499 {
500 ndarray::Vector<long, N> begin(offset.reverse());
501 ndarray::Vector<long, N> end(begin);
502 end += array.getShape().reverse();
503 ndarray::Vector<long, N> increment(1);
504 begin += increment; // first FITS pixel is 1, not 0
505 readImageImpl(N, array.getData(), begin.elems, end.elems, increment.elems);
506 }
T begin(T... args)
T end(T... args)

◆ readKey()

template<typename T>
void lsst::afw::fits::Fits::readKey ( std::string const & key,
T & value )

Read a FITS header key into the given reference.

Definition at line 758 of file fits.cc.

758 {
759 readKeyImpl(*this, key.c_str(), value);
760 if (behavior & AUTO_CHECK) {
761 LSST_FITS_CHECK_STATUS(*this, boost::format("Reading key '%s'") % key);
762 }
763}

◆ readMetadata()

void lsst::afw::fits::Fits::readMetadata ( daf::base::PropertySet & metadata,
bool strip = false )

Read a FITS header into a PropertySet or PropertyList.

Parameters
[in,out]metadataA PropertySet or PropertyList that FITS header items will be added to.
[in]stripIf true, common FITS keys that usually have non-metadata intepretations (e.g. NAXIS, BITPIX) will be ignored.

Order will preserved if and only if the metadata object is actually a PropertyList.

Definition at line 1078 of file fits.cc.

1078 {
1079 MetadataIterationFunctor f;
1080 f.strip = strip;
1081 f.set = &metadata;
1082 f.list = dynamic_cast<daf::base::PropertyList *>(&metadata);
1083 forEachKey(f);
1084}
void forEachKey(HeaderIterationFunctor &functor)
Call a polymorphic functor for every key in the header.
Definition fits.cc:765

◆ readTableArray()

template<typename T>
void lsst::afw::fits::Fits::readTableArray ( std::size_t row,
int col,
int nElements,
T * value )

Read an array value from a binary table.

Definition at line 1183 of file fits.cc.

1183 {
1184 int anynul = false;
1185 fits_read_col(reinterpret_cast<fitsfile *>(fptr), FitsTableType<T>::CONSTANT, col + 1, row + 1, 1,
1186 nElements, nullptr, value, &anynul, &status);
1187 if (behavior & AUTO_CHECK) {
1188 LSST_FITS_CHECK_STATUS(*this, boost::format("Reading value at table cell (%d, %d)") % row % col);
1189 }
1190}

◆ readTableScalar() [1/2]

void lsst::afw::fits::Fits::readTableScalar ( std::size_t row,
int col,
std::string & value,
bool isVariableLength )

Read a string from a binary table.

Definition at line 1192 of file fits.cc.

1192 {
1193 int anynul = false;
1194 long size = isVariableLength ? getTableArraySize(row, col) : getTableArraySize(col);
1195 // We can't directly write into a std::string until C++17.
1196 std::vector<char> buf(size + 1, 0);
1197 // cfitsio wants a char** because they imagine we might want an array of strings,
1198 // but we only want one element.
1199 char *tmp = &buf.front();
1200 fits_read_col(reinterpret_cast<fitsfile *>(fptr), TSTRING, col + 1, row + 1, 1, 1, nullptr, &tmp, &anynul,
1201 &status);
1202 if (behavior & AUTO_CHECK) {
1203 LSST_FITS_CHECK_STATUS(*this, boost::format("Reading value at table cell (%d, %d)") % row % col);
1204 }
1205 value = std::string(tmp);
1206}
long getTableArraySize(int col)
Return the size of an array column.
Definition fits.cc:1208

◆ readTableScalar() [2/2]

template<typename T>
void lsst::afw::fits::Fits::readTableScalar ( std::size_t row,
int col,
T & value )
inline

Read an array scalar from a binary table.

Definition at line 553 of file fits.h.

553 {
554 readTableArray(row, col, 1, &value);
555 }
void readTableArray(std::size_t row, int col, int nElements, T *value)
Read an array value from a binary table.
Definition fits.cc:1183

◆ setHdu() [1/2]

void lsst::afw::fits::Fits::setHdu ( int hdu,
bool relative = false )

Set the current HDU.

Parameters
[in]hduThe HDU to move to (0-indexed; 0 is the Primary HDU). The special value of DEFAULT_HDU moves to the first extension if the Primary HDU is empty (has NAXIS==0) and the the Primary HDU is the current one.
[in]relativeIf true, move relative to the current HDU.

Definition at line 489 of file fits.cc.

489 {
490 if (relative) {
491 fits_movrel_hdu(reinterpret_cast<fitsfile *>(fptr), hdu, nullptr, &status);
492 if (behavior & AUTO_CHECK) {
493 LSST_FITS_CHECK_STATUS(*this, boost::format("Incrementing HDU by %d") % hdu);
494 }
495 } else {
496 if (hdu != DEFAULT_HDU) {
497 fits_movabs_hdu(reinterpret_cast<fitsfile *>(fptr), hdu + 1, nullptr, &status);
498 }
499 if (hdu == DEFAULT_HDU && getHdu() == 0 && getImageDim() == 0) {
500 // want a silent failure here
501 int tmpStatus = status;
502 fits_movrel_hdu(reinterpret_cast<fitsfile *>(fptr), 1, nullptr, &tmpStatus);
503 }
504 if (behavior & AUTO_CHECK) {
505 LSST_FITS_CHECK_STATUS(*this, boost::format("Moving to HDU %d") % hdu);
506 }
507 }
508}
int getImageDim()
Return the number of dimensions in the current HDU.
Definition fits.cc:1639
const int DEFAULT_HDU
Specify that the default HDU should be read.

◆ setHdu() [2/2]

void lsst::afw::fits::Fits::setHdu ( std::string const & name,
HduType hdutype = HduType::ANY,
int hduver = 0 )

Set the current HDU using its name, version and type.

Parameters
[in]nameThe name of the HDU to move to
[in]hdutypeThe type of HDU to match. If not supplied, defaults to ANY_HDU
[in]hduverThe value of EXTVER to match. If not supplied, defaults to 0

Definition at line 510 of file fits.cc.

510 {
511 fits_movnam_hdu(reinterpret_cast<fitsfile *>(fptr), static_cast<int>(hdutype),
512 const_cast<char *>(name.c_str()), hduver, &status);
513 if (behavior & AUTO_CHECK)
514 LSST_FITS_CHECK_STATUS(*this, boost::format("Moving to named HDU %s, type %d, hduver %d") % name %
515 static_cast<int>(hdutype) % hduver);
516}

◆ updateColumnKey() [1/4]

void lsst::afw::fits::Fits::updateColumnKey ( std::string const & prefix,
int n,
char const * value )
inline

Definition at line 325 of file fits.h.

325 {
326 updateColumnKey(prefix, n, std::string(value));
327 }

◆ updateColumnKey() [2/4]

void lsst::afw::fits::Fits::updateColumnKey ( std::string const & prefix,
int n,
char const * value,
std::string const & comment )
inline

Definition at line 320 of file fits.h.

320 {
321 updateColumnKey(prefix, n, std::string(value), comment);
322 }

◆ updateColumnKey() [3/4]

template<typename T>
void lsst::afw::fits::Fits::updateColumnKey ( std::string const & prefix,
int n,
T const & value )

Definition at line 691 of file fits.cc.

691 {
692 updateKey((boost::format("%s%d") % prefix % (n + 1)).str(), value);
693 if (behavior & AUTO_CHECK) {
694 LSST_FITS_CHECK_STATUS(*this, boost::format("Updating key '%s%d': '%s'") % prefix % (n + 1) % value);
695 }
696}
void updateKey(std::string const &key, T const &value, std::string const &comment)
Set a FITS header key, editing if it already exists and appending it if not.
Definition fits.cc:643

◆ updateColumnKey() [4/4]

template<typename T>
void lsst::afw::fits::Fits::updateColumnKey ( std::string const & prefix,
int n,
T const & value,
std::string const & comment )

Update a key of the form XXXXXnnn, where XXXXX is the prefix and nnn is a column number.

Definition at line 675 of file fits.cc.

675 {
676 updateKey((boost::format("%s%d") % prefix % (n + 1)).str(), value, comment);
677 if (behavior & AUTO_CHECK) {
678 LSST_FITS_CHECK_STATUS(*this, boost::format("Updating key '%s%d': '%s'") % prefix % (n + 1) % value);
679 }
680}

◆ updateKey() [1/4]

void lsst::afw::fits::Fits::updateKey ( std::string const & key,
char const * value )
inline

Definition at line 295 of file fits.h.

295{ updateKey(key, std::string(value)); }

◆ updateKey() [2/4]

void lsst::afw::fits::Fits::updateKey ( std::string const & key,
char const * value,
std::string const & comment )
inline

Definition at line 290 of file fits.h.

290 {
291 updateKey(key, std::string(value), comment);
292 }

◆ updateKey() [3/4]

template<typename T>
void lsst::afw::fits::Fits::updateKey ( std::string const & key,
T const & value )

Definition at line 659 of file fits.cc.

659 {
660 updateKeyImpl(*this, key.c_str(), value, nullptr);
661 if (behavior & AUTO_CHECK) {
662 LSST_FITS_CHECK_STATUS(*this, boost::format("Updating key '%s': '%s'") % key % value);
663 }
664}

◆ updateKey() [4/4]

template<typename T>
void lsst::afw::fits::Fits::updateKey ( std::string const & key,
T const & value,
std::string const & comment )

Set a FITS header key, editing if it already exists and appending it if not.

Definition at line 643 of file fits.cc.

643 {
644 updateKeyImpl(*this, key.c_str(), value, comment.c_str());
645 if (behavior & AUTO_CHECK) {
646 LSST_FITS_CHECK_STATUS(*this, boost::format("Updating key '%s': '%s'") % key % value);
647 }
648}

◆ writeColumnKey() [1/4]

void lsst::afw::fits::Fits::writeColumnKey ( std::string const & prefix,
int n,
char const * value )
inline

Definition at line 339 of file fits.h.

339 {
340 writeColumnKey(prefix, n, std::string(value));
341 }
void writeColumnKey(std::string const &prefix, int n, T const &value, std::string const &comment)
Write a key of the form XXXXXnnn, where XXXXX is the prefix and nnn is a column number.
Definition fits.cc:683

◆ writeColumnKey() [2/4]

void lsst::afw::fits::Fits::writeColumnKey ( std::string const & prefix,
int n,
char const * value,
std::string const & comment )
inline

Definition at line 334 of file fits.h.

334 {
335 writeColumnKey(prefix, n, std::string(value), comment);
336 }

◆ writeColumnKey() [3/4]

template<typename T>
void lsst::afw::fits::Fits::writeColumnKey ( std::string const & prefix,
int n,
T const & value )

Definition at line 699 of file fits.cc.

699 {
700 writeKey((boost::format("%s%d") % prefix % (n + 1)).str(), value);
701 if (behavior & AUTO_CHECK) {
702 LSST_FITS_CHECK_STATUS(*this, boost::format("Writing key '%s%d': '%s'") % prefix % (n + 1) % value);
703 }
704}
void writeKey(std::string const &key, T const &value, std::string const &comment)
Add a FITS header key to the bottom of the header.
Definition fits.cc:651

◆ writeColumnKey() [4/4]

template<typename T>
void lsst::afw::fits::Fits::writeColumnKey ( std::string const & prefix,
int n,
T const & value,
std::string const & comment )

Write a key of the form XXXXXnnn, where XXXXX is the prefix and nnn is a column number.

Definition at line 683 of file fits.cc.

683 {
684 writeKey((boost::format("%s%d") % prefix % (n + 1)).str(), value, comment);
685 if (behavior & AUTO_CHECK) {
686 LSST_FITS_CHECK_STATUS(*this, boost::format("Writing key '%s%d': '%s'") % prefix % (n + 1) % value);
687 }
688}

◆ writeImage() [1/2]

template<typename T>
void lsst::afw::fits::Fits::writeImage ( image::ImageBase< T > const & image,
CompressionOptions const * compression = nullptr,
daf::base::PropertySet const * header = nullptr,
image::Mask< image::MaskPixel > const * mask = nullptr )

Write an image to FITS.

This method is all-inclusive, and covers creating the HDU (with the correct BITPIX), writing the header and optional scaling and compression of the image.

Parameters
[in]imageImage to write to FITS.
[in]compressionOptions for compressing the image.
[in]headerFITS header to write.
[in]maskMask for image (used for statistics when scaling).

Definition at line 1564 of file fits.cc.

1566 {
1567 // Context will restore the original settings when it is destroyed.
1568 CompressionContext context(*this, compression, image, mask);
1569 if (behavior & AUTO_CHECK) {
1570 LSST_FITS_CHECK_STATUS(*this, "Activating compression for write image");
1571 }
1572 // We need a place to put the image+header, and CFITSIO needs to know the
1573 // dimensions.
1574 ndarray::Vector<long, 2> dims(image.getArray().getShape().reverse());
1575 createImageImpl(cfitsio_bitpix<T>, 2, dims.elems);
1576 // Write the header
1577 std::shared_ptr<daf::base::PropertyList> wcsMetadata =
1578 geom::createTrivialWcsMetadata(image::detail::wcsNameForXY0, image.getXY0());
1579 std::shared_ptr<daf::base::PropertySet> fullMetadata;
1580 if (header) {
1581 fullMetadata = header->deepCopy();
1582 fullMetadata->combine(*wcsMetadata);
1583 } else {
1584 fullMetadata = wcsMetadata;
1585 }
1586 writeMetadata(*fullMetadata);
1587 std::optional<T> explicit_null = std::nullopt;
1588 if constexpr(std::is_floating_point_v<T>) {
1589 if (compression && compression->quantization) {
1590 explicit_null = -std::numeric_limits<T>::infinity();
1591 }
1592 }
1593 // Write the image itself.
1594 writeImageImpl(context.get_pixel_data<T>(), context.get_n_pixels(), explicit_null);
1595}
void writeMetadata(daf::base::PropertySet const &metadata)
Read a FITS header into a PropertySet or PropertyList.
Definition fits.cc:1086
T infinity(T... args)
std::string const wcsNameForXY0
Definition ImageBase.h:70

◆ writeImage() [2/2]

template<typename T, int N, int C>
void lsst::afw::fits::Fits::writeImage ( ndarray::Array< T const, N, C > const & array)
inline

Write an ndarray::Array to a FITS image HDU.

The HDU must already exist and have the correct bitpix.

An extra deep-copy may be necessary if the array is not fully contiguous.

No compression or scaling is performed.

Definition at line 434 of file fits.h.

434 {
435 writeImageImpl(makeContiguousArray(array).getData(), array.getNumElements());
436 }
ndarray::Array< T const, N, N > const makeContiguousArray(ndarray::Array< T, N, C > const &array)
Construct a contiguous ndarray.
Definition fits.h:213

◆ writeKey() [1/4]

void lsst::afw::fits::Fits::writeKey ( std::string const & key,
char const * value )
inline

Definition at line 313 of file fits.h.

313{ writeKey(key, std::string(value)); }

◆ writeKey() [2/4]

void lsst::afw::fits::Fits::writeKey ( std::string const & key,
char const * value,
std::string const & comment )
inline

Definition at line 308 of file fits.h.

308 {
309 writeKey(key, std::string(value), comment);
310 }

◆ writeKey() [3/4]

template<typename T>
void lsst::afw::fits::Fits::writeKey ( std::string const & key,
T const & value )

Definition at line 667 of file fits.cc.

667 {
668 writeKeyImpl(*this, key.c_str(), value, nullptr);
669 if (behavior & AUTO_CHECK) {
670 LSST_FITS_CHECK_STATUS(*this, boost::format("Writing key '%s': '%s'") % key % value);
671 }
672}

◆ writeKey() [4/4]

template<typename T>
void lsst::afw::fits::Fits::writeKey ( std::string const & key,
T const & value,
std::string const & comment )

Add a FITS header key to the bottom of the header.

If the key is HISTORY or COMMENT and the value is a std::string or C-string, a special HISTORY or COMMENT key will be appended (and the comment argument will be ignored if present).

Definition at line 651 of file fits.cc.

651 {
652 writeKeyImpl(*this, key.c_str(), value, comment.c_str());
653 if (behavior & AUTO_CHECK) {
654 LSST_FITS_CHECK_STATUS(*this, boost::format("Writing key '%s': '%s'") % key % value);
655 }
656}

◆ writeMetadata()

void lsst::afw::fits::Fits::writeMetadata ( daf::base::PropertySet const & metadata)

Read a FITS header into a PropertySet or PropertyList.

Parameters
[in]metadataA PropertySet or PropertyList whose items will be appended to the FITS header.

All keys will be appended to the FITS header rather than used to update existing keys. Order of keys will be preserved if and only if the metadata object is actually a PropertyList.

Definition at line 1086 of file fits.cc.

1086 {
1087 using NameList = std::vector<std::string>;
1088 daf::base::PropertyList const *pl = dynamic_cast<daf::base::PropertyList const *>(&metadata);
1089 NameList paramNames;
1090 if (pl) {
1091 paramNames = pl->getOrderedNames();
1092 } else {
1093 paramNames = metadata.paramNames(false);
1094 }
1095 for (auto const &paramName : paramNames) {
1096 if (!isKeyIgnored(paramName, true)) {
1097 if (pl) {
1098 writeKeyFromProperty(*this, metadata, paramName, pl->getComment(paramName).c_str());
1099 } else {
1100 writeKeyFromProperty(*this, metadata, paramName);
1101 }
1102 }
1103 }
1104}

◆ writeTableArray()

template<typename T>
void lsst::afw::fits::Fits::writeTableArray ( std::size_t row,
int col,
int nElements,
T const * value )

Write an array value to a binary table.

Definition at line 1160 of file fits.cc.

1160 {
1161 fits_write_col(reinterpret_cast<fitsfile *>(fptr), FitsTableType<T>::CONSTANT, col + 1, row + 1, 1,
1162 nElements, const_cast<T *>(value), &status);
1163 if (behavior & AUTO_CHECK) {
1164 LSST_FITS_CHECK_STATUS(*this, boost::format("Writing %d-element array at table cell (%d, %d)") %
1165 nElements % row % col);
1166 }
1167}

◆ writeTableScalar() [1/2]

void lsst::afw::fits::Fits::writeTableScalar ( std::size_t row,
int col,
std::string const & value )

Write a string to a binary table.

Definition at line 1169 of file fits.cc.

1169 {
1170 // cfitsio doesn't let us specify the size of a string, it just looks for null terminator.
1171 // Using std::string::c_str() guarantees that we have one. But we can't store arbitrary
1172 // data in a string field because cfitsio will also chop off anything after the first null
1173 // terminator.
1174 char const *tmp = value.c_str();
1175 fits_write_col(reinterpret_cast<fitsfile *>(fptr), TSTRING, col + 1, row + 1, 1, 1,
1176 const_cast<char const **>(&tmp), &status);
1177 if (behavior & AUTO_CHECK) {
1178 LSST_FITS_CHECK_STATUS(*this, boost::format("Writing value at table cell (%d, %d)") % row % col);
1179 }
1180}

◆ writeTableScalar() [2/2]

template<typename T>
void lsst::afw::fits::Fits::writeTableScalar ( std::size_t row,
int col,
T value )
inline

Write a scalar value to a binary table.

Definition at line 541 of file fits.h.

541 {
542 writeTableArray(row, col, 1, &value);
543 }
void writeTableArray(std::size_t row, int col, int nElements, T const *value)
Write an array value to a binary table.
Definition fits.cc:1160

Member Data Documentation

◆ behavior

int lsst::afw::fits::Fits::behavior

Definition at line 601 of file fits.h.

◆ fptr

void* lsst::afw::fits::Fits::fptr

Definition at line 599 of file fits.h.

◆ status

int lsst::afw::fits::Fits::status

Definition at line 600 of file fits.h.


The documentation for this class was generated from the following files: