GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GFitsTableBitCol.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GFitsTableBitCol.cpp - FITS table Bit column class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2008-2021 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 GFitsTableBitCol.cpp
23  * @brief FITS table bit 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 "GFitsTableBitCol.hpp"
36 
37 /* __ Method name definitions ____________________________________________ */
38 #define G_INSERT "GFitsTableBitCol::insert(int&, int&)"
39 #define G_REMOVE "GFitsTableBitCol::remove(int&, int&)"
40 #define G_LOAD_COLUMN "GFitsTableBitCol::load_column()"
41 #define G_SAVE_COLUMN "GFitsTableBitCol::save_column()"
42 #define G_GET_BIT "GFitsTableBitCol::get_bit(int&,int&)"
43 
44 /* __ Macros _____________________________________________________________ */
45 
46 /* __ Coding definitions _________________________________________________ */
47 
48 /* __ Debug definitions __________________________________________________ */
49 //#define G_CALL_GRAPH //!< Dump call graph in console
50 
51 
52 /*==========================================================================
53  = =
54  = Constructors/destructors =
55  = =
56  ==========================================================================*/
57 
58 /***********************************************************************//**
59  * @brief Constructor
60  ***************************************************************************/
62 {
63  // Initialise class members for clean destruction
64  init_members();
65 
66  // Return
67  return;
68 }
69 
70 
71 /***********************************************************************//**
72  * @brief Constructor
73  *
74  * @param[in] name Name of column.
75  * @param[in] nrows Number of rows in column.
76  * @param[in] size Vector size of column.
77  ***************************************************************************/
78 GFitsTableBitCol::GFitsTableBitCol(const std::string& name,
79  const int& nrows,
80  const int& size) :
81  GFitsTableCol(name, nrows, size, 1)
82 {
83  // Initialise class members for clean destruction
84  init_members();
85 
86  // Return
87  return;
88 }
89 
90 
91 /***********************************************************************//**
92  * @brief Copy constructor
93  *
94  * @param[in] column Table column.
95  ***************************************************************************/
97  GFitsTableCol(column)
98 {
99  // Initialise class members for clean destruction
100  init_members();
101 
102  // Copy members
103  copy_members(column);
104 
105  // Return
106  return;
107 }
108 
109 
110 /***********************************************************************//**
111  * @brief Destructor
112  ***************************************************************************/
114 {
115  // Free members
116  free_members();
117 
118  // Return
119  return;
120 }
121 
122 
123 /*==========================================================================
124  = =
125  = Operators =
126  = =
127  ==========================================================================*/
128 
129 /***********************************************************************//**
130  * @brief Assignment operator
131  *
132  * @param[in] column Table column.
133  * @return Table column.
134  ***************************************************************************/
136 {
137  // Execute only if object is not identical
138  if (this != &column) {
139 
140  // Copy base class members
141  this->GFitsTableCol::operator=(column);
142 
143  // Free members
144  free_members();
145 
146  // Initialise private members for clean destruction
147  init_members();
148 
149  // Copy members
150  copy_members(column);
151 
152  } // endif: object was not identical
153 
154  // Return this object
155  return *this;
156 }
157 
158 
159 /***********************************************************************//**
160  * @brief Column data access operator
161  *
162  * @param[in] row Row of column to access.
163  * @param[in] inx Vector index in column row to access.
164  *
165  * Provides access to data in a column.
166  ***************************************************************************/
167 bool& GFitsTableBitCol::operator()(const int& row, const int& inx)
168 {
169  // If data are not available then load them now
170  if (m_data == NULL) this->fetch_data();
171 
172  // Set any pending Bit
173  set_pending();
174 
175  // Get Bit
176  get_bit(row, inx);
177 
178  // Signal that a Bit is pending. We need this here since the non-const
179  // operator allows changing the Bit after exiting the method, hence
180  // we have to signal that the actual value of 'm_bit_value' could have
181  // been modified and needs to be written back into the data array.
182  m_bit_pending = true;
183 
184  // Return Bit
185  return m_bit_value;
186 }
187 
188 
189 /***********************************************************************//**
190  * @brief Column data access operator (const variant)
191  *
192  * @param[in] row Row of column to access.
193  * @param[in] inx Vector index in column row to access
194  *
195  * Provides access to data in a column.
196  ***************************************************************************/
197 const bool& GFitsTableBitCol::operator()(const int& row, const int& inx) const
198 {
199  // Circumvent const correctness
200  GFitsTableBitCol* ptr = const_cast<GFitsTableBitCol*>(this);
201 
202  // If data are not available then load them now
203  if (m_data == NULL) ptr->fetch_data();
204 
205  // Set any pending Bit
206  ptr->set_pending();
207 
208  // Get Bit
209  ptr->get_bit(row, inx);
210 
211  // Return data bin
212  return m_bit_value;
213 }
214 
215 
216 /*==========================================================================
217  = =
218  = Public methods =
219  = =
220  ==========================================================================*/
221 
222 /***********************************************************************//**
223  * @brief Clear instance
224  *
225  * This method properly resets the object to an initial state.
226  ***************************************************************************/
228 {
229  // Free class members (base and derived classes, derived class first)
230  free_members();
232 
233  // Initialise members
235  init_members();
236 
237  // Return
238  return;
239 }
240 
241 
242 /***********************************************************************//**
243  * @brief Clone column
244  ***************************************************************************/
246 {
247  return new GFitsTableBitCol(*this);
248 }
249 
250 
251 /***********************************************************************//**
252  * @brief Get string value
253  *
254  * @param[in] row Table row.
255  * @param[in] inx Table column vector index.
256  *
257  * Returns value of specified row and vector index as string.
258  ***************************************************************************/
259 std::string GFitsTableBitCol::string(const int& row, const int& inx) const
260 {
261  // Get Bit value
262  bool bit = (*this)(row, inx);
263 
264  // Convert bit into string
265  std::string result = (bit) ? "T" : "F";
266 
267  // Return result
268  return result;
269 }
270 
271 
272 /***********************************************************************//**
273  * @brief Get double precision value
274  *
275  * @param[in] row Table row.
276  * @param[in] inx Table column vector index.
277  *
278  * Returns value of specified row and vector index as double precision.
279  ***************************************************************************/
280 double GFitsTableBitCol::real(const int& row, const int& inx) const
281 {
282  // Get Bit value
283  bool bit = (*this)(row, inx);
284 
285  // Convert bit into double
286  double result = (bit) ? 1.0 : 0.0;
287 
288  // Return result
289  return result;
290 }
291 
292 
293 /***********************************************************************//**
294  * @brief Get integer value
295  *
296  * @param[in] row Table row.
297  * @param[in] inx Table column vector index.
298  *
299  * Returns value of specified row and vector index as integer.
300  ***************************************************************************/
301 int GFitsTableBitCol::integer(const int& row, const int& inx) const
302 {
303  // Get Bit value
304  bool bit = (*this)(row, inx);
305 
306  // Convert bit into double
307  int result = (bit) ? 1 : 0;
308 
309  // Return result
310  return result;
311 }
312 
313 
314 /***********************************************************************//**
315  * @brief Insert rows in column
316  *
317  * @param[in] row Row after which rows should be inserted (0=first row).
318  * @param[in] nrows Number of rows to be inserted.
319  *
320  * @exception GException::out_of_range
321  * Specified row is invalid.
322  *
323  * Inserts rows into a FITS table. This implies that the column will be
324  * loaded into memory.
325  ***************************************************************************/
326 void GFitsTableBitCol::insert(const int& row, const int& nrows)
327 {
328  // Make sure that row is valid
329  if (row < 0 || row > m_length) {
330  throw GException::out_of_range(G_INSERT, "FITS table row number",
331  row, m_length+1);
332  }
333 
334  // Continue only if there are rows to be inserted
335  if (nrows > 0) {
336 
337  // If we have no rows yet then simply set the length to the
338  // number of rows to be inserted
339  if (m_length == 0) {
340  m_length = nrows;
342  alloc_data();
343  init_data();
344  }
345 
346  // ... otherwise fetch data, allocate new data and copy over
347  // the existing items
348  else {
349 
350  // If data are not available then load them now
351  if (m_data == NULL) fetch_data();
352 
353  // Set any pending Bit
354  set_pending();
355 
356  // Compute new column length
357  int length = m_length + nrows;
358 
359  // Compute total number of Bits in column
360  m_bits = m_number * length;
361 
362  // Compute number of Bytes and Bits per row
363  m_bytes_per_row = (m_number > 0) ? ((m_number-1) / 8) + 1 : 0;
365 
366  // Compute length of memory array
367  m_size = m_bytes_per_row * length;
368 
369  // Allocate new data to hold the column
370  unsigned char* new_data = new unsigned char[m_size];
371 
372  // Compute the number of elements before the insertion point,
373  // the number of elements that get inserted, and the total
374  // number of elements after the insertion point
375  int n_before = m_bytes_per_row * row;
376  int n_insert = m_bytes_per_row * nrows;
377  int n_after = m_bytes_per_row * (m_length - row);
378 
379  // Copy and initialise data
380  unsigned char* src = m_data;
381  unsigned char* dst = new_data;
382  for (int i = 0; i < n_before; ++i) {
383  *dst++ = *src++;
384  }
385  for (int i = 0; i < n_insert; ++i) {
386  *dst++ = 0;
387  }
388  for (int i = 0; i < n_after; ++i) {
389  *dst++ = *src++;
390  }
391 
392  // Free old data
393  if (m_data != NULL) delete [] m_data;
394 
395  // Set pointer to new data and store length
396  m_data = new_data;
397  m_length = length;
398 
399  } // endelse: there were already data
400 
401  } // endfor: there were rows to be inserted
402 
403  // Return
404  return;
405 }
406 
407 
408 /***********************************************************************//**
409  * @brief Remove rows from column
410  *
411  * @param[in] row Row after which rows should be removed (0=first row).
412  * @param[in] nrows Number of rows to be removed.
413  *
414  * @exception GException::out_of_range
415  * Specified row is invalid.
416  * Invalid number of rows specified.
417  *
418  * This method removes rows from a FITS table. This implies that the column
419  * will be loaded into memory.
420  ***************************************************************************/
421 void GFitsTableBitCol::remove(const int& row, const int& nrows)
422 {
423  // Make sure that row is valid
424  if (row < 0 || row >= m_length) {
425  throw GException::out_of_range(G_REMOVE, "FITS table row number",
426  row, m_length);
427  }
428 
429  // Make sure that we don't remove beyond the limit
430  if (nrows < 0 || nrows > m_length-row) {
431  throw GException::out_of_range(G_REMOVE, "Number of FITS table rows",
432  nrows, m_length-row+1);
433  }
434 
435  // Continue only if there are rows to be removed
436  if (nrows > 0) {
437 
438  // If data are not available then load them now
439  if (m_data == NULL) fetch_data();
440 
441  // Set any pending Bit
442  set_pending();
443 
444  // Compute new column length
445  int length = m_length - nrows;
446 
447  // Compute total number of Bits in column
448  m_bits = m_number * length;
449 
450  // Compute number of Bytes and Bits per row
451  m_bytes_per_row = (m_number > 0) ? ((m_number-1) / 8) + 1 : 0;
453 
454  // Compute length of memory array
455  m_size = m_bytes_per_row * length;
456 
457  // If we have rows remaining then allocate new data to hold
458  // the column
459  if (m_size > 0) {
460 
461  // Allocate new data to hold the column
462  unsigned char* new_data = new unsigned char[m_size];
463 
464  // Compute the number of elements before the removal point,
465  // the number of elements that get removed, and the total
466  // number of elements after the removal point
467  int n_before = m_bytes_per_row * row;
468  int n_remove = m_bytes_per_row * nrows;
469  int n_after = m_bytes_per_row * (length - row);
470 
471  // Copy data
472  unsigned char* src = m_data;
473  unsigned char* dst = new_data;
474  for (int i = 0; i < n_before; ++i) {
475  *dst++ = *src++;
476  }
477  src += n_remove;
478  for (int i = 0; i < n_after; ++i) {
479  *dst++ = *src++;
480  }
481 
482  // Free old data
483  if (m_data != NULL) delete [] m_data;
484 
485  // Set pointer to new data and store length
486  m_data = new_data;
487  m_length = length;
488 
489  } // endif: there are still elements after removal
490 
491  // ... otherwise just remove all data
492  else {
493 
494  // Free old data
495  if (m_data != NULL) delete [] m_data;
496 
497  // Set pointer to new data and store length
498  m_data = NULL;
499  m_length = length;
500  }
501 
502  } // endfor: there were rows to be removed
503 
504  // Return
505  return;
506 }
507 
508 
509 /***********************************************************************//**
510  * @brief Set nul value
511  *
512  * @param[in] value Nul value.
513  *
514  * @todo To correctly reflect the nul value in the data, the column should
515  * be reloaded. However, the column may have been changed, so in principle
516  * saving is needed. However, we may not want to store the data, hence saving
517  * is also not desired. We thus have to develop a method to update the
518  * column information for a new nul value in place ...
519  ***************************************************************************/
520 void GFitsTableBitCol::nulval(const unsigned char* value)
521 {
522  // Allocate nul value
523  alloc_nulval(value);
524 
525  // Update column
526 // if (m_data != NULL) {
527 // save();
528 // load();
529 // }
530 
531  // Return
532  return;
533 }
534 
535 
536 /*==========================================================================
537  = =
538  = Private methods =
539  = =
540  ==========================================================================*/
541 
542 /***********************************************************************//**
543  * @brief Initialise class members
544  ***************************************************************************/
546 {
547  // Optionally print call graph
548  #if defined(G_CALL_GRAPH)
549  printf("GFitsTableBitCol::init_members\n");
550  #endif
551 
552  // Initialise members
553  m_type = __TBIT;
554  m_bits = 0;
555  m_bytes_per_row = 0;
556  m_bits_per_row = 0;
557  m_data = NULL;
558  m_nulval = NULL;
559  m_bit_pending = false;
560  m_bit_value = false;
561  m_bit_byte = 0;
562  m_bit_mask = 0;
563 
564  // Optionally print call graph
565  #if defined(G_CALL_GRAPH)
566  printf("exit GFitsTableBitCol::init_members\n");
567  #endif
568 
569  // Return
570  return;
571 }
572 
573 
574 /***********************************************************************//**
575  * @brief Copy class members
576  *
577  * @param[in] column Column.
578  *
579  * Sets the content of the vector column by copying from another column.
580  * If the code is compiled with the small memory option, and if the source
581  * column has not yet been loaded, then we only load the column temporarily
582  * for copying purposes and release it again once copying is finished.
583  ***************************************************************************/
585 {
586  // Fetch data if necessary
587  bool not_loaded = (!column.is_loaded());
588  if (not_loaded) {
589  column.fetch_data();
590  }
591 
592  // Copy attributes
593  m_type = column.m_type;
594  m_size = column.m_size;
595  m_varlen = column.m_varlen;
596  m_rowstart = column.m_rowstart;
597  m_bits = column.m_bits;
600  m_bit_pending = column.m_bit_pending;
601  m_bit_value = column.m_bit_value;
602  m_bit_byte = column.m_bit_byte;
603  m_bit_mask = column.m_bit_mask;
604 
605  // Copy column data
606  if (column.m_data != NULL && m_size > 0) {
607  alloc_data();
608  for (int i = 0; i < m_size; ++i)
609  m_data[i] = column.m_data[i];
610  }
611 
612  // Copy NULL value
613  alloc_nulval(column.m_nulval);
614 
615  // Small memory option: release column if it was fetch above
616  #if defined(G_SMALL_MEMORY)
617  if (not_loaded) {
618  const_cast<GFitsTableBitCol*>(&column)->release_data();
619  }
620  #endif
621 
622  // Return
623  return;
624 }
625 
626 
627 /***********************************************************************//**
628  * @brief Delete class members
629  ***************************************************************************/
631 {
632  // Optionally print call graph
633  #if defined(G_CALL_GRAPH)
634  printf("GFitsTableBitCol::free_members\n");
635  #endif
636 
637  // Free memory
638  if (m_data != NULL) delete [] m_data;
639  if (m_nulval != NULL) delete m_nulval;
640 
641  // Mark memory as freed
642  m_data = NULL;
643  m_nulval = NULL;
644 
645  // Reset load flag
646  m_size = 0;
647 
648  // Optionally print call graph
649  #if defined(G_CALL_GRAPH)
650  printf("exit GFitsTableBitCol::free_members\n");
651  #endif
652 
653  // Return
654  return;
655 }
656 
657 
658 /***********************************************************************//**
659  * @brief Returns format string of ASCII table
660  ***************************************************************************/
661 std::string GFitsTableBitCol::ascii_format(void) const
662 {
663  // Initialize format string
664  std::string format;
665 
666  // Set type code
667  format.append("I");
668 
669  // Set width
670  format.append(gammalib::str(m_width));
671 
672  // Return format
673  return format;
674 }
675 
676 
677 /***********************************************************************//**
678  * @brief Allocates column data
679  ***************************************************************************/
681 {
682  // Optionally print call graph
683  #if defined(G_CALL_GRAPH)
684  printf("GFitsTableBitCol::alloc_data(%d)\n", m_size);
685  #endif
686 
687  // Free any existing memory
688  if (m_data != NULL) delete [] m_data;
689 
690  // Mark pointer as free
691  m_data = NULL;
692 
693  // Allocate new data
694  if (m_size > 0) {
695  m_data = new unsigned char[m_size];
696  }
697 
698  // Optionally print call graph
699  #if defined(G_CALL_GRAPH)
700  printf("exit GFitsTableBitCol::alloc_data(m_data=%x)\n", m_data);
701  #endif
702 
703  // Return
704  return;
705 }
706 
707 
708 /***********************************************************************//**
709  * @brief Fetch column data
710  *
711  * This method fetches column data when needed. It is declared const, so
712  * that const data access methods can be implemented.
713  *
714  * If a FITS file is attached to the column the data are loaded into memory
715  * from the FITS file. If no FITS file is attached, memory is allocated
716  * to hold the column data and all cells are initialised.
717  *
718  * This method calls GFitsTableCol::load_column to do the job.
719  ***************************************************************************/
721 {
722  // Load column (circumvent const correctness)
723  const_cast<GFitsTableBitCol*>(this)->load_column();
724 
725  // Return
726  return;
727 }
728 
729 
730 /***********************************************************************//**
731  * @brief Resize column data
732  *
733  * @param[in] index Start index.
734  * @param[in] number Number of elements to add/remove.
735  *
736  * Adds or removes elements from specified index on. Adding is done if
737  * @p number is a positive number, removing if @p number is negative.
738  * Note that the method does not change the validity of the arguments.
739  * This needs to be done by the client.
740  *
741  * @todo Needs to be implemented
742  ***************************************************************************/
743 void GFitsTableBitCol::resize_data(const int& index, const int& number)
744 {
745  //TODO
746 
747  // Return
748  return;
749 }
750 
751 
752 /***********************************************************************//**
753  * @brief Release column data
754  ***************************************************************************/
756 {
757  // Free any existing memory
758  if (m_data != NULL) delete [] m_data;
759 
760  // Mark pointer as free and reset loaded vector size
761  m_data = NULL;
762  m_size = 0;
763 
764  // Return
765  return;
766 }
767 
768 
769 /***********************************************************************//**
770  * @brief Allocates null value
771  ***************************************************************************/
772 void GFitsTableBitCol::alloc_nulval(const unsigned char* value)
773 {
774  // Free any existing memory
775  if (m_nulval != NULL) delete m_nulval;
776 
777  // Mark pointer as free
778  m_nulval = NULL;
779 
780  // If we have valid value, allocate and set nul value
781  if (value != NULL) {
782  m_nulval = new unsigned char;
783  *m_nulval = *value;
784  }
785 
786  // Return
787  return;
788 }
789 
790 
791 /***********************************************************************//**
792  * @brief Initialise column data
793  ***************************************************************************/
795 {
796  // Initialise data if they exist
797  if (m_data != NULL) {
798  for (int i = 0; i < m_size; ++i) {
799  m_data[i] = 0;
800  }
801  }
802 
803  // Return
804  return;
805 }
806 
807 
808 /***********************************************************************//**
809  * @brief Load table column from FITS file
810  *
811  * @exception GException::fits_hdu_not_found
812  * Specified HDU not found in FITS file.
813  * @exception GException::fits_error
814  * An error occured while loading column data from FITS file.
815  *
816  * Load Bit (vector) column into memory by reading 8 Bits at once.
817  ***************************************************************************/
819 {
820  // Compute total number of Bits in column
822 
823  // Compute number of Bytes and Bits per row
824  m_bytes_per_row = (m_number > 0) ? ((m_number-1) / 8) + 1 : 0;
826 
827  // Compute length of memory array
829 
830  // Load only if the column has a positive size
831  if (m_size > 0) {
832 
833  // Allocate and initialise fresh memory
834  alloc_data();
835  init_data();
836 
837  // If a FITS file is attached then load column data from the FITS
838  // file
839  if (FPTR(m_fitsfile)->Fptr != NULL) {
840 
841  // Move to the HDU
842  int status = 0;
843  status = __ffmahd(FPTR(m_fitsfile),
844  (FPTR(m_fitsfile)->HDUposition)+1,
845  NULL, &status);
846  if (status != 0) {
847  std::string msg = "FITS HDU number "+
848  gammalib::str((FPTR(m_fitsfile)->HDUposition)+1)+
849  " not found in FITS file.";
850  throw GException::fits_error(G_LOAD_COLUMN, status, msg);
851  }
852 
853  // Load data 8 Bits at once
854  status = __ffgcv(FPTR(m_fitsfile), __TBYTE, m_colnum, 1, 1, m_size,
855  m_nulval, m_data, &m_anynul, &status);
856  if (status != 0) {
858  "for column \""+m_name+"\".");
859  }
860  }
861 
862  } // endif: column has a positive size
863 
864  // Return
865  return;
866 }
867 
868 
869 /***********************************************************************//**
870  * @brief Save table column into FITS file
871  *
872  * @exception GException::fits_hdu_not_found
873  * Specified HDU not found in FITS file.
874  * @exception GException::fits_error
875  * Error occured during writing of the column data.
876  *
877  * Save Bit (vector) column into FITS file by writing 8 Bits at once.
878  ***************************************************************************/
880 {
881  // Continue only if a FITS file is connected and data have been loaded
882  if (FPTR(m_fitsfile)->Fptr != NULL && m_colnum > 0 && m_data != NULL) {
883 
884  // Set any pending Bit
885  set_pending();
886 
887  // Move to the HDU
888  int status = 0;
889  status = __ffmahd(FPTR(m_fitsfile),
890  (FPTR(m_fitsfile)->HDUposition)+1, NULL,
891  &status);
892  if (status != 0) {
893  std::string msg = "FITS HDU number "+
894  gammalib::str((FPTR(m_fitsfile)->HDUposition)+1)+
895  " not found in FITS file.";
896  throw GException::fits_error(G_SAVE_COLUMN, status, msg);
897  }
898 
899  // Save data 8 Bits at once
900  status = __ffpcn(FPTR(m_fitsfile), __TBYTE, m_colnum, 1, 1,
901  m_size, m_data, m_nulval, &status);
902  if (status != 0) {
903  throw GException::fits_error(G_SAVE_COLUMN, status);
904  }
905 
906  } // endif: FITS file was connected
907 
908  // Return
909  return;
910 }
911 
912 
913 /***********************************************************************//**
914  * @brief Get Bit for boolean access
915  *
916  * @param[in] row Row of column.
917  * @param[in] inx Vector index in column row.
918  *
919  * @exception GException::out_of_range
920  * Table row out of valid range.
921  * Table vector index out of valid range.
922  *
923  * Set the Bit for boolean data access. Note that this method assumes that
924  * the data have already been loaded.
925  ***************************************************************************/
926 void GFitsTableBitCol::get_bit(const int& row, const int& inx)
927 {
928  // Check row value
929  #if defined(G_RANGE_CHECK)
930  if (row < 0 || row >= m_length) {
931  throw GException::out_of_range(G_GET_BIT, "FITS table row number",
932  row, m_length);
933  }
934  #endif
935 
936  // Check inx value
937  #if defined(G_RANGE_CHECK)
938  if (inx < 0 || inx >= m_number) {
939  throw GException::out_of_range(G_GET_BIT, "FITS table column vector index",
940  inx, m_number);
941  }
942  #endif
943 
944  // Compute Byte and Bit mask
945  m_bit_byte = row * m_bytes_per_row + inx / 8;
946  m_bit_mask = 1 << (7 - (inx % 8));
947 
948  // Set Bit value
950 
951  // Return
952  return;
953 }
954 
955 
956 /***********************************************************************//**
957  * @brief Set pending Bit
958  *
959  * Write the pending Bit into the data. Note that this method assumes that
960  * the data have already been loaded.
961  ***************************************************************************/
963 {
964  // Continue only if we have a pending Bit
965  if (m_bit_pending) {
966 
967  // Set or unset Bit
968  if (m_bit_value) {
970  }
971  else {
973  }
974 
975  // Signal that no more Bit is pending
976  m_bit_pending = false;
977 
978  }
979 
980  // Return
981  return;
982 }
int m_bits
Total number of Bits in column.
virtual void release_data(void)
Release column data.
virtual int integer(const int &row, const int &col=0) const
Get integer value.
int m_type
Column type.
std::string number(const std::string &noun, const int &number)
Convert singular noun into number noun.
Definition: GTools.cpp:1167
int m_colnum
Column number (starting from 1). This parameter is used to signal if a table column corresponds to a ...
#define FPTR(A)
void free_members(void)
Delete class members.
virtual void resize_data(const int &index, const int &number)
Resize column data.
int m_anynul
Number of NULLs encountered.
virtual std::string string(const int &row, const int &col=0) const
Get string value.
virtual ~GFitsTableBitCol(void)
Destructor.
virtual GFitsTableBitCol * clone(void) const
Clone column.
int m_number
Number of elements in column.
#define G_LOAD_COLUMN
void free_members(void)
Delete class members.
bool m_bit_value
Actual bit to be accessed.
GFitsTableCol & operator=(const GFitsTableCol &column)
Assignment operator.
virtual void insert(const int &row, const int &nrows)
Insert rows in column.
virtual void clear(void)
Clear instance.
unsigned char * m_data
Data area.
void init_members(void)
Initialise class members.
bool m_bit_pending
Bit value has to be written back.
void copy_members(const GFitsTableBitCol &column)
Copy class members.
int m_varlen
Maximum number of elements in variable-length.
#define __ffgcv(A, B, C, D, E, F, G, H, I, J)
Gammalib tools definition.
bool & operator()(const int &row, const int &inx=0)
Column data access operator.
unsigned char * m_nulval
NULL value.
#define __TBYTE
virtual double real(const int &row, const int &col=0) const
Get double precision value.
int m_bits_per_row
Number of Bits per row.
#define __ffmahd(A, B, C, D)
#define __TBIT
void init_members(void)
Initialise class members.
#define G_INSERT
FITS table Bit column.
CFITSIO interface header.
Abstract interface for FITS table column.
std::vector< int > m_rowstart
Start index of each row.
#define G_SAVE_COLUMN
FITS table bit column class interface definition.
GFitsTableBitCol & operator=(const GFitsTableBitCol &column)
Assignment operator.
std::string m_name
Column name.
int m_length
Length of column (number of rows)
unsigned char * nulval(void)
Returns pointer to nul value.
virtual bool is_loaded(void) const
Checks if column has been loaded.
virtual void alloc_data(void)
Allocates column data.
int m_bit_byte
Row of actual bit to be accessed.
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)
#define __ffpcn(A, B, C, D, E, F, G, H, I)
virtual void fetch_data(void) const
Fetch column data.
void get_bit(const int &row, const int &inx)
Get Bit for boolean access.
Exception handler interface definition.
virtual void save_column(void)
Save table column into FITS file.
#define G_GET_BIT
int m_bit_mask
Index of actual bit to be accessed.
void * m_fitsfile
FITS file pointer associated with column.
const int & nrows(void) const
Returns number of rows in column.
GFitsTableBitCol(void)
Constructor.
int m_bytes_per_row
Number of Bytes per row.
virtual void load_column(void)
Load table column from FITS file.
#define G_REMOVE
void set_pending(void)
Set pending Bit.
virtual std::string ascii_format(void) const
Returns format string of ASCII table.
virtual void init_data(void)
Initialise column data.
int m_width
Width in Bytes of single column element.
void alloc_nulval(const unsigned char *value)
Allocates null value.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489