GammaLib  1.7.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GFitsTableUShortCol.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GFitsTableUShortCol.cpp - FITS table unsigned short integer column class*
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2010-2017 by Juergen Knoedlseder *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 /**
22  * @file GFitsTableUShortCol.cpp
23  * @brief FITS table unsigned short integer column class implementation
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <string>
32 #include "GException.hpp"
33 #include "GTools.hpp"
34 #include "GFitsCfitsio.hpp"
35 #include "GFitsTableUShortCol.hpp"
36 
37 /* __ Method name definitions ____________________________________________ */
38 #define G_INSERT "GFitsTableUShortCol::insert(int&, int&)"
39 #define G_REMOVE "GFitsTableUShortCol::remove(int&, int&)"
40 
41 /* __ Macros _____________________________________________________________ */
42 
43 /* __ Coding definitions _________________________________________________ */
44 
45 /* __ Debug definitions __________________________________________________ */
46 
47 
48 /*==========================================================================
49  = =
50  = Constructors/destructors =
51  = =
52  ==========================================================================*/
53 
54 /***********************************************************************//**
55  * @brief Constructor
56  ***************************************************************************/
58 {
59  // Initialise class members for clean destruction
60  init_members();
61 
62  // Return
63  return;
64 }
65 
66 
67 /***********************************************************************//**
68  * @brief Constructor
69  *
70  * @param[in] name Name of column.
71  * @param[in] nrows Number of rows in column.
72  * @param[in] size Vector size of column.
73  ***************************************************************************/
75  const int& nrows,
76  const int& size) :
77  GFitsTableCol(name, nrows, size, 2)
78 {
79  // Initialise class members for clean destruction
80  init_members();
81 
82  // Return
83  return;
84 }
85 
86 
87 /***********************************************************************//**
88  * @brief Copy constructor
89  *
90  * @param[in] column Table column.
91  ***************************************************************************/
93  GFitsTableCol(column)
94 {
95  // Initialise class members for clean destruction
96  init_members();
97 
98  // Copy members
99  copy_members(column);
100 
101  // Return
102  return;
103 }
104 
105 
106 /***********************************************************************//**
107  * @brief Destructor
108  ***************************************************************************/
110 {
111  // Free members
112  free_members();
113 
114  // Return
115  return;
116 }
117 
118 
119 /*==========================================================================
120  = =
121  = Operators =
122  = =
123  ==========================================================================*/
124 
125 /***********************************************************************//**
126  * @brief Assignment operator
127  *
128  * @param[in] column Table column.
129  ***************************************************************************/
131 {
132  // Execute only if object is not identical
133  if (this != &column) {
134 
135  // Copy base class members
136  this->GFitsTableCol::operator=(column);
137 
138  // Free members
139  free_members();
140 
141  // Initialise private members for clean destruction
142  init_members();
143 
144  // Copy members
145  copy_members(column);
146 
147  } // endif: object was not identical
148 
149  // Return this object
150  return *this;
151 }
152 
153 
154 /***********************************************************************//**
155  * @brief Column data access operator
156  *
157  * @param[in] row Row of column to access.
158  * @param[in] inx Vector index in column row to access
159  *
160  * Provides access to data in a column.
161  ***************************************************************************/
162 unsigned short& GFitsTableUShortCol::operator()(const int& row, const int& inx)
163 {
164  // If data are not available then load them now
165  if (m_data == NULL) fetch_data();
166 
167  // Return data bin
168  return m_data[offset(row, inx)];
169 }
170 
171 
172 /***********************************************************************//**
173  * @brief Column data access operator (const variant)
174  *
175  * @param[in] row Row of column to access.
176  * @param[in] inx Vector index in column row to access
177  *
178  * Provides access to data in a column.
179  ***************************************************************************/
180 const unsigned short& GFitsTableUShortCol::operator()(const int& row, const int& inx) const
181 {
182  // If data are not available then load them now
183  if (m_data == NULL) fetch_data();
184 
185  // Return data bin
186  return m_data[offset(row, inx)];
187 }
188 
189 
190 /*==========================================================================
191  = =
192  = Public methods =
193  = =
194  ==========================================================================*/
195 
196 /***********************************************************************//**
197  * @brief Clear instance
198  *
199  * This method properly resets the object to an initial state.
200  ***************************************************************************/
202 {
203  // Free class members (base and derived classes, derived class first)
204  free_members();
206 
207  // Initialise members
209  init_members();
210 
211  // Return
212  return;
213 }
214 
215 
216 /***********************************************************************//**
217  * @brief Clone column
218  ***************************************************************************/
220 {
221  return new GFitsTableUShortCol(*this);
222 }
223 
224 
225 /***********************************************************************//**
226  * @brief Get string value
227  *
228  * @param[in] row Table row.
229  * @param[in] inx Table column vector index.
230  *
231  * Returns value of specified row and vector index as string.
232  ***************************************************************************/
233 std::string GFitsTableUShortCol::string(const int& row, const int& inx) const
234 {
235  // If data are not available then load them now
236  if (m_data == NULL) fetch_data();
237 
238  // Return value
239  return (gammalib::str(m_data[offset(row,inx)]));
240 }
241 
242 
243 /***********************************************************************//**
244  * @brief Get double precision value
245  *
246  * @param[in] row Table row.
247  * @param[in] inx Table column vector index.
248  *
249  * Returns value of specified row and vector index as double precision.
250  ***************************************************************************/
251 double GFitsTableUShortCol::real(const int& row, const int& inx) const
252 {
253  // If data are not available then load them now
254  if (m_data == NULL) fetch_data();
255 
256  // Convert unsigned short into double
257  double value = (double)m_data[offset(row,inx)];
258 
259  // Return value
260  return value;
261 }
262 
263 
264 /***********************************************************************//**
265  * @brief Get integer value
266  *
267  * @param[in] row Table row.
268  * @param[in] inx Table column vector index.
269  *
270  * Returns value of specified row and vector index as integer.
271  ***************************************************************************/
272 int GFitsTableUShortCol::integer(const int& row, const int& inx) const
273 {
274  // If data are not available then load them now
275  if (m_data == NULL) fetch_data();
276 
277  // Convert unsigned short into int
278  int value = (int)m_data[offset(row,inx)];
279 
280  // Return value
281  return value;
282 }
283 
284 
285 /***********************************************************************//**
286  * @brief Insert rows in column
287  *
288  * @param[in] row Row after which rows should be inserted (0=first row).
289  * @param[in] nrows Number of rows to be inserted.
290  *
291  * @exception GException::fits_invalid_row
292  * Specified row is invalid.
293  *
294  * Inserts rows into a FITS table. This implies that all columns will be
295  * loaded into memory.
296  ***************************************************************************/
297 void GFitsTableUShortCol::insert(const int& row, const int& nrows)
298 {
299  // Make sure that row is valid
300  if (row < 0 || row > m_length) {
301  throw GException::fits_invalid_row(G_INSERT, row, m_length);
302  }
303 
304  // Continue only if there are rows to be inserted
305  if (nrows > 0) {
306 
307  // If we have no rows yet then simply set the length to the
308  // number of rows to be inserted
309  if (m_length == 0) {
310  m_length = nrows;
312  alloc_data();
313  init_data();
314  }
315 
316  // ... otherwise fetch data, allocate new data and copy over
317  // the existing items
318  else {
319 
320  // If data are not available then load them now
321  if (m_data == NULL) fetch_data();
322 
323  // Compute new column length
324  int length = m_length + nrows;
325 
326  // Calculate size of new memory
327  m_size = m_number * length;
328 
329  // Allocate new data to hold the column
330  unsigned short* new_data = new unsigned short[m_size];
331 
332  // Compute the number of elements before the insertion point,
333  // the number of elements that get inserted, and the total
334  // number of elements after the insertion point
335  int n_before = m_number * row;
336  int n_insert = m_number * nrows;
337  int n_after = m_number * (m_length - row);
338 
339  // Copy and initialise data
340  unsigned short* src = m_data;
341  unsigned short* dst = new_data;
342  for (int i = 0; i < n_before; ++i) {
343  *dst++ = *src++;
344  }
345  for (int i = 0; i < n_insert; ++i) {
346  *dst++ = 0;
347  }
348  for (int i = 0; i < n_after; ++i) {
349  *dst++ = *src++;
350  }
351 
352  // Free old data
353  if (m_data != NULL) delete [] m_data;
354 
355  // Set pointer to new data and store length
356  m_data = new_data;
357  m_length = length;
358 
359  } // endelse: there were already data
360 
361  } // endfor: there were rows to be inserted
362 
363  // Return
364  return;
365 }
366 
367 
368 /***********************************************************************//**
369  * @brief Remove rows from column
370  *
371  * @param[in] row Row after which rows should be removed (0=first row).
372  * @param[in] nrows Number of rows to be removed.
373  *
374  * @exception GException::fits_invalid_row
375  * Specified row is invalid.
376  * @exception GException::fits_invalid_nrows
377  * Invalid number of rows specified.
378  *
379  * This method removes rows from a FITS table. This implies that the column
380  * will be loaded into memory.
381  ***************************************************************************/
382 void GFitsTableUShortCol::remove(const int& row, const int& nrows)
383 {
384  // Make sure that row is valid
385  if (row < 0 || row >= m_length) {
387  }
388 
389  // Make sure that we don't remove beyond the limit
390  if (nrows < 0 || nrows > m_length-row) {
392  }
393 
394  // Continue only if there are rows to be removed
395  if (nrows > 0) {
396 
397  // If data are not available then load them now
398  if (m_data == NULL) fetch_data();
399 
400  // Compute new column length
401  int length = m_length - nrows;
402 
403  // Calculate size of new memory
404  m_size = m_number * length;
405 
406  // If we have rows remaining then allocate new data to hold
407  // the column
408  if (m_size > 0) {
409 
410  // Allocate new data to hold the column
411  unsigned short* new_data = new unsigned short[m_size];
412 
413  // Compute the number of elements before the removal point,
414  // the number of elements that get removed, and the total
415  // number of elements after the removal point
416  int n_before = m_number * row;
417  int n_remove = m_number * nrows;
418  int n_after = m_number * (length - row);
419 
420  // Copy data
421  unsigned short* src = m_data;
422  unsigned short* dst = new_data;
423  for (int i = 0; i < n_before; ++i) {
424  *dst++ = *src++;
425  }
426  src += n_remove;
427  for (int i = 0; i < n_after; ++i) {
428  *dst++ = *src++;
429  }
430 
431  // Free old data
432  if (m_data != NULL) delete [] m_data;
433 
434  // Set pointer to new data and store length
435  m_data = new_data;
436  m_length = length;
437 
438  } // endif: there are still elements after removal
439 
440  // ... otherwise just remove all data
441  else {
442 
443  // Free old data
444  if (m_data != NULL) delete [] m_data;
445 
446  // Set pointer to new data and store length
447  m_data = NULL;
448  m_length = length;
449  }
450 
451  } // endfor: there were rows to be removed
452 
453  // Return
454  return;
455 }
456 
457 
458 /***********************************************************************//**
459  * @brief Set nul value
460  *
461  * @param[in] value Nul value.
462  *
463  * @todo To correctly reflect the nul value in the data, the column should
464  * be reloaded. However, the column may have been changed, so in principle
465  * saving is needed. However, we may not want to store the data, hence saving
466  * is also not desired. We thus have to develop a method to update the
467  * column information for a new nul value in place ...
468  ***************************************************************************/
469 void GFitsTableUShortCol::nulval(const unsigned short* value)
470 {
471  // Allocate nul value
472  alloc_nulval(value);
473 
474  // Update column
475 // if (m_data != NULL) {
476 // save();
477 // load();
478 // }
479 
480  // Return
481  return;
482 }
483 
484 
485 /*==========================================================================
486  = =
487  = Private methods =
488  = =
489  ==========================================================================*/
490 
491 /***********************************************************************//**
492  * @brief Initialise class members
493  ***************************************************************************/
495 {
496  // Initialise members
497  m_type = __TUSHORT;
498  m_data = NULL;
499  m_nulval = NULL;
500 
501  // Return
502  return;
503 }
504 
505 
506 /***********************************************************************//**
507  * @brief Copy class members
508  *
509  * @param[in] column Column.
510  *
511  * Sets the content of the vector column by copying from another column.
512  * If the code is compiled with the small memory option, and if the source
513  * column has not yet been loaded, then we only load the column temporarily
514  * for copying purposes and release it again once copying is finished.
515  ***************************************************************************/
517 {
518  // Fetch data if necessary
519  bool not_loaded = (!column.is_loaded());
520  if (not_loaded) {
521  column.fetch_data();
522  }
523 
524  // Copy attributes
525  m_type = column.m_type;
526  m_size = column.m_size;
527  m_varlen = column.m_varlen;
528  m_rowstart = column.m_rowstart;
529 
530  // Copy column data
531  if (column.m_data != NULL && m_size > 0) {
532  alloc_data();
533  for (int i = 0; i < m_size; ++i) {
534  m_data[i] = column.m_data[i];
535  }
536  }
537 
538  // Copy NULL value
539  alloc_nulval(column.m_nulval);
540 
541  // Small memory option: release column if it was fetch above
542  #if defined(G_SMALL_MEMORY)
543  if (not_loaded) {
544  const_cast<GFitsTableUShortCol*>(&column)->release_data();
545  }
546  #endif
547 
548  // Return
549  return;
550 }
551 
552 
553 /***********************************************************************//**
554  * @brief Delete class members
555  ***************************************************************************/
557 {
558  // Free memory
559  if (m_data != NULL) delete [] m_data;
560  if (m_nulval != NULL) delete m_nulval;
561 
562  // Mark memory as freed
563  m_data = NULL;
564  m_nulval = NULL;
565 
566  // Return
567  return;
568 }
569 
570 
571 /***********************************************************************//**
572  * @brief Returns format string of ASCII table
573  ***************************************************************************/
574 std::string GFitsTableUShortCol::ascii_format(void) const
575 {
576  // Initialize format string
577  std::string format;
578 
579  // Set type code
580  format.append("I5");
581 
582  // Set width
583  //format.append(gammalib::str(m_width));
584 
585  // Return format
586  return format;
587 }
588 
589 
590 /***********************************************************************//**
591  * @brief Allocates column data
592  ***************************************************************************/
594 {
595  // Free any existing memory
596  if (m_data != NULL) delete [] m_data;
597 
598  // Mark pointer as free
599  m_data = NULL;
600 
601  // Allocate new data
602  if (m_size > 0) {
603  m_data = new unsigned short[m_size];
604  }
605 
606  // Return
607  return;
608 }
609 
610 
611 /***********************************************************************//**
612  * @brief Fetch column data
613  ***************************************************************************/
615 {
616  // Load column (circumvent const correctness)
617  const_cast<GFitsTableUShortCol*>(this)->load_column();
618 
619  // Return
620  return;
621 }
622 
623 
624 /***********************************************************************//**
625  * @brief Resize column data
626  *
627  * @param[in] index Start index.
628  * @param[in] number Number of elements to add/remove.
629  *
630  * Adds or removes elements from specified index on. Adding is done if
631  * @p number is a positive number, removing if @p number is negative.
632  * Note that the method does not change the validity of the arguments.
633  * This needs to be done by the client.
634  ***************************************************************************/
635 void GFitsTableUShortCol::resize_data(const int& index, const int& number)
636 {
637  // Continue only if number of elements is not zero
638  if (number != 0) {
639 
640  // If data are not available then load them now
641  if (m_data == NULL) fetch_data();
642 
643  // If elements should be removed then do not allocate new memory
644  // but just move elements forward and change the logical size of
645  // memory. Only if all elements should be removed the memory is
646  // released.
647  if (number < 0) {
648  int left = index - number;
649  unsigned short* dst = m_data + index;
650  unsigned short* src = m_data + left;
651  int num = m_size - left;
652  for (int i = 0; i < num; ++i) {
653  *dst++ = *src++;
654  }
655  m_size += number;
656  if (m_size < 1) {
657  release_data();
658  }
659  }
660 
661  // If elements should be added then allocate new memory, copy over
662  // the old data and initialise the new elements
663  else {
664  int left = m_size - index;
665  m_size += number;
666  unsigned short* new_data = new unsigned short[m_size];
667  unsigned short* dst = new_data;
668  unsigned short* src = m_data;
669  for (int i = 0; i < index; ++i) {
670  *dst++ = *src++;
671  }
672  for (int i = 0; i < number; ++i) {
673  *dst++ = 0;
674  }
675  for (int i = 0; i < left; ++i) {
676  *dst++ = *src++;
677  }
678  if (m_data != NULL) delete [] m_data;
679  m_data = new_data;
680  }
681 
682  } // endif: number was non-zero
683 
684  // Return
685  return;
686 }
687 
688 
689 /***********************************************************************//**
690  * @brief Release column data
691  ***************************************************************************/
693 {
694  // Free any existing memory
695  if (m_data != NULL) delete [] m_data;
696 
697  // Mark pointer as free and reset loaded vector size
698  m_data = NULL;
699  m_size = 0;
700 
701  // Return
702  return;
703 }
704 
705 
706 /***********************************************************************//**
707  * @brief Allocates null value
708  ***************************************************************************/
709 void GFitsTableUShortCol::alloc_nulval(const unsigned short* value)
710 {
711  // Free any existing memory
712  if (m_nulval != NULL) delete m_nulval;
713 
714  // Mark pointer as free
715  m_nulval = NULL;
716 
717  // If we have valid value, allocate and set nul value
718  if (value != NULL) {
719  m_nulval = new unsigned short;
720  *m_nulval = *value;
721  }
722 
723  // Return
724  return;
725 }
726 
727 
728 /***********************************************************************//**
729  * @brief Initialise column data
730  ***************************************************************************/
732 {
733  // Initialise data if they exist
734  if (m_data != NULL) {
735  for (int i = 0; i < m_size; ++i) {
736  m_data[i] = 0;
737  }
738  }
739 
740  // Return
741  return;
742 }
#define __TUSHORT
virtual ~GFitsTableUShortCol(void)
Destructor.
int m_type
Column type.
void init_members(void)
Initialise class members.
std::string number(const std::string &noun, const int &number)
Convert singular noun into number noun.
Definition: GTools.cpp:1046
virtual void resize_data(const int &index, const int &number)
Resize column data.
virtual void clear(void)
Clear instance.
virtual void insert(const int &row, const int &nrows)
Insert rows in column.
unsigned short & operator()(const int &row, const int &inx=0)
Column data access operator.
int m_number
Number of elements in column.
void free_members(void)
Delete class members.
GFitsTableCol & operator=(const GFitsTableCol &column)
Assignment operator.
virtual void alloc_data(void)
Allocates column data.
virtual void release_data(void)
Release column data.
GFitsTableUShortCol & operator=(const GFitsTableUShortCol &column)
Assignment operator.
unsigned short * m_data
Data vector.
int m_varlen
Maximum number of elements in variable-length.
Gammalib tools definition.
virtual GFitsTableUShortCol * clone(void) const
Clone column.
virtual void load_column(void)
Load table column from FITS file.
virtual void fetch_data(void) const
Fetch column data.
virtual std::string string(const int &row, const int &col=0) const
Get string value.
const int & number(void) const
Returns number of elements in column.
virtual int integer(const int &row, const int &col=0) const
Get integer value.
virtual bool is_loaded(void) const
Checks if column has been loaded.
void copy_members(const GFitsTableUShortCol &column)
Copy class members.
void free_members(void)
Delete class members.
#define G_REMOVE
void init_members(void)
Initialise class members.
virtual std::string ascii_format(void) const
Returns format string of ASCII table.
CFITSIO interface header.
GFitsTableUShortCol(void)
Constructor.
Abstract interface for FITS table column.
std::vector< int > m_rowstart
Start index of each row.
#define G_INSERT
std::string left(const std::string &s, const int &n, const char &c= ' ')
Left justify string to achieve a length of n characters.
Definition: GTools.cpp:949
FITS table unsigned short integer column class interface definition.
void alloc_nulval(const unsigned short *value)
Allocates null value.
int m_length
Length of column (number of rows)
unsigned short * nulval(void)
Returns pointer to nul value.
virtual void init_data(void)
Initialise column data.
virtual void remove(const int &row, const int &nrows)
Remove rows from column.
int m_size
Size of allocated data area (0 if not loaded)
unsigned short * m_nulval
NULL value.
FITS table unsigned short integer column.
virtual double real(const int &row, const int &col=0) const
Get double precision value.
virtual int offset(const int &row, const int &inx) const
Compute offset of column element in memory.
Exception handler interface definition.
const int & nrows(void) const
Returns number of rows in column.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:413