17#include <boost/pointer_cast.hpp>
37 "EXTEND = T / FITS dataset may contain extensions";
39 "Transport System) format is defined in "
42 "2001A&A...376..359H";
59const
std::
string SaveFITS::name()
const {
return "SaveFITS"; }
69 return "Saves image data from a workspace in FITS (Flexible Image Transport "
74const std::string PROP_INPUT_WS =
"InputWorkspace";
75const std::string PROP_FILENAME =
"Filename";
76const std::string PROP_BIT_DEPTH =
"BitDepth";
84 std::make_shared<API::WorkspaceUnitValidator>(
"Label")),
85 "Workspace holding an image (with one spectrum per pixel row).");
88 std::vector<std::string>(1,
".fits")),
89 "Name of the output file where the image is saved.");
92 "The bit depth or number of bits per pixel to use for the "
93 "output image(s). Only 16 bits is supported at the "
99 std::map<std::string, std::string> result;
103 if (0 == wks->blocksize()) {
104 result[PROP_INPUT_WS] =
"The input workspace must have at least one "
105 "column (the X axis is empty)";
107 if (0 == wks->getNumberHistograms()) {
108 result[PROP_INPUT_WS] =
"The input workspace must have at least one row "
109 "(the Y axis is empty)";
125 std::to_string(ws->getNumberHistograms()) +
" rows saved in '" + filename +
"'\n";
135 std::ofstream outfile(filename, std::ofstream::binary);
154 const size_t entriesPerHDU = 36;
159 const size_t sizeX = img->blocksize();
160 const size_t sizeY = img->getNumberHistograms();
163 const size_t bytespp =
static_cast<size_t>(bitDepth) / 8;
165 for (
size_t row = 0; row < sizeY; ++row) {
166 const auto &yData = img->y(row);
167 for (
size_t col = 0; col < sizeX; ++col) {
170 pixelVal =
static_cast<uint8_t
>(yData[col]);
171 }
else if (16 == bitDepth) {
172 pixelVal =
static_cast<uint16_t
>(yData[col]);
173 }
else if (32 == bitDepth) {
174 pixelVal =
static_cast<uint32_t
>(yData[col]);
180 std::array<uint8_t, g_maxBytesPP> bytesPixel;
181 auto *iter =
reinterpret_cast<uint8_t *
>(&pixelVal);
182 std::reverse_copy(iter, iter + bytespp, bytesPixel.data());
184 file.write(
reinterpret_cast<const char *
>(bytesPixel.data()), bytespp);
190 static const std::vector<char> blanks(
g_maxLenHdr, 32);
192 auto count = hdr.size();
196 file.write(hdr.c_str(),
sizeof(
char) *
count);
202 const std::string sizeY =
std::to_string(img->getNumberHistograms());
204 const size_t fieldWidth = 20;
205 std::stringstream axis1;
206 axis1 <<
"NAXIS1 = " << std::setw(fieldWidth) << sizeX <<
" / length of data axis 1";
209 std::stringstream axis2;
210 axis2 <<
"NAXIS2 = " << std::setw(fieldWidth) << sizeY <<
" / length of data axis 2";
215 std::stringstream hdr;
230 static const std::vector<char> blanks(
g_maxLenHdr, 32);
232 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.