/***************************************************************************
* GFitsTableCol.cpp - FITS table column abstract base class *
* ----------------------------------------------------------------------- *
* copyright (C) 2008-2017 by Juergen Knoedlseder *
* ----------------------------------------------------------------------- *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see . *
* *
***************************************************************************/
/**
* @file GFitsTableCol.cpp
* @brief Abstract FITS table column class implementation
* @author Juergen Knoedlseder
*/
/* __ Includes ___________________________________________________________ */
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include "GException.hpp"
#include "GFitsCfitsio.hpp"
#include "GFitsTableCol.hpp"
#include "GTools.hpp"
/* __ Method name definitions ____________________________________________ */
#define G_ELEMENTS1 "GFitsTableCol::elements(int&, int&)"
#define G_ELEMENTS2 "GFitsTableCol::elements(int&)"
#define G_LOAD_COLUMN_FIXED "GFitsTableCol::load_column_fixed()"
#define G_LOAD_COLUMN_VARIABLE "GFitsTableCol::load_column_variable()"
#define G_SAVE_COLUMN_FIXED "GFitsTableCol::save_column_fixed()"
#define G_SAVE_COLUMN_VARIABLE "GFitsTableCol::save_column_variable()"
#define G_OFFSET "GFitsTableCol::offset(int&, int&)"
/* __ Macros _____________________________________________________________ */
/* __ Coding definitions _________________________________________________ */
/* __ Debug definitions __________________________________________________ */
//#define G_CALL_GRAPH //!< Dump call graph in console
#define G_PRINT_CONTENT //!< Print column content
/*==========================================================================
= =
= Constructors/destructors =
= =
==========================================================================*/
/***********************************************************************//**
* @brief Void constructor
***************************************************************************/
GFitsTableCol::GFitsTableCol(void)
{
// Initialise class members for clean destruction
init_members();
// Return
return;
}
/***********************************************************************//**
* @brief Column constructor
*
* @param[in] name Name of column.
* @param[in] nrows Number of rows in column.
* @param[in] number Number of elements in column (negative for variable-length).
* @param[in] width Width of one column element.
*
* Construct column instance from @p name, @p nrows, @p number of elements
* and @p width (or size) of one element. If @p number is negative, a
* variable-length column will be allocated. The repeat value, which is
* required for binary tables, is computed internally by multiplying the
* @p number by the @p width.
***************************************************************************/
GFitsTableCol::GFitsTableCol(const std::string& name,
const int& nrows,
const int& number,
const int& width)
{
// Initialise class members for clean destruction
init_members();
// Store attributes
if (number >= 0) { // fixed-length column
m_name = name;
m_length = nrows;
m_number = number;
m_width = width;
m_variable = false;
}
else { // variable-length column
m_name = name;
m_length = nrows;
m_number = 1;
m_width = width;
m_variable = true;
m_rowstart.assign(nrows+1, 0);
}
// Calculate repeat value (only used for binary table!)
m_repeat = m_number * m_width;
// Return
return;
}
/***********************************************************************//**
* @brief Copy constructor
*
* @param[in] column Column.
***************************************************************************/
GFitsTableCol::GFitsTableCol(const GFitsTableCol& column)
{
// Initialise class members for clean destruction
init_members();
// Copy members
copy_members(column);
// Return
return;
}
/***********************************************************************//**
* @brief Destructor
***************************************************************************/
GFitsTableCol::~GFitsTableCol(void)
{
// Free members
free_members();
// Return
return;
}
/*==========================================================================
= =
= Operators =
= =
==========================================================================*/
/***********************************************************************//**
* @brief Assignment operator
*
* @param[in] column Column.
* @return Column.
***************************************************************************/
GFitsTableCol& GFitsTableCol::operator=(const GFitsTableCol& column)
{
// Execute only if object is not identical
if (this != &column) {
// Free members
free_members();
// Initialise private members for clean destruction
init_members();
// Copy members
copy_members(column);
} // endif: object was not identical
// Return this object
return *this;
}
/*==========================================================================
= =
= Public methods =
= =
==========================================================================*/
/***********************************************************************//**
* @brief Set number of column elements for specific row
*
* @param[in] row Row index.
* @param[in] elements Number of elements in @p row.
*
* @exception GException::out_of_range
* Invalid row index specified.
* @exception GException::invalid_argument
* Invalid number of elements specified.
*
* Sets the number of elements in column for a specific @p row.
***************************************************************************/
void GFitsTableCol::elements(const int& row, const int& elements)
{
// Check row value
if (row < 0 || row >= nrows()) {
throw GException::out_of_range(G_ELEMENTS1, "Row index", row, nrows());
}
// Check that elements is non-negative
if (elements < 0) {
std::string msg = "Number of elements " + gammalib::str(elements) +
" can not be negative.\nPlease specify a"
" non-negative number of elements.";
throw GException::invalid_argument(G_ELEMENTS1, msg);
}
// First handle the case of a variable-length column
if (is_variable()) {
// Determine number of elements to add or to remove
int difference = elements - (m_rowstart[row+1] - m_rowstart[row]);
// If difference is positive, then add elements at the end of
// the vector. This is done using resize_data() which will insert
// "difference" elements at the index specified as first argument
if (difference > 0) {
resize_data(m_rowstart[row+1], difference);
}
// ... else if difference is negative then remove elements from
// the end of the array. This is done using resize_data() which
// will remove "difference" element from the index on specified as
// first argument
else if (difference < 0) {
resize_data(m_rowstart[row+1]+difference, difference);
}
// Update row start indices
for (int i = row + 1; i <= nrows(); ++i) {
m_rowstart[i] += difference;
}
// Update maximum column length
m_varlen = 0;
for (int i = 0; i < nrows(); ++i) {
int len = m_rowstart[row+1] - m_rowstart[row];
if (len > m_varlen) {
m_varlen = len;
}
}
} // endif: we had a variable-length column
// Return
return;
}
/***********************************************************************//**
* @brief Returns number of elements in column for specific row
*
* @param[in] row Row index.
* @return Number of elements in column at @p row.
*
* @exception GException::out_of_range
* Row index out of valid range.
*
* Returns the number of elements in the column for a specific @p row. For a
* fixed-length column the returned number is independent of the row. For a
* variable-length column the returned number is then length of the column
* for the specified row.
***************************************************************************/
int GFitsTableCol::elements(const int& row) const
{
// Check row value
if (row < 0 || row >= nrows()) {
throw GException::out_of_range(G_ELEMENTS2, "Row index", row, nrows());
}
// Get number of elements
int number = (m_variable) ? m_rowstart[row+1] - m_rowstart[row]
: m_number;
// Return number
return number;
}
/***********************************************************************//**
* @brief Returns TFORM code for binary table column
*
* Constructs the TFORM code for a binary table column, supporting
* fixed-length and variable-length column types.
***************************************************************************/
std::string GFitsTableCol::tform_binary(void) const
{
// Set type code string
std::string typecode = "";
switch (std::abs(type())) {
case __TBIT:
typecode = "X";
break;
case __TBYTE:
typecode = "B";
break;
case __TLOGICAL:
typecode = "L";
break;
case __TSTRING:
// If there are substrings then add width of substring
typecode = "A";
if (repeat() > width()) {
typecode.append(gammalib::str(width()));
}
break;
case __TUSHORT:
typecode = "U";
break;
case __TSHORT:
typecode = "I";
break;
case __TULONG:
typecode = "V";
break;
case __TLONG:
typecode = "J";
break;
case __TFLOAT:
typecode = "E";
break;
case __TLONGLONG:
typecode = "K";
break;
case __TDOUBLE:
typecode = "D";
break;
case __TCOMPLEX:
typecode = "C";
break;
case __TDBLCOMPLEX:
typecode = "M";
break;
default:
break;
}
// Build TFORM code
std::string tform;
if (std::abs(type()) == __TSTRING) {
tform.append(gammalib::str(repeat()));
}
else {
tform.append(gammalib::str(number()));
}
if (is_variable()) {
tform.append("P");
}
tform.append(typecode);
if (is_variable() && m_varlen > 0) {
tform.append("("+gammalib::str(m_varlen)+")");
}
// Return TFORM code
return tform;
}
/***********************************************************************//**
* @brief Set table column scale value
*
* @param[in] tscale Table column scale value.
* @param[in] tzero Table column scale value.
*
* Sets the table column scale values @p tscale and @p tzero. When reading
* FITS table column values, the true value is computed using
*
* \f[
* {\rm true value} = {\rm FITS value} \times {\tm tscale} + {\tm tzero}
* \f]
*
* Setting of the @p tscale and @p tzero values will only be effective if
* this is done before the first reading of a table column value. Also, the
* setting will not affect the TSCALE and TZERO keywords that may exist in
* the FITS header.
***************************************************************************/
void GFitsTableCol::scale(const double& tscale, const double& tzero) const
{
// Set tscale and tzero values
int status = 0;
status = __fftscl(FPTR(m_fitsfile), m_colnum, tscale, tzero, &status);
// Return
return;
}
/***********************************************************************//**
* @brief Print column information
*
* @param[in] chatter Chattiness.
* @return String containing column information.
*
* @todo Format and cfitsio information is mainly for debugging. This could
* vanish in a more stable version of the code, or it could be compiled-in
* conditionally using a debug option. Alternatively, a higher chatter level
* may be required to see this information.
***************************************************************************/
std::string GFitsTableCol::print(const GChatter& chatter) const
{
// Initialise result string
std::string result;
// Continue only if chatter is not silent
if (chatter != SILENT) {
// Append formatted column name. Optionally add units
if (unit().length() > 0) {
result.append(gammalib::parformat(name()+" ("+unit()+")"));
}
else {
result.append(gammalib::parformat(name()));
}
// Append column number. This will be "-" if the column does not exist
// in the FITS file.
if (m_colnum > 0) {
result.append(gammalib::right(gammalib::str(m_colnum),4)+" ");
}
else {
result.append(gammalib::right("[-]",4)+" ");
}
// Append loading information
if (is_loaded()) {
result.append("[loaded] ");
}
else {
result.append("[not loaded] ");
}
// Append format information
result.append("["+tform_binary()+","+ascii_format()+"]");
// Append dimensions (if available)
if (!dim().empty()) {
// Build TDIM string
std::string value = "("+gammalib::str(dim()[0]);
for (int k = 1; k < dim().size(); ++k) {
value += ","+gammalib::str(dim()[k]);
}
value += ")";
// Append
result.append(" "+value);
}
// Append cfitsio information
if (is_variable()) {
result.append(" repeat=" + gammalib::str(repeat()));
result.append(" width=" + gammalib::str(width()));
result.append(" number=" + gammalib::str(number()));
result.append(" rows=" + gammalib::str(nrows()));
result.append(" size=" + gammalib::str(m_size));
result.append(" varlen=");
if (m_varlen > 0) {
result.append(gammalib::str(m_varlen));
}
else {
result.append("undetermined");
}
}
else {
result.append(" repeat=" + gammalib::str(repeat()));
result.append(" width=" + gammalib::str(width()));
result.append(" number=" + gammalib::str(number()));
result.append(" rows=" + gammalib::str(nrows()));
result.append(" size=" + gammalib::str(m_size));
}
} // endif: chatter was not silent
// Compile option: print content
#if defined(G_PRINT_CONTENT)
if (chatter != SILENT) {
// Fetch data if necessary
if (!is_loaded()) fetch_data();
// Loop over all rows
for (int row = 0; row < nrows(); ++row) {
result.append("\n");
if (is_variable()) {
result.append("start=");
result.append(gammalib::str(m_rowstart[row]));
result.append(":");
}
for (int inx = 0; inx < elements(row); ++inx) {
result.append(" "+string(row, inx));
}
}
if (is_variable()) {
result.append("\nend=");
result.append(gammalib::str(m_rowstart[nrows()]));
}
}
#endif
// Return result
return result;
}
/*==========================================================================
= =
= Protected methods =
= =
==========================================================================*/
/***********************************************************************//**
* @brief Save table column into FITS file
*
* Refer to GFitsTableCol::save_column() for more information.
***************************************************************************/
void GFitsTableCol::save(void)
{
// Save column
save_column();
// Return
return;
}
/***********************************************************************//**
* @brief Load table column from FITS file
*
* Loads table column from FITS file by calling the load_column_variable()
* method for variable-length columns and load_column_fixed() for fixed-
* length columns.
***************************************************************************/
void GFitsTableCol::load_column(void)
{
// Load variable-length or fixed-length column from FITS file
if (is_variable()) {
load_column_variable();
}
else {
load_column_fixed();
}
// Return
return;
}
/***********************************************************************//**
* @brief Load fixed-length column from FITS file
*
* @exception GException::fits_hdu_not_found
* Specified HDU not found in FITS file.
* @exception GException::fits_error
* An error occured while loading column data from FITS file.
*
* If a FITS file is attached to the column the data are loaded into memory
* from the FITS file. If no FITS file is attached, memory is allocated
* to hold the column data and all cells are set to 0.
*
* The method makes use of the virtual methods
* GFitsTableCol::alloc_data,
* GFitsTableCol::init_data,
* GFitsTableCol::ptr_data, and
* GFitsTableCol::ptr_nulval.
* These methods are implemented by the derived column classes which
* implement a specific storage class (i.e. float, double, short, ...).
***************************************************************************/
void GFitsTableCol::load_column_fixed(void)
{
// Calculate size of memory
m_size = m_number * m_length;
// Load only if the column has a positive size
if (m_size > 0) {
// Allocate and initialise fresh memory
alloc_data();
init_data();
// If a FITS file is attached then try loading column data from the
// FITS file. This may fail in case that no data has yet been written
// to the FITS file. In that case we just skip loading and return
// the initalised column ...
if (FPTR(m_fitsfile)->Fptr != NULL) {
// Move to the HDU
int status = 0;
status = __ffmahd(FPTR(m_fitsfile),
(FPTR(m_fitsfile)->HDUposition)+1,
NULL, &status);
// If this failed because:
// - the primary HDU was not found (status 252)
// - we moved past the file (status 107)
// we assume that no data have yet been written to the file and
// we skip the loading.
if (status != 252 && status != 107) {
// Break on any other cfitsio error
if (status != 0) {
throw GException::fits_hdu_not_found(G_LOAD_COLUMN_FIXED,
(FPTR(m_fitsfile)->HDUposition)+1,
status);
}
// Load data
status = __ffgcv(FPTR(m_fitsfile), m_type, m_colnum,
1, 1, m_size, ptr_nulval(), ptr_data(),
&m_anynul, &status);
if (status != 0) {
throw GException::fits_error(G_LOAD_COLUMN_FIXED, status,
"for column '"+m_name+"'.");
}
} // endif: no primary HDU found
} // endif: there was a FITS file attached
} // endif: column has a positive size
// Return
return;
}
/***********************************************************************//**
* @brief Load variable-length column from FITS file
*
* @exception GException::fits_hdu_not_found
* Specified HDU not found in FITS file.
* @exception GException::fits_error
* An error occured while loading column data from FITS file.
*
* If a FITS file is attached to the column the data are loaded into memory
* from the FITS file. If no FITS file is attached, memory is allocated
* to hold the column data and all cells are set to 0.
*
* The method makes use of the virtual methods
* GFitsTableCol::alloc_data,
* GFitsTableCol::init_data,
* GFitsTableCol::ptr_data, and
* GFitsTableCol::ptr_nulval.
* These methods are implemented by the derived column classes which
* implement a specific storage class (i.e. float, double, short, ...).
***************************************************************************/
void GFitsTableCol::load_column_variable(void)
{
// If a FITS file is attached then try loading column data from the
// FITS file. This may fail in case that no data has yet been written
// to the FITS file. In that case we just skip loading and return
// the initalised column ...
if (FPTR(m_fitsfile)->Fptr != NULL) {
// Move to the HDU
int status = 0;
status = __ffmahd(FPTR(m_fitsfile),
(FPTR(m_fitsfile)->HDUposition)+1,
NULL,
&status);
// If this failed because:
// - the primary HDU was not found (status 252)
// - we moved past the file (status 107)
// we assume that no data have yet been written to the file and
// we skip the loading.
if (status != 252 && status != 107) {
// Break on any other cfitsio error
if (status != 0) {
throw GException::fits_hdu_not_found(G_LOAD_COLUMN_VARIABLE,
(FPTR(m_fitsfile)->HDUposition)+1,
status);
}
// Allocate rowstart array
m_rowstart.assign(m_length+1, 0);
// Determine the column length for each row by looping over
// all rows and derive the total memory requirement
m_size = 0;
m_varlen = 0;
m_rowstart[0] = 0;
for (int row = 0; row < m_length; ++row) {
// Initialise offset and repeat
long offset(0);
long repeat(0);
// Get variable-length of row in repeat
status = __ffgdes(FPTR(m_fitsfile),
m_colnum,
row+1,
&repeat,
&offset,
&status);
if (status != 0) {
std::string msg = "Unable to get descriptor of row "+
gammalib::str(row+1)+" of column '"+
name()+"' from FITS file.";
throw GException::fits_error(G_LOAD_COLUMN_VARIABLE, status,
msg);
}
// Store start of next row
m_rowstart[row+1] = m_rowstart[row] + repeat;
m_size += repeat;
if (repeat > m_varlen) {
m_varlen = repeat;
}
} // endfor: looped over all rows
// Allocate and initialise fresh memory
alloc_data();
init_data();
// Load data for each row
for (int row = 0; row < m_length; ++row) {
// Initialise anynul
int anynul(0);
// Load data
status = __ffgcv(FPTR(m_fitsfile),
std::abs(m_type),
m_colnum,
row+1,
1,
elements(row),
ptr_nulval(),
ptr_data(m_rowstart[row]),
&anynul,
&status);
if (status != 0) {
std::string msg = "Unable to load row "+gammalib::str(row+1)+""
" of column '"+name()+"' from FITS file.";
throw GException::fits_error(G_LOAD_COLUMN_VARIABLE, status,
msg);
}
// Increment anynul
m_anynul += anynul;
} // endfor: looped over all rows
} // endif: no primary HDU found
} // endif: there was a FITS file attached
// Return
return;
}
/***********************************************************************//**
* @brief Save table column into FITS file
*
* Save table column into FITS file by calling the save_column_variable()
* method for variable-length columns and save_column_fixed() for fixed-
* length columns.
***************************************************************************/
void GFitsTableCol::save_column(void)
{
// Save variable-length or fixed-length column into FITS file
if (is_variable()) {
save_column_variable();
}
else {
save_column_fixed();
}
// Return
return;
}
/***********************************************************************//**
* @brief Save table column into FITS file
*
* @exception GException::fits_hdu_not_found
* Specified HDU not found in FITS file.
* @exception GException::fits_error
* Error occured during writing of the column data.
*
* The table column is only saved if it is linked to a FITS file and if the
* data are indeed present in the class instance. This avoids saving of data
* that have not been modified.
*
* The method make use of the virtual methods
* GFitsTableCol::ptr_data and
* GFitsTableCol::ptr_nulval.
* These methods are implemented by the derived column classes which
* implement a specific storage class (i.e. float, double, short, ...).
***************************************************************************/
void GFitsTableCol::save_column_fixed(void)
{
// Continue only if a FITS file is connected and data have been loaded
if (FPTR(m_fitsfile)->Fptr != NULL && m_colnum > 0 && ptr_data() != NULL) {
// Move to the HDU
int status = 0;
status = __ffmahd(FPTR(m_fitsfile),
(FPTR(m_fitsfile)->HDUposition)+1, NULL,
&status);
if (status != 0) {
throw GException::fits_hdu_not_found(G_SAVE_COLUMN_FIXED,
(FPTR(m_fitsfile)->HDUposition)+1,
status);
}
// Save the column data
status = __ffpcn(FPTR(m_fitsfile), m_type, m_colnum, 1, 1,
m_size, ptr_data(), ptr_nulval(), &status);
if (status != 0) {
std::string msg = "Unable to save column '"+name()+"' to"
" FITS file.";
throw GException::fits_error(G_SAVE_COLUMN_FIXED, status, msg);
}
} // endif: FITS file was connected
// Return
return;
}
/***********************************************************************//**
* @brief Save table column into FITS file
*
* @exception GException::fits_hdu_not_found
* Specified HDU not found in FITS file.
* @exception GException::fits_error
* Error occured during writing of the column data.
*
* The table column is only saved if it is linked to a FITS file and if the
* data are indeed present in the class instance. This avoids saving of data
* that have not been modified.
*
* The method make use of the virtual methods
* GFitsTableCol::ptr_data and
* GFitsTableCol::ptr_nulval.
* These methods are implemented by the derived column classes which
* implement a specific storage class (i.e. float, double, short, ...).
***************************************************************************/
void GFitsTableCol::save_column_variable(void)
{
// Continue only if a FITS file is connected and data have been loaded
if (FPTR(m_fitsfile)->Fptr != NULL && m_colnum > 0 && ptr_data() != NULL) {
// Move to the HDU
int status = 0;
status = __ffmahd(FPTR(m_fitsfile),
(FPTR(m_fitsfile)->HDUposition)+1, NULL,
&status);
if (status != 0) {
throw GException::fits_hdu_not_found(G_SAVE_COLUMN_VARIABLE,
(FPTR(m_fitsfile)->HDUposition)+1,
status);
}
// Save the column data row-by-row
for (int row = 0; row < m_length; ++row) {
// Save row data
status = __ffpcn(FPTR(m_fitsfile),
std::abs(m_type),
m_colnum,
row+1,
1,
elements(row),
ptr_data(m_rowstart[row]),
ptr_nulval(),
&status);
if (status != 0) {
std::string msg = "Unable to save row "+gammalib::str(row+1)+""
" of column '"+name()+"' to FITS file.";
throw GException::fits_error(G_SAVE_COLUMN_VARIABLE, status,
msg);
}
} // endfor: looped over rows
} // endif: FITS file was connected
// Return
return;
}
/***********************************************************************//**
* @brief Compute offset of column element in memory
*
* @param[in] row Row of column.
* @param[in] inx Vector index in column row.
*
* @exception GException::out_of_range
* Table row or vector index are out of valid range.
*
* Computes the offset of a column element in the storage array from the
* @p row number and the vector index. The method also supports both
* variable-length and fixed-length columns.
***************************************************************************/
int GFitsTableCol::offset(const int& row, const int& inx) const
{
// Check row value
#if defined(G_RANGE_CHECK)
if (row < 0 || row >= m_length) {
throw GException::out_of_range(G_OFFSET, row, 0, m_length-1);
}
#endif
// Check inx value
#if defined(G_RANGE_CHECK)
if (inx < 0 || inx >= elements(row)) {
throw GException::out_of_range(G_OFFSET, inx, 0, elements(row));
}
#endif
// Calculate pixel offset
int offset = (is_variable()) ? m_rowstart[row] + inx : row * m_number + inx;
// Return offset
return offset;
}
/*==========================================================================
= =
= Private methods =
= =
==========================================================================*/
/***********************************************************************//**
* @brief Initialise class members
***************************************************************************/
void GFitsTableCol::init_members(void)
{
// Optionally print call graph
#if defined(G_CALL_GRAPH)
printf("GFitsTableCol::init_members\n");
#endif
// Allocate FITS file pointer
m_fitsfile = new __fitsfile;
FPTR(m_fitsfile)->HDUposition = 0;
FPTR(m_fitsfile)->Fptr = NULL;
// Initialise members
m_name.clear();
m_unit.clear();
m_dim.clear();
m_rowstart.clear();
m_colnum = 0;
m_type = 0;
m_repeat = 0;
m_width = 0;
m_number = 0;
m_length = 0;
m_variable = false;
m_varlen = 0;
m_size = 0;
m_anynul = 0;
// Optionally print call graph
#if defined(G_CALL_GRAPH)
printf("exit GFitsTableCol::init_members\n");
#endif
// Return
return;
}
/***********************************************************************//**
* @brief Copy class members
*
* @param[in] column Column to be copied.
***************************************************************************/
void GFitsTableCol::copy_members(const GFitsTableCol& column)
{
// Copy attributes
m_name = column.m_name;
m_unit = column.m_unit;
m_dim = column.m_dim;
m_colnum = column.m_colnum;
m_type = column.m_type;
m_repeat = column.m_repeat;
m_width = column.m_width;
m_number = column.m_number;
m_length = column.m_length;
m_variable = column.m_variable;
m_varlen = column.m_varlen;
m_rowstart = column.m_rowstart;
m_size = column.m_size;
m_anynul = column.m_anynul;
FPTR_COPY(m_fitsfile, column.m_fitsfile);
// Return
return;
}
/***********************************************************************//**
* @brief Delete class members
***************************************************************************/
void GFitsTableCol::free_members(void)
{
// Optionally print call graph
#if defined(G_CALL_GRAPH)
printf("GFitsTableCol::free_members\n");
#endif
// Free memory
if (m_fitsfile != NULL) delete FPTR(m_fitsfile);
// Mark memory as free
m_fitsfile = NULL;
// Optionally print call graph
#if defined(G_CALL_GRAPH)
printf("exit GFitsTableCol::free_members\n");
#endif
// Return
return;
}
/***********************************************************************//**
* @brief Connect table column to FITS file
*
* @param[in] vptr Column file void pointer.
*
* A table column is connected to a FITS file when the m_fitsfile holds a
* FITS file pointer. In that way, the column knows to which file it belongs.
***************************************************************************/
void GFitsTableCol::connect(void* vptr)
{
// Connect table column by copying the column file pointer
FPTR_COPY(m_fitsfile, vptr);
// Return
return;
}