GammaLib 2.0.0
Loading...
Searching...
No Matches
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-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 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"
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
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
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
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 ***************************************************************************/
162unsigned 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 ***************************************************************************/
180const 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 ***************************************************************************/
233std::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 ***************************************************************************/
251double 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 ***************************************************************************/
272int 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::out_of_range
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 ***************************************************************************/
297void 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::out_of_range(G_INSERT, "FITS table row number",
302 row, m_length+1);
303 }
304
305 // Continue only if there are rows to be inserted
306 if (nrows > 0) {
307
308 // If we have no rows yet then simply set the length to the
309 // number of rows to be inserted
310 if (m_length == 0) {
311 m_length = nrows;
313 alloc_data();
314 init_data();
315 }
316
317 // ... otherwise fetch data, allocate new data and copy over
318 // the existing items
319 else {
320
321 // If data are not available then load them now
322 if (m_data == NULL) fetch_data();
323
324 // Compute new column length
325 int length = m_length + nrows;
326
327 // Calculate size of new memory
328 m_size = m_number * length;
329
330 // Allocate new data to hold the column
331 unsigned short* new_data = new unsigned short[m_size];
332
333 // Compute the number of elements before the insertion point,
334 // the number of elements that get inserted, and the total
335 // number of elements after the insertion point
336 int n_before = m_number * row;
337 int n_insert = m_number * nrows;
338 int n_after = m_number * (m_length - row);
339
340 // Copy and initialise data
341 unsigned short* src = m_data;
342 unsigned short* dst = new_data;
343 for (int i = 0; i < n_before; ++i) {
344 *dst++ = *src++;
345 }
346 for (int i = 0; i < n_insert; ++i) {
347 *dst++ = 0;
348 }
349 for (int i = 0; i < n_after; ++i) {
350 *dst++ = *src++;
351 }
352
353 // Free old data
354 if (m_data != NULL) delete [] m_data;
355
356 // Set pointer to new data and store length
357 m_data = new_data;
358 m_length = length;
359
360 } // endelse: there were already data
361
362 } // endfor: there were rows to be inserted
363
364 // Return
365 return;
366}
367
368
369/***********************************************************************//**
370 * @brief Remove rows from column
371 *
372 * @param[in] row Row after which rows should be removed (0=first row).
373 * @param[in] nrows Number of rows to be removed.
374 *
375 * @exception GException::out_of_range
376 * Specified row is invalid.
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 ***************************************************************************/
382void GFitsTableUShortCol::remove(const int& row, const int& nrows)
383{
384 // Make sure that row is valid
385 if (row < 0 || row >= m_length) {
386 throw GException::out_of_range(G_REMOVE, "FITS table row number",
387 row, m_length);
388 }
389
390 // Make sure that we don't remove beyond the limit
392 throw GException::out_of_range(G_REMOVE, "Number of FITS table rows",
393 nrows, m_length-row+1);
394 }
395
396 // Continue only if there are rows to be removed
397 if (nrows > 0) {
398
399 // If data are not available then load them now
400 if (m_data == NULL) fetch_data();
401
402 // Compute new column length
403 int length = m_length - nrows;
404
405 // Calculate size of new memory
406 m_size = m_number * length;
407
408 // If we have rows remaining then allocate new data to hold
409 // the column
410 if (m_size > 0) {
411
412 // Allocate new data to hold the column
413 unsigned short* new_data = new unsigned short[m_size];
414
415 // Compute the number of elements before the removal point,
416 // the number of elements that get removed, and the total
417 // number of elements after the removal point
418 int n_before = m_number * row;
419 int n_remove = m_number * nrows;
420 int n_after = m_number * (length - row);
421
422 // Copy data
423 unsigned short* src = m_data;
424 unsigned short* dst = new_data;
425 for (int i = 0; i < n_before; ++i) {
426 *dst++ = *src++;
427 }
428 src += n_remove;
429 for (int i = 0; i < n_after; ++i) {
430 *dst++ = *src++;
431 }
432
433 // Free old data
434 if (m_data != NULL) delete [] m_data;
435
436 // Set pointer to new data and store length
437 m_data = new_data;
438 m_length = length;
439
440 } // endif: there are still elements after removal
441
442 // ... otherwise just remove all data
443 else {
444
445 // Free old data
446 if (m_data != NULL) delete [] m_data;
447
448 // Set pointer to new data and store length
449 m_data = NULL;
450 m_length = length;
451 }
452
453 } // endfor: there were rows to be removed
454
455 // Return
456 return;
457}
458
459
460/***********************************************************************//**
461 * @brief Set nul value
462 *
463 * @param[in] value Nul value.
464 *
465 * @todo To correctly reflect the nul value in the data, the column should
466 * be reloaded. However, the column may have been changed, so in principle
467 * saving is needed. However, we may not want to store the data, hence saving
468 * is also not desired. We thus have to develop a method to update the
469 * column information for a new nul value in place ...
470 ***************************************************************************/
471void GFitsTableUShortCol::nulval(const unsigned short* value)
472{
473 // Allocate nul value
474 alloc_nulval(value);
475
476 // Update column
477// if (m_data != NULL) {
478// save();
479// load();
480// }
481
482 // Return
483 return;
484}
485
486
487/*==========================================================================
488 = =
489 = Private methods =
490 = =
491 ==========================================================================*/
492
493/***********************************************************************//**
494 * @brief Initialise class members
495 ***************************************************************************/
497{
498 // Initialise members
500 m_data = NULL;
501 m_nulval = NULL;
502
503 // Return
504 return;
505}
506
507
508/***********************************************************************//**
509 * @brief Copy class members
510 *
511 * @param[in] column Column.
512 *
513 * Sets the content of the vector column by copying from another column.
514 * If the code is compiled with the small memory option, and if the source
515 * column has not yet been loaded, then we only load the column temporarily
516 * for copying purposes and release it again once copying is finished.
517 ***************************************************************************/
519{
520 // Fetch data if necessary
521 bool not_loaded = (!column.is_loaded());
522 if (not_loaded) {
523 column.fetch_data();
524 }
525
526 // Copy attributes
527 m_type = column.m_type;
528 m_size = column.m_size;
529 m_varlen = column.m_varlen;
530 m_rowstart = column.m_rowstart;
531
532 // Copy column data
533 if (column.m_data != NULL && m_size > 0) {
534 alloc_data();
535 for (int i = 0; i < m_size; ++i) {
536 m_data[i] = column.m_data[i];
537 }
538 }
539
540 // Copy NULL value
541 alloc_nulval(column.m_nulval);
542
543 // Small memory option: release column if it was fetch above
544 #if defined(G_SMALL_MEMORY)
545 if (not_loaded) {
546 const_cast<GFitsTableUShortCol*>(&column)->release_data();
547 }
548 #endif
549
550 // Return
551 return;
552}
553
554
555/***********************************************************************//**
556 * @brief Delete class members
557 ***************************************************************************/
559{
560 // Free memory
561 if (m_data != NULL) delete [] m_data;
562 if (m_nulval != NULL) delete m_nulval;
563
564 // Mark memory as freed
565 m_data = NULL;
566 m_nulval = NULL;
567
568 // Return
569 return;
570}
571
572
573/***********************************************************************//**
574 * @brief Returns format string of ASCII table
575 ***************************************************************************/
577{
578 // Initialize format string
579 std::string format;
580
581 // Set type code
582 format.append("I5");
583
584 // Set width
585 //format.append(gammalib::str(m_width));
586
587 // Return format
588 return format;
589}
590
591
592/***********************************************************************//**
593 * @brief Allocates column data
594 ***************************************************************************/
596{
597 // Free any existing memory
598 if (m_data != NULL) delete [] m_data;
599
600 // Mark pointer as free
601 m_data = NULL;
602
603 // Allocate new data
604 if (m_size > 0) {
605 m_data = new unsigned short[m_size];
606 }
607
608 // Return
609 return;
610}
611
612
613/***********************************************************************//**
614 * @brief Fetch column data
615 ***************************************************************************/
617{
618 // Load column (circumvent const correctness)
619 const_cast<GFitsTableUShortCol*>(this)->load_column();
620
621 // Return
622 return;
623}
624
625
626/***********************************************************************//**
627 * @brief Resize column data
628 *
629 * @param[in] index Start index.
630 * @param[in] number Number of elements to add/remove.
631 *
632 * Adds or removes elements from specified index on. Adding is done if
633 * @p number is a positive number, removing if @p number is negative.
634 * Note that the method does not change the validity of the arguments.
635 * This needs to be done by the client.
636 ***************************************************************************/
637void GFitsTableUShortCol::resize_data(const int& index, const int& number)
638{
639 // Continue only if number of elements is not zero
640 if (number != 0) {
641
642 // If data are not available then load them now
643 if (m_data == NULL) fetch_data();
644
645 // If elements should be removed then do not allocate new memory
646 // but just move elements forward and change the logical size of
647 // memory. Only if all elements should be removed the memory is
648 // released.
649 if (number < 0) {
650 int left = index - number;
651 unsigned short* dst = m_data + index;
652 unsigned short* src = m_data + left;
653 int num = m_size - left;
654 for (int i = 0; i < num; ++i) {
655 *dst++ = *src++;
656 }
657 m_size += number;
658 if (m_size < 1) {
659 release_data();
660 }
661 }
662
663 // If elements should be added then allocate new memory, copy over
664 // the old data and initialise the new elements
665 else {
666 int left = m_size - index;
667 m_size += number;
668 unsigned short* new_data = new unsigned short[m_size];
669 unsigned short* dst = new_data;
670 unsigned short* src = m_data;
671 for (int i = 0; i < index; ++i) {
672 *dst++ = *src++;
673 }
674 for (int i = 0; i < number; ++i) {
675 *dst++ = 0;
676 }
677 for (int i = 0; i < left; ++i) {
678 *dst++ = *src++;
679 }
680 if (m_data != NULL) delete [] m_data;
681 m_data = new_data;
682 }
683
684 } // endif: number was non-zero
685
686 // Return
687 return;
688}
689
690
691/***********************************************************************//**
692 * @brief Release column data
693 ***************************************************************************/
695{
696 // Free any existing memory
697 if (m_data != NULL) delete [] m_data;
698
699 // Mark pointer as free and reset loaded vector size
700 m_data = NULL;
701 m_size = 0;
702
703 // Return
704 return;
705}
706
707
708/***********************************************************************//**
709 * @brief Allocates null value
710 ***************************************************************************/
711void GFitsTableUShortCol::alloc_nulval(const unsigned short* value)
712{
713 // Free any existing memory
714 if (m_nulval != NULL) delete m_nulval;
715
716 // Mark pointer as free
717 m_nulval = NULL;
718
719 // If we have valid value, allocate and set nul value
720 if (value != NULL) {
721 m_nulval = new unsigned short;
722 *m_nulval = *value;
723 }
724
725 // Return
726 return;
727}
728
729
730/***********************************************************************//**
731 * @brief Initialise column data
732 ***************************************************************************/
734{
735 // Initialise data if they exist
736 if (m_data != NULL) {
737 for (int i = 0; i < m_size; ++i) {
738 m_data[i] = 0;
739 }
740 }
741
742 // Return
743 return;
744}
Exception handler interface definition.
CFITSIO interface header.
#define __TUSHORT
#define G_INSERT
#define G_REMOVE
FITS table unsigned short integer column class interface definition.
Gammalib tools definition.
Abstract interface for FITS table column.
int m_type
Column type.
int m_length
Length of column (number of rows)
const int & nrows(void) const
Returns number of rows in column.
std::vector< int > m_rowstart
Start index of each row.
int m_size
Size of allocated data area (0 if not loaded)
int m_varlen
Maximum number of elements in variable-length.
GFitsTableCol & operator=(const GFitsTableCol &column)
Assignment operator.
const int & number(void) const
Returns number of elements in column.
void free_members(void)
Delete class members.
virtual void load_column(void)
Load table column from FITS file.
void init_members(void)
Initialise class members.
virtual int offset(const int &row, const int &inx) const
Compute offset of column element in memory.
int m_number
Number of elements in column.
FITS table unsigned short integer column.
virtual void release_data(void)
Release column data.
unsigned short * m_data
Data vector.
virtual void resize_data(const int &index, const int &number)
Resize column data.
virtual void alloc_data(void)
Allocates column data.
virtual std::string string(const int &row, const int &col=0) const
Get string value.
void free_members(void)
Delete class members.
unsigned short * nulval(void)
Returns pointer to nul value.
virtual void fetch_data(void) const
Fetch column data.
virtual void clear(void)
Clear instance.
void copy_members(const GFitsTableUShortCol &column)
Copy class members.
virtual std::string ascii_format(void) const
Returns format string of ASCII table.
virtual double real(const int &row, const int &col=0) const
Get double precision value.
virtual GFitsTableUShortCol * clone(void) const
Clone column.
virtual bool is_loaded(void) const
Checks if column has been loaded.
virtual int integer(const int &row, const int &col=0) const
Get integer value.
void init_members(void)
Initialise class members.
GFitsTableUShortCol(void)
Constructor.
GFitsTableUShortCol & operator=(const GFitsTableUShortCol &column)
Assignment operator.
void alloc_nulval(const unsigned short *value)
Allocates null value.
virtual void remove(const int &row, const int &nrows)
Remove rows from column.
virtual ~GFitsTableUShortCol(void)
Destructor.
unsigned short & operator()(const int &row, const int &inx=0)
Column data access operator.
virtual void init_data(void)
Initialise column data.
virtual void insert(const int &row, const int &nrows)
Insert rows in column.
unsigned short * m_nulval
NULL value.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489