Skip to content

Commit

Permalink
Added Unit Tests for FITS module along with some minor bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
gopi487krishna committed Jul 23, 2020
1 parent 8caea42 commit 056c741
Show file tree
Hide file tree
Showing 21 changed files with 4,941 additions and 683 deletions.
163 changes: 66 additions & 97 deletions include/boost/astronomy/io/ascii_table.hpp
Expand Up @@ -43,6 +43,14 @@ namespace boost { namespace astronomy { namespace io {
struct ascii_table : public table_extension
{
public:

/**
* @brief Creates a standalone ascii_table object
*/
ascii_table() {}

/**
/**
* @brief Constructs an ascii_table object from the given filestream
* @details This constructor constructs an ASCII_table object by reading the
Expand All @@ -65,7 +73,7 @@ struct ascii_table : public table_extension
* @param[in] other hdu object containing the header information of the current extension HDU
* @note After the reading the file pointer/cursor will be set to the end of logical HDU unit
*/
ascii_table(std::fstream &file, hdu const& other) : table_extension(file, other)
ascii_table(std::fstream &file, hdu const& other) : table_extension(other)
{
set_ascii_table_info(file);
set_unit_end(file);
Expand All @@ -92,144 +100,98 @@ struct ascii_table : public table_extension
*/
void populate_column_data()
{
for (std::size_t i = 0; i < this->tfields; i++)
for (std::size_t i = 0; i < this->tfields_; i++)
{
col_metadata[i].index(i + 1);
col_metadata_[i].index(i + 1);

col_metadata[i].TFORM(
col_metadata_[i].TFORM(
value_of<std::string>("TFORM" + boost::lexical_cast<std::string>(i + 1))
);

col_metadata[i].TBCOL(
col_metadata_[i].TBCOL(
value_of<std::size_t>("TBCOL" + boost::lexical_cast<std::string>(i + 1))
);

try {
col_metadata[i].TTYPE(
col_metadata_[i].TTYPE(
value_of<std::string>("TTYPE" + boost::lexical_cast<std::string>(i + 1))
);

col_metadata[i].comment(
value_of<std::string>(col_metadata[i].TTYPE())
col_metadata_[i].comment(
value_of<std::string>(col_metadata_[i].TTYPE())
);
}
catch (std::out_of_range e) {/*Do Nothing*/ }
catch (std::out_of_range&) {/*Do Nothing*/ }

try {
col_metadata[i].TUNIT(
col_metadata_[i].TUNIT(
value_of<std::string>("TUNIT" + boost::lexical_cast<std::string>(i + 1))
);
}
catch (std::out_of_range e) {/*Do Nothing*/ }
catch (std::out_of_range&) {/*Do Nothing*/ }

try {
col_metadata[i].TSCAL(
col_metadata_[i].TSCAL(
value_of<double>("TSCAL" + boost::lexical_cast<std::string>(i + 1))
);
}
catch (std::out_of_range e) {/*Do Nothing*/ }
catch (std::out_of_range&) {/*Do Nothing*/ }

try {
col_metadata[i].TZERO(
col_metadata_[i].TZERO(
value_of<double>("TZERO" + boost::lexical_cast<std::string>(i + 1))
);
}
catch (std::out_of_range e) {/*Do Nothing*/ }
catch (std::out_of_range&) {/*Do Nothing*/ }
}
}

/**
* @brief Reads the data associated with ASCII_Table extension HDU from the filestream
* @param[in,out] file filestream set to open mode for reading
* @note After the reading the file pointer/cursor will be set to the end of logical HDU unit
* @brief Returns the data of ASCII table
*/
void read_data(std::fstream &file)
{
file.read(&data[0], naxis(1)*naxis(2));
set_unit_end(file);
}
std::vector<char>& get_data() { return data_; }

/**
* @brief Returns the data of ASCII table (const version)
*/
const std::vector<char>& get_data() const { return data_; }

/**
* @brief Gets the metadata along with value(field_value) for every row of specified field
* @details This methods takes a field name as argument and returns the metadata information
* of the field along with the field value for all the rows in the table.
* @param[in] name Name of the field
* @return Returns the metadata along with value for every row of specified field
* @todo From what i feel so far this function provides returns empty column
*/
std::unique_ptr<column> get_column(std::string name) const
{
for (auto& col : col_metadata)
{
if (col.TTYPE() == name)
{
switch (get_type(col.TFORM()))
{
case 'A':
{
auto result = std::make_unique<column_data<char>>(col);
fill_column(result->get_data(), col.TBCOL(), column_size(col.TFORM()),
[](char const* element) -> char {
return *element;
}
);
std::unique_ptr<column> get_column(std::string column_name) const {
for (auto col : col_metadata_) {
if (col.TTYPE() == column_name) {
switch (get_type(col.TFORM())) {
case 'A': {
auto result = std::make_unique<column_data<std::string>>(col);
fill_column<std::string>(result->get_data(), col);
return std::move(result);
}
case 'I':
{
auto result = std::make_unique<column_data<std::int32_t>>(col);
fill_column(result->get_data(), col.TBCOL(), column_size(col.TFORM()),
[](char const* element) -> std::int32_t {
return boost::endian::big_to_native(*reinterpret_cast<const std::int32_t*>(element));
}
);
case 'I': {
auto result = std::make_unique<column_data<boost::int32_t>>(col);
fill_column<boost::int32_t>(result->get_data(), col);
return std::move(result);
}
case 'F':
{
auto result = std::make_unique<column_data<float>>(col);
fill_column(result->get_data(), col.TBCOL(), column_size(col.TFORM()),
[](char const* element) -> float {
float result = (element[3] << 0) | (element[2] << 8) |
(element[1] << 16) | (element[0] << 24);
return result;
}
);
case 'F': // Floating Point only hence fallthrough
case 'E': {
auto result = std::make_unique<column_data<boost::float32_t>>(col);
fill_column<boost::float32_t>(result->get_data(), col);
return std::move(result);
}
case 'E':
{
auto result = std::make_unique<column_data<float>>(col);
fill_column(result->get_data(), col.TBCOL(), column_size(col.TFORM()),
[](char const* element) -> float {
float result = (element[3] << 0) | (element[2] << 8) |
(element[1] << 16) | (element[0] << 24);
return result;
}
);
case 'D': {
auto result = std::make_unique<column_data<boost::float64_t>>(col);
fill_column<boost::float64_t>(result->get_data(), col);
return std::move(result);
}
case 'D':
{
auto result = std::make_unique<column_data<double>>(col);
fill_column(result->get_data(), col.TBCOL(), column_size(col.TFORM()),
[](char const* element) -> double {
double result = (element[7] << 0) | (element[6] << 8) |
(element[5] << 16) | (element[4] << 24) |
(element[3] << 32) | (element[2] << 40) |
(element[1] << 48) | (element[0] << 56);
return result;
}
);
return std::move(result);
}
default:
throw invalid_table_colum_format();
}
}
}

return std::unique_ptr<column>(nullptr);
return nullptr;
}

/**
Expand All @@ -242,8 +204,8 @@ struct ascii_table : public table_extension
std::string form = boost::trim_copy_if(format, [](char c) -> bool {
return c == '\'' || c == ' ';
});
int decimal = form.length();
for(int i = 0; i < form.length(); i++)
int decimal = static_cast<int>(form.length());
for(int i = 0; i < static_cast<int>(form.length()); i++)
{
if(form[i] == '.')
{
Expand Down Expand Up @@ -279,30 +241,37 @@ struct ascii_table : public table_extension
* @param[in] lambda Lambda function for fetching the field data from data buffer
* @todo Why is column size present there
*/
template<typename VectorType, typename Lambda>
template<typename ColDataType, typename VectorType>
void fill_column
(
std::vector<VectorType> &column_container,
std::size_t start,
std::size_t column_size,
Lambda lambda
const column& col_metadata
) const
{
column_container.reserve(naxis(2));
for (std::size_t i = 0; i < naxis(2); i++)
{
column_container.emplace_back(lambda(this->data.data() + (i * naxis(1) + start)));
for (std::size_t i = 0; i < naxis(2); i++) {
auto starting_offset =
this->data_.begin() + i * naxis(1) + col_metadata.TBCOL();

auto ending_offset = starting_offset + column_size(col_metadata.TFORM());

std::string row_data_str(starting_offset, ending_offset + 1);

ColDataType row_data = boost::lexical_cast<ColDataType>(
boost::algorithm::trim_copy(row_data_str));

column_container.emplace_back(row_data);
}
}

private:
/**
* @brief Initializes the current object with column metadata and table data
*/
void set_ascii_table_info(std::fstream& file)
{
populate_column_data();
std::copy_n(std::istream_iterator<char>(file), naxis(1) * naxis(2), std::back_inserter(data));
std::copy_n(std::istreambuf_iterator<char>(file), naxis(1) * naxis(2),
std::back_inserter(data_));

}

Expand Down

0 comments on commit 056c741

Please sign in to comment.