Skip to content

Commit

Permalink
src: Removed MapCommand_T class template.
Browse files Browse the repository at this point in the history
Type-specific MapCommand instances are no longer created during MaRC
input file parsing.  Type-specific operations are now deferred until
the MapCommand is actually executed.  This allows type related
decisions to be made internally without user input.

Upcoming changes will include the automatic type selection logic.
Related to #62.
  • Loading branch information
ossama-othman committed Aug 31, 2018
1 parent fa61aca commit 6afc680
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 236 deletions.
21 changes: 12 additions & 9 deletions doc/MaRC_input.texi
Original file line number Diff line number Diff line change
Expand Up @@ -440,10 +440,12 @@ does @strong{NOT} modify the data being stored in the output file in
anyway. It may, however, cause other applications that read the
output file to transform the data to their true/physical values. The
@code{DATA_OFFSET} entry must be entered immediately before the
@code{DATA_SCALE} entry. Immediately following these two keywords is
the @code{DATA_TYPE} keyword. The @code{DATA_TYPE} keyword is
required. It specifies the number format that the mapped data will be
stored as. Available data types are:
@code{DATA_SCALE} entry.

Immediately following these two keywords is the @code{DATA_TYPE}
keyword. The @code{DATA_TYPE} keyword is optional. It specifies the
number format that the mapped data will be stored as. Available data
types are:
@cindex @code{DATA_TYPE}
@cindex @code{BYTE}
@cindex @code{SHORT}
Expand Down Expand Up @@ -476,15 +478,16 @@ stored as. Available data types are:


@noindent
Be aware, for example, that a @code{DOUBLE} type map will occupy four
times as much memory and storage space then a @code{SHORT} type map of
the same dimensions. An example of how all three keywords are used
follows:
A @code{DATA_TYPE} will be automatically chosen based on the type of
images being mapped if one is not specified. Be aware, for example,
that a @code{DOUBLE} type map will occupy four times as much memory
and storage space then a @code{SHORT} type map of the same dimensions.
An example of how all three keywords are used follows:

@example
DATA_OFFSET: -1.3 # This is optional. The default is zero.
DATA_SCALE: 0.0001 # This is optional. The default is one.
DATA_TYPE: SHORT # This is required.
DATA_TYPE: SHORT # This is optional.
@end example

@node Lat/Lon Grid, Projections, Output Data, Input Files
Expand Down
3 changes: 1 addition & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ noinst_HEADERS = \
PhotoImageFactory.h \
MosaicImageFactory.h \
MapCommand.h \
MapCommand_T.h \
MapCommand_T.cpp \
MapCommand_t.cpp \
calc.h \
command_line.h \
parse_scan.h \
Expand Down
106 changes: 102 additions & 4 deletions src/MapCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
*/

#include "MapCommand.h"
#include "MapCommand_t.cpp"

#include "FITS_traits.h"
#include "FITS_memory.h"

Expand Down Expand Up @@ -72,6 +74,22 @@ namespace

return os.str();
}

/**
* @brief Validate given FITS BITBIX value.
*
* @retval true Valid @a bitpix value.
* @retval false Invalid @a bitpix value.
*/
bool valid_bitpix(int bitpix)
{
return bitpix == BYTE_IMG
|| bitpix == SHORT_IMG
|| bitpix == LONG_IMG
|| bitpix == LONGLONG_IMG
|| bitpix == FLOAT_IMG
|| bitpix == DOUBLE_IMG;
}
}


Expand All @@ -80,7 +98,8 @@ MaRC::MapCommand::MapCommand(std::string filename,
long samples,
long lines,
std::unique_ptr<MapFactory> factory)
: samples_(samples)
: bitpix_(0)
, samples_(samples)
, lines_(lines)
, factory_(std::move(factory))
, image_factories_()
Expand Down Expand Up @@ -265,7 +284,30 @@ MaRC::MapCommand::execute()
auto const start = std::chrono::high_resolution_clock::now();

// Create and write the map planes.
this->make_map_planes(fptr, status);
switch (this->bitpix()) {
case BYTE_IMG:
this->template make_map_planes<FITS::byte_type>(fptr, status);
break;
case SHORT_IMG:
this->template make_map_planes<FITS::short_type>(fptr, status);
break;
case LONG_IMG:
this->template make_map_planes<FITS::long_type>(fptr, status);
break;
case LONGLONG_IMG:
this->template make_map_planes<FITS::longlong_type>(fptr, status);
break;
case FLOAT_IMG:
this->template make_map_planes<FITS::float_type>(fptr, status);
break;
case DOUBLE_IMG:
this->template make_map_planes<FITS::double_type>(fptr, status);
break;
default:
// We should never get here.
MaRC::error("Unexpected BITPIX value\n");
return -1;
}

auto const end = std::chrono::high_resolution_clock::now();

Expand Down Expand Up @@ -486,11 +528,67 @@ MaRC::MapCommand::image_factories(image_factories_type factories)
this->image_factories_ = std::move(factories);
}

void
MaRC::MapCommand::initialize_FITS_image(fitsfile * fptr, int & status)
{
// The CFITSIO 'naxes' value is of type 'long'. It is extremely
// unlikely that a map with more than LONG_MAX planes will ever be
// created, so this implicit conversion should be safe.
long const planes = this->image_factories_.size();

int const naxis =
(planes > 1
? 3 /* 3 dimensions -- map "cube" */
: 2 /* 2 dimensions -- map "plane" */);

// Specify map cube dimensions. Note that in the two-dimensional
// map case, the third "planes" dimension will be ignored since
// the above "naxis" variable will be set to two, not three.
long naxes[] = { this->samples_, this->lines_, planes };

// Create the primary array.
(void) fits_create_img(fptr,
this->bitpix(),
naxis,
naxes,
&status);
}

void
MaRC::MapCommand::bitpix(int n)
{
// Zero means choose bitpix automatically.
if (n != 0 && !valid_bitpix(n))
throw std::invalid_argument("Invalid FITS BITPIX value");

this->bitpix_ = n;
}

int
MaRC::MapCommand::bitpix()
{
/**
* @bug Choose BITPIX value based on SourceImage, such as the
* BITPIX value in a PhotoImage, or a BITPIX for floating
* point values for VirtualImages with floating point
* values etc. Fixes #62.
*
* @todo Warn the user if the their desired BITPIX (map data type)
* is smaller than the data type in a photo. (e.g. 16 bits
* chosen vs 32 bits in photo). Fixes #72.
*/

// This should never happen!
if (!valid_bitpix(this->bitpix_))
throw std::runtime_error("Unable to determine BITPIX value.");

return this->bitpix_;
}

void
MaRC::MapCommand::write_virtual_image_facts(fitsfile * fptr,
std::size_t plane,
std::size_t num_planes,
int bitpix,
SourceImage const * image,
int & status)
{
Expand All @@ -512,7 +610,7 @@ MaRC::MapCommand::write_virtual_image_facts(fitsfile * fptr,
*/
// bitpix > 0: integer data
// bitpix < 0: floating point data
if (bitpix < 0)
if (this->bitpix() < 0)
return;

// The map contains integer type data meaning data was scaled to
Expand Down
43 changes: 31 additions & 12 deletions src/MapCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ namespace MaRC
MapCommand & operator=(MapCommand const &) = delete;

/// Destructor.
virtual ~MapCommand() = default;
~MapCommand() = default;

/// Execute the command.
int execute();
Expand All @@ -95,6 +95,9 @@ namespace MaRC
/// Get name of projection.
char const * projection_name() const;

/// Set map bits per pixel code.
void bitpix(int bitpix);

/// Set map author.
void author(std::string author);

Expand Down Expand Up @@ -163,6 +166,26 @@ namespace MaRC

protected:

/**
* @brief Get map FITS bits per pixel code.
*
* Obtain the bits per pixel "BITPIX" in the map FITS file, as
* defined by the FITS standard. This value may either be
* supplied by the user or determined at run-time based on
* source image data being mapped.
*
* @retval 8 8 bit unsigned integer data.
* @retval 16 16 bit signed integer data.
* @retval 32 32 bit signed integer data.
* @retval 64 64 bit signed integer data.
* @retval -32 32 bit floating point data.
* @retval -64 64 bit floating point data.
*
* @throw std::runtime_error Unable to determine bitpix
* value.
*/
int bitpix();

/// Write @c VirtualImage information to FITS file.
/**
* Write information specific to @c VirtualImage (e.g.
Expand All @@ -174,8 +197,6 @@ namespace MaRC
* @c VirtualImage.
* @param[in] num_planes Number of map planes being written
* to the FITS file.
* @param[in] bitpix Bits-per-pixel in the FITS file, as
* defined by the FITS standard.
* @param[in] image @c SourceImage object that may be a
* @c VirtualImage about which facts
* are being written to the FITS file.
Expand All @@ -184,7 +205,6 @@ namespace MaRC
void write_virtual_image_facts(fitsfile * fptr,
std::size_t plane,
std::size_t num_planes,
int bitpix,
SourceImage const * image,
int & status);

Expand All @@ -195,19 +215,15 @@ namespace MaRC
* @param[in] fptr CFITSIO pointer to the map FITS file.
* @param[out] status CFITSIO file operation status.
*/
virtual void initialize_FITS_image(fitsfile * fptr,
int & status) = 0;
void initialize_FITS_image(fitsfile * fptr, int & status);

/// Create and write map planes.
/**
* This is a "template method" (the design pattern, not a C++
* class template member) that performs type-specific map
* plane creation.
*
* @brief Create and write map planes.
* @param[in] fptr CFITSIO pointer to the map FITS file.
* @param[out] status CFITSIO file operation status.
*/
virtual void make_map_planes(fitsfile * fptr, int & status) = 0;
template <typename T>
void make_map_planes(fitsfile * fptr, int & status);

/// Create grid image.
/**
Expand Down Expand Up @@ -237,6 +253,9 @@ namespace MaRC

protected:

/// FITS bits per pixel (i.e. 8, 16, 32, 64, -32, or -64).
int bitpix_;

/// Number of samples in map.
long const samples_;

Expand Down
79 changes: 0 additions & 79 deletions src/MapCommand_T.h

This file was deleted.

Loading

0 comments on commit 6afc680

Please sign in to comment.