17#include <boost/pointer_cast.hpp>
34 "EXTEND = T / FITS dataset may contain extensions";
36 "Transport System) format is defined in "
39 "2001A&A...376..359H";
66 return "Saves image data from a workspace in FITS (Flexible Image Transport "
71const std::string PROP_INPUT_WS =
"InputWorkspace";
72const std::string PROP_FILENAME =
"Filename";
73const std::string PROP_BIT_DEPTH =
"BitDepth";
81 std::make_shared<API::WorkspaceUnitValidator>(
"Label")),
82 "Workspace holding an image (with one spectrum per pixel row).");
85 std::vector<std::string>(1,
".fits")),
86 "Name of the output file where the image is saved.");
89 "The bit depth or number of bits per pixel to use for the "
90 "output image(s). Only 16 bits is supported at the "
96 std::map<std::string, std::string> result;
100 if (0 == wks->blocksize()) {
101 result[PROP_INPUT_WS] =
"The input workspace must have at least one "
102 "column (the X axis is empty)";
104 if (0 == wks->getNumberHistograms()) {
105 result[PROP_INPUT_WS] =
"The input workspace must have at least one row "
106 "(the Y axis is empty)";
122 std::to_string(ws->getNumberHistograms()) +
" rows saved in '" + filename +
"'\n";
132 std::ofstream outfile(filename, std::ofstream::binary);
151 const size_t entriesPerHDU = 36;
156 const size_t sizeX = img->blocksize();
157 const size_t sizeY = img->getNumberHistograms();
160 const size_t bytespp =
static_cast<size_t>(bitDepth) / 8;
162 for (
size_t row = 0; row < sizeY; ++row) {
163 const auto &yData = img->y(row);
164 for (
size_t col = 0; col < sizeX; ++col) {
167 pixelVal =
static_cast<uint8_t
>(yData[col]);
168 }
else if (16 == bitDepth) {
169 pixelVal =
static_cast<uint16_t
>(yData[col]);
170 }
else if (32 == bitDepth) {
171 pixelVal =
static_cast<uint32_t
>(yData[col]);
177 std::array<uint8_t, g_maxBytesPP> bytesPixel;
178 auto *iter =
reinterpret_cast<uint8_t *
>(&pixelVal);
179 std::reverse_copy(iter, iter + bytespp, bytesPixel.data());
181 file.write(
reinterpret_cast<const char *
>(bytesPixel.data()), bytespp);
187 static const std::vector<char> blanks(
g_maxLenHdr, 32);
189 auto count = hdr.size();
193 file.write(hdr.c_str(),
sizeof(
char) *
count);
199 const std::string sizeY =
std::to_string(img->getNumberHistograms());
201 const size_t fieldWidth = 20;
202 std::stringstream axis1;
203 axis1 <<
"NAXIS1 = " << std::setw(fieldWidth) << sizeX <<
" / length of data axis 1";
206 std::stringstream axis2;
207 axis2 <<
"NAXIS2 = " << std::setw(fieldWidth) << sizeY <<
" / length of data axis 2";
212 std::stringstream hdr;
227 static const std::vector<char> blanks(
g_maxLenHdr, 32);
229 for (
size_t i = 0; i <
count; ++i) {
#define DECLARE_ALGORITHM(classname)
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
@ Save
to specify a file to write to, the file may or may not exist
A property class for workspaces.
SaveFITS : Save images in FITS formats.
static const std::string g_bitDepthPost
static const size_t g_maxBytesPP
void writeFITSHeaderEntry(const std::string &hdr, std::ofstream &file)
static const std::string g_FITSHdrExtensions
void init() override final
Initialize the algorithm's properties.
std::string makeBitDepthHeader(size_t depth) const
void writePaddingFITSHeaders(size_t count, std::ofstream &file)
Writes the padding required to fill every header block.
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
void writeFITSHeaderBlock(const API::MatrixWorkspace_sptr &img, std::ofstream &file)
static const std::array< int, 3 > g_bitDepths
void writeFITSImageMatrix(const API::MatrixWorkspace_sptr &img, std::ofstream &file)
static const size_t g_maxLenHdr
static const std::string g_FITSHdrEnd
static const std::string g_FITSHdrRefComment2
int version() const override final
Algorithm's version for identification.
static const std::string g_FITSHdrFirst
static const size_t g_maxBitDepth
const std::string summary() const override final
Algorithm's summary for use in the GUI and help.
const std::string category() const override final
Algorithm's category for identification.
static const std::string g_bitDepthPre
static const std::string g_FITSHdrRefComment1
void writeFITSHeaderAxesSizes(const API::MatrixWorkspace_sptr &img, std::ofstream &file)
void exec() override final
Execute the algorithm.
static const std::string g_FITSHdrAxes
void saveFITSImage(const API::MatrixWorkspace_sptr &img, const std::string &filename)
Save an image workspace into a file.
ListValidator is a validator that requires the value of a property to be one of a defined list of pos...
void information(const std::string &msg)
Logs at information level.
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::string to_string(const wide_integer< Bits, Signed > &n)
Describes the direction (within an algorithm) of a Property.
@ Input
An input workspace.