GammaLib  1.7.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-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 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::fits_invalid_row
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::fits_invalid_row(G_INSERT, row, m_length);
331  }
332 
333  // Continue only if there are rows to be inserted
334  if (nrows > 0) {
335 
336  // If we have no rows yet then simply set the length to the
337  // number of rows to be inserted
338  if (m_length == 0) {
339  m_length = nrows;
341  alloc_data();
342  init_data();
343  }
344 
345  // ... otherwise fetch data, allocate new data and copy over
346  // the existing items
347  else {
348 
349  // If data are not available then load them now
350  if (m_data == NULL) fetch_data();
351 
352  // Set any pending Bit
353  set_pending();
354 
355  // Compute new column length
356  int length = m_length + nrows;
357 
358  // Compute total number of Bits in column
359  m_bits = m_number * length;
360 
361  // Compute number of Bytes and Bits per row
362  m_bytes_per_row = (m_number > 0) ? ((m_number-1) / 8) + 1 : 0;
364 
365  // Compute length of memory array
366  m_size = m_bytes_per_row * length;
367 
368  // Allocate new data to hold the column
369  unsigned char* new_data = new unsigned char[m_size];
370 
371  // Compute the number of elements before the insertion point,
372  // the number of elements that get inserted, and the total
373  // number of elements after the insertion point
374  int n_before = m_bytes_per_row * row;
375  int n_insert = m_bytes_per_row * nrows;
376  int n_after = m_bytes_per_row * (m_length - row);
377 
378  // Copy and initialise data
379  unsigned char* src = m_data;
380  unsigned char* dst = new_data;
381  for (int i = 0; i < n_before; ++i) {
382  *dst++ = *src++;
383  }
384  for (int i = 0; i < n_insert; ++i) {
385  *dst++ = 0;
386  }
387  for (int i = 0; i < n_after; ++i) {
388  *dst++ = *src++;
389  }
390 
391  // Free old data
392  if (m_data != NULL) delete [] m_data;
393 
394  // Set pointer to new data and store length
395  m_data = new_data;
396  m_length = length;
397 
398  } // endelse: there were already data
399 
400  } // endfor: there were rows to be inserted
401 
402  // Return
403  return;
404 }
405 
406 
407 /***********************************************************************//**
408  * @brief Remove rows from column
409  *
410  * @param[in] row Row after which rows should be removed (0=first row).
411  * @param[in] nrows Number of rows to be removed.
412  *
413  * @exception GException::fits_invalid_row
414  * Specified row is invalid.
415  * @exception GException::fits_invalid_nrows
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) {
426  }
427 
428  // Make sure that we don't remove beyond the limit
429  if (nrows < 0 || nrows > m_length-row) {
431  }
432 
433  // Continue only if there are rows to be removed
434  if (nrows > 0) {
435 
436  // If data are not available then load them now
437  if (m_data == NULL) fetch_data();
438 
439  // Set any pending Bit
440  set_pending();
441 
442  // Compute new column length
443  int length = m_length - nrows;
444 
445  // Compute total number of Bits in column
446  m_bits = m_number * length;
447 
448  // Compute number of Bytes and Bits per row
449  m_bytes_per_row = (m_number > 0) ? ((m_number-1) / 8) + 1 : 0;
451 
452  // Compute length of memory array
453  m_size = m_bytes_per_row * length;
454 
455  // If we have rows remaining then allocate new data to hold
456  // the column
457  if (m_size > 0) {
458 
459  // Allocate new data to hold the column
460  unsigned char* new_data = new unsigned char[m_size];
461 
462  // Compute the number of elements before the removal point,
463  // the number of elements that get removed, and the total
464  // number of elements after the removal point
465  int n_before = m_bytes_per_row * row;
466  int n_remove = m_bytes_per_row * nrows;
467  int n_after = m_bytes_per_row * (length - row);
468 
469  // Copy data
470  unsigned char* src = m_data;
471  unsigned char* dst = new_data;
472  for (int i = 0; i < n_before; ++i) {
473  *dst++ = *src++;
474  }
475  src += n_remove;
476  for (int i = 0; i < n_after; ++i) {
477  *dst++ = *src++;
478  }
479 
480  // Free old data
481  if (m_data != NULL) delete [] m_data;
482 
483  // Set pointer to new data and store length
484  m_data = new_data;
485  m_length = length;
486 
487  } // endif: there are still elements after removal
488 
489  // ... otherwise just remove all data
490  else {
491 
492  // Free old data
493  if (m_data != NULL) delete [] m_data;
494 
495  // Set pointer to new data and store length
496  m_data = NULL;
497  m_length = length;
498  }
499 
500  } // endfor: there were rows to be removed
501 
502  // Return
503  return;
504 }
505 
506 
507 /***********************************************************************//**
508  * @brief Set nul value
509  *
510  * @param[in] value Nul value.
511  *
512  * @todo To correctly reflect the nul value in the data, the column should
513  * be reloaded. However, the column may have been changed, so in principle
514  * saving is needed. However, we may not want to store the data, hence saving
515  * is also not desired. We thus have to develop a method to update the
516  * column information for a new nul value in place ...
517  ***************************************************************************/
518 void GFitsTableBitCol::nulval(const unsigned char* value)
519 {
520  // Allocate nul value
521  alloc_nulval(value);
522 
523  // Update column
524 // if (m_data != NULL) {
525 // save();
526 // load();
527 // }
528 
529  // Return
530  return;
531 }
532 
533 
534 /*==========================================================================
535  = =
536  = Private methods =
537  = =
538  ==========================================================================*/
539 
540 /***********************************************************************//**
541  * @brief Initialise class members
542  ***************************************************************************/
544 {
545  // Optionally print call graph
546  #if defined(G_CALL_GRAPH)
547  printf("GFitsTableBitCol::init_members\n");
548  #endif
549 
550  // Initialise members
551  m_type = __TBIT;
552  m_bits = 0;
553  m_bytes_per_row = 0;
554  m_bits_per_row = 0;
555  m_data = NULL;
556  m_nulval = NULL;
557  m_bit_pending = false;
558  m_bit_value = false;
559  m_bit_byte = 0;
560  m_bit_mask = 0;
561 
562  // Optionally print call graph
563  #if defined(G_CALL_GRAPH)
564  printf("exit GFitsTableBitCol::init_members\n");
565  #endif
566 
567  // Return
568  return;
569 }
570 
571 
572 /***********************************************************************//**
573  * @brief Copy class members
574  *
575  * @param[in] column Column.
576  *
577  * Sets the content of the vector column by copying from another column.
578  * If the code is compiled with the small memory option, and if the source
579  * column has not yet been loaded, then we only load the column temporarily
580  * for copying purposes and release it again once copying is finished.
581  ***************************************************************************/
583 {
584  // Fetch data if necessary
585  bool not_loaded = (!column.is_loaded());
586  if (not_loaded) {
587  column.fetch_data();
588  }
589 
590  // Copy attributes
591  m_type = column.m_type;
592  m_size = column.m_size;
593  m_varlen = column.m_varlen;
594  m_rowstart = column.m_rowstart;
595  m_bits = column.m_bits;
598  m_bit_pending = column.m_bit_pending;
599  m_bit_value = column.m_bit_value;
600  m_bit_byte = column.m_bit_byte;
601  m_bit_mask = column.m_bit_mask;
602 
603  // Copy column data
604  if (column.m_data != NULL && m_size > 0) {
605  alloc_data();
606  for (int i = 0; i < m_size; ++i)
607  m_data[i] = column.m_data[i];
608  }
609 
610  // Copy NULL value
611  alloc_nulval(column.m_nulval);
612 
613  // Small memory option: release column if it was fetch above
614  #if defined(G_SMALL_MEMORY)
615  if (not_loaded) {
616  const_cast<GFitsTableBitCol*>(&column)->release_data();
617  }
618  #endif
619 
620  // Return
621  return;
622 }
623 
624 
625 /***********************************************************************//**
626  * @brief Delete class members
627  ***************************************************************************/
629 {
630  // Optionally print call graph
631  #if defined(G_CALL_GRAPH)
632  printf("GFitsTableBitCol::free_members\n");
633  #endif
634 
635  // Free memory
636  if (m_data != NULL) delete [] m_data;
637  if (m_nulval != NULL) delete m_nulval;
638 
639  // Mark memory as freed
640  m_data = NULL;
641  m_nulval = NULL;
642 
643  // Reset load flag
644  m_size = 0;
645 
646  // Optionally print call graph
647  #if defined(G_CALL_GRAPH)
648  printf("exit GFitsTableBitCol::free_members\n");
649  #endif
650 
651  // Return
652  return;
653 }
654 
655 
656 /***********************************************************************//**
657  * @brief Returns format string of ASCII table
658  ***************************************************************************/
659 std::string GFitsTableBitCol::ascii_format(void) const
660 {
661  // Initialize format string
662  std::string format;
663 
664  // Set type code
665  format.append("I");
666 
667  // Set width
668  format.append(gammalib::str(m_width));
669 
670  // Return format
671  return format;
672 }
673 
674 
675 /***********************************************************************//**
676  * @brief Allocates column data
677  ***************************************************************************/
679 {
680  // Optionally print call graph
681  #if defined(G_CALL_GRAPH)
682  printf("GFitsTableBitCol::alloc_data(%d)\n", m_size);
683  #endif
684 
685  // Free any existing memory
686  if (m_data != NULL) delete [] m_data;
687 
688  // Mark pointer as free
689  m_data = NULL;
690 
691  // Allocate new data
692  if (m_size > 0) {
693  m_data = new unsigned char[m_size];
694  }
695 
696  // Optionally print call graph
697  #if defined(G_CALL_GRAPH)
698  printf("exit GFitsTableBitCol::alloc_data(m_data=%x)\n", m_data);
699  #endif
700 
701  // Return
702  return;
703 }
704 
705 
706 /***********************************************************************//**
707  * @brief Fetch column data
708  *
709  * This method fetches column data when needed. It is declared const, so
710  * that const data access methods can be implemented.
711  *
712  * If a FITS file is attached to the column the data are loaded into memory
713  * from the FITS file. If no FITS file is attached, memory is allocated
714  * to hold the column data and all cells are initialised.
715  *
716  * This method calls GFitsTableCol::load_column to do the job.
717  ***************************************************************************/
719 {
720  // Load column (circumvent const correctness)
721  const_cast<GFitsTableBitCol*>(this)->load_column();
722 
723  // Return
724  return;
725 }
726 
727 
728 /***********************************************************************//**
729  * @brief Resize column data
730  *
731  * @param[in] index Start index.
732  * @param[in] number Number of elements to add/remove.
733  *
734  * Adds or removes elements from specified index on. Adding is done if
735  * @p number is a positive number, removing if @p number is negative.
736  * Note that the method does not change the validity of the arguments.
737  * This needs to be done by the client.
738  *
739  * @todo Needs to be implemented
740  ***************************************************************************/
741 void GFitsTableBitCol::resize_data(const int& index, const int& number)
742 {
743  //TODO
744 
745  // Return
746  return;
747 }
748 
749 
750 /***********************************************************************//**
751  * @brief Release column data
752  ***************************************************************************/
754 {
755  // Free any existing memory
756  if (m_data != NULL) delete [] m_data;
757 
758  // Mark pointer as free and reset loaded vector size
759  m_data = NULL;
760  m_size = 0;
761 
762  // Return
763  return;
764 }
765 
766 
767 /***********************************************************************//**
768  * @brief Allocates null value
769  ***************************************************************************/
770 void GFitsTableBitCol::alloc_nulval(const unsigned char* value)
771 {
772  // Free any existing memory
773  if (m_nulval != NULL) delete m_nulval;
774 
775  // Mark pointer as free
776  m_nulval = NULL;
777 
778  // If we have valid value, allocate and set nul value
779  if (value != NULL) {
780  m_nulval = new unsigned char;
781  *m_nulval = *value;
782  }
783 
784  // Return
785  return;
786 }
787 
788 
789 /***********************************************************************//**
790  * @brief Initialise column data
791  ***************************************************************************/
793 {
794  // Initialise data if they exist
795  if (m_data != NULL) {
796  for (int i = 0; i < m_size; ++i) {
797  m_data[i] = 0;
798  }
799  }
800 
801  // Return
802  return;
803 }
804 
805 
806 /***********************************************************************//**
807  * @brief Load table column from FITS file
808  *
809  * @exception GException::fits_hdu_not_found
810  * Specified HDU not found in FITS file.
811  * @exception GException::fits_error
812  * An error occured while loading column data from FITS file.
813  *
814  * Load Bit (vector) column into memory by reading 8 Bits at once.
815  ***************************************************************************/
817 {
818  // Compute total number of Bits in column
820 
821  // Compute number of Bytes and Bits per row
822  m_bytes_per_row = (m_number > 0) ? ((m_number-1) / 8) + 1 : 0;
824 
825  // Compute length of memory array
827 
828  // Load only if the column has a positive size
829  if (m_size > 0) {
830 
831  // Allocate and initialise fresh memory
832  alloc_data();
833  init_data();
834 
835  // If a FITS file is attached then load column data from the FITS
836  // file
837  if (FPTR(m_fitsfile)->Fptr != NULL) {
838 
839  // Move to the HDU
840  int status = 0;
841  status = __ffmahd(FPTR(m_fitsfile),
842  (FPTR(m_fitsfile)->HDUposition)+1,
843  NULL, &status);
844  if (status != 0) {
846  (FPTR(m_fitsfile)->HDUposition)+1,
847  status);
848  }
849 
850  // Load data 8 Bits at once
851  status = __ffgcv(FPTR(m_fitsfile), __TBYTE, m_colnum, 1, 1, m_size,
852  m_nulval, m_data, &m_anynul, &status);
853  if (status != 0) {
855  "for column \""+m_name+"\".");
856  }
857  }
858 
859  } // endif: column has a positive size
860 
861  // Return
862  return;
863 }
864 
865 
866 /***********************************************************************//**
867  * @brief Save table column into FITS file
868  *
869  * @exception GException::fits_hdu_not_found
870  * Specified HDU not found in FITS file.
871  * @exception GException::fits_error
872  * Error occured during writing of the column data.
873  *
874  * Save Bit (vector) column into FITS file by writing 8 Bits at once.
875  ***************************************************************************/
877 {
878  // Continue only if a FITS file is connected and data have been loaded
879  if (FPTR(m_fitsfile)->Fptr != NULL && m_colnum > 0 && m_data != NULL) {
880 
881  // Set any pending Bit
882  set_pending();
883 
884  // Move to the HDU
885  int status = 0;
886  status = __ffmahd(FPTR(m_fitsfile),
887  (FPTR(m_fitsfile)->HDUposition)+1, NULL,
888  &status);
889  if (status != 0) {
891  (FPTR(m_fitsfile)->HDUposition)+1,
892  status);
893  }
894 
895  // Save data 8 Bits at once
896  status = __ffpcn(FPTR(m_fitsfile), __TBYTE, m_colnum, 1, 1,
897  m_size, m_data, m_nulval, &status);
898  if (status != 0) {
899  throw GException::fits_error(G_SAVE_COLUMN, status);
900  }
901 
902  } // endif: FITS file was connected
903 
904  // Return
905  return;
906 }
907 
908 
909 /***********************************************************************//**
910  * @brief Get Bit for boolean access
911  *
912  * @param[in] row Row of column.
913  * @param[in] inx Vector index in column row.
914  *
915  * @exception GException::fits_invalid_row
916  * Table row out of valid range.
917  * @exception GException::out_of_range
918  * Table vector index out of valid range.
919  *
920  * Set the Bit for boolean data access. Note that this method assumes that
921  * the data have already been loaded.
922  ***************************************************************************/
923 void GFitsTableBitCol::get_bit(const int& row, const int& inx)
924 {
925  // Check row value
926  #if defined(G_RANGE_CHECK)
927  if (row < 0 || row >= m_length) {
929  }
930  #endif
931 
932  // Check inx value
933  #if defined(G_RANGE_CHECK)
934  if (inx < 0 || inx >= m_number) {
935  throw GException::out_of_range(G_GET_BIT, inx, 0, m_number-1);
936  }
937  #endif
938 
939  // Compute Byte and Bit mask
940  m_bit_byte = row * m_bytes_per_row + inx / 8;
941  m_bit_mask = 1 << (7 - (inx % 8));
942 
943  // Set Bit value
945 
946  // Return
947  return;
948 }
949 
950 
951 /***********************************************************************//**
952  * @brief Set pending Bit
953  *
954  * Write the pending Bit into the data. Note that this method assumes that
955  * the data have already been loaded.
956  ***************************************************************************/
958 {
959  // Continue only if we have a pending Bit
960  if (m_bit_pending) {
961 
962  // Set or unset Bit
963  if (m_bit_value) {
965  }
966  else {
968  }
969 
970  // Signal that no more Bit is pending
971  m_bit_pending = false;
972 
973  }
974 
975  // Return
976  return;
977 }
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:1046
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:413