GammaLib 2.0.0
Loading...
Searching...
No Matches
GArf.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GArf.cpp - XSPEC Auxiliary Response File class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2013-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 GArf.cpp
23 * @brief XSPEC Auxiliary Response File class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GArf.hpp"
32#include "GException.hpp"
33#include "GFilename.hpp"
34#include "GTools.hpp"
35#include "GFits.hpp"
36#include "GFitsTable.hpp"
37#include "GFitsBinTable.hpp"
40
41/* __ Method name definitions ____________________________________________ */
42#define G_OPERATOR_PLUS "GArf::operator+=(GArf&)"
43#define G_OPERATOR_MINUS "GArf::operator-=(GArf&)"
44#define G_OPERATOR "GArf::operator[](std::string&)"
45#define G_OPERATOR2 "GArf::operator()(std::string&, GEnergy&)"
46#define G_AT1 "GArf::at(int&)"
47#define G_AT2 "GArf::at(int&, int&)"
48#define G_APPEND "GArf::append(std::string&, std::vector<double>&)"
49
50/* __ Macros _____________________________________________________________ */
51
52/* __ Coding definitions _________________________________________________ */
53
54/* __ Debug definitions __________________________________________________ */
55
56
57/*==========================================================================
58 = =
59 = Constructors/destructors =
60 = =
61 ==========================================================================*/
62
63/***********************************************************************//**
64 * @brief Void constructor
65 ***************************************************************************/
67{
68 // Initialise members
70
71 // Return
72 return;
73}
74
75
76/***********************************************************************//**
77 * @brief File constructor
78 *
79 * @param[in] filename File name.
80 ***************************************************************************/
81GArf::GArf(const GFilename& filename)
82{
83 // Initialise members
85
86 // Load ARF file
88
89 // Return
90 return;
91}
92
93
94/***********************************************************************//**
95 * @brief Energy boundary constructor
96 *
97 * @param[in] ebds Energy boundaries.
98 ***************************************************************************/
99GArf::GArf(const GEbounds& ebds)
100{
101 // Initialise members
102 init_members();
103
104 // Set energy boundaries
105 m_ebounds = ebds;
106
107 // Set log true energy node array
108 set_logetrue();
109
110 // Initialize spectral response
111 m_specresp.assign(ebds.size(), 0.0);
112
113 // Return
114 return;
115}
116
117
118/***********************************************************************//**
119 * @brief Copy constructor
120 *
121 * @param[in] arf Auxiliary Response File.
122 ***************************************************************************/
123GArf::GArf(const GArf& arf)
124{
125 // Initialise members
126 init_members();
127
128 // Copy members
129 copy_members(arf);
130
131 // Return
132 return;
133}
134
135
136/***********************************************************************//**
137 * @brief Destructor
138 ***************************************************************************/
140{
141 // Free members
142 free_members();
143
144 // Return
145 return;
146}
147
148
149/*==========================================================================
150 = =
151 = Operators =
152 = =
153 ==========================================================================*/
154
155/***********************************************************************//**
156 * @brief Assignment operator
157 *
158 * @param[in] arf Auxiliary Response File.
159 * @return Auxiliary Response File.
160 ***************************************************************************/
162{
163 // Execute only if object is not identical
164 if (this != &arf) {
165
166 // Free members
167 free_members();
168
169 // Initialise members
170 init_members();
171
172 // Copy members
173 copy_members(arf);
174
175 } // endif: object was not identical
176
177 // Return
178 return *this;
179}
180
181
182/***********************************************************************//**
183 * @brief Add Auxiliary Response File
184 *
185 * @param[in] arf Auxiliary Response File.
186 * @return Sum of Auxiliary Response Files.
187 *
188 * @exception GException::invalid_value
189 * Incompatible Auxiliary Response Files.
190 *
191 * Adds the ARF values of an Auxiliary Response File to the current values.
192 *
193 * The operator only works if the provide Auxiliary Response File has the
194 * same energy binning than the current Auxiliary Response File.
195 ***************************************************************************/
197{
198 // Throw an exception if the ARF are not compatible
199 if (this->ebounds() != arf.ebounds()) {
200 std::string msg = "Incompatible energy binning of Auxiliary "
201 "Response File.";
203 }
204
205 // Add ARF values
206 for (int i = 0; i < this->size(); ++i) {
207 m_specresp[i] += arf.m_specresp[i];
208 }
209
210 // Return
211 return *this;
212}
213
214
215/***********************************************************************//**
216 * @brief Subtract Auxiliary Response File
217 *
218 * @param[in] arf Auxiliary Response File.
219 * @return Difference of Auxiliary Response File.
220 *
221 * @exception GException::invalid_value
222 * Incompatible Auxiliary Response Files.
223 *
224 * Subtracts the ARF values of an Auxiliary Response File from the current
225 * values.
226 *
227 * The operator only works if the provide Auxiliary Response File has the
228 * same energy binning than the current Auxiliary Response File.
229 ***************************************************************************/
231{
232 // Throw an exception if the ARF are not compatible
233 if (this->ebounds() != arf.ebounds()) {
234 std::string msg = "Incompatible energy binning of Auxiliary "
235 "Response File.";
237 }
238
239 // Subtract ARF values
240 for (int i = 0; i < this->size(); ++i) {
241 m_specresp[i] -= arf.m_specresp[i];
242 }
243
244 // Return
245 return *this;
246}
247
248
249/***********************************************************************//**
250 * @brief Scale Auxiliary Response File values
251 *
252 * @param[in] scale Scale factor.
253 * @return Scaled Auxiliary Response File.
254 *
255 * Multiplies the values of the Auxiliary Response File with a scale factor.
256 ***************************************************************************/
257GArf& GArf::operator*=(const double& scale)
258{
259 // Scale ARF values
260 for (int i = 0; i < this->size(); ++i) {
261 m_specresp[i] *= scale;
262 }
263
264 // Return
265 return *this;
266}
267
268
269/***********************************************************************//**
270 * @brief Divide Auxiliary Response File values
271 *
272 * @param[in] scale Division factor.
273 * @return Divided Auxiliary Response File.
274 *
275 * Divides the values of the Auxiliary Response File by a division factor.
276 ***************************************************************************/
277GArf& GArf::operator/=(const double& scale)
278{
279 // Divide ARF values
280 for (int i = 0; i < this->size(); ++i) {
281 m_specresp[i] /= scale;
282 }
283
284 // Return
285 return *this;
286}
287
288
289/***********************************************************************//**
290 * @brief Return additional vector column
291 *
292 * @param[in] colname Vector column name.
293 * @return Vector column.
294 *
295 * Returns reference to additional vector column.
296 ***************************************************************************/
297std::vector<double>& GArf::operator[](const std::string& colname)
298{
299 // Determine index of additional column (-1 if not found)
300 int index = column_index(colname);
301
302 // Throw exception if index not found
303 if (index == -1) {
304 std::string msg = "Could not find additional column with name \""+
305 colname+"\".";
307 }
308
309 // Return reference to vector column
310 return (m_coldata[index]);
311}
312
313
314/***********************************************************************//**
315 * @brief Return additional vector column (const version)
316 *
317 * @param[in] colname Vector column name.
318 * @return Vector column.
319 *
320 * Returns reference to additional vector column.
321 ***************************************************************************/
322const std::vector<double>& GArf::operator[](const std::string& colname) const
323{
324 // Determine index of additional column (-1 if not found)
325 int index = column_index(colname);
326
327 // Throw exception if index not found
328 if (index == -1) {
329 std::string msg = "Could not find additional column with name \""+
330 colname+"\".";
332 }
333
334 // Return reference to vector column
335 return (m_coldata[index]);
336}
337
338
339/***********************************************************************//**
340 * @brief Return vector column content as function of energy
341 *
342 * @param[in] colname Vector column name.
343 * @param[in] energy Energy.
344 * @return Vector column content.
345 *
346 * Returns content of additional vector column as function of @p energy.
347 ***************************************************************************/
348double GArf::operator()(const std::string& colname,
349 const GEnergy& energy) const
350{
351 // Determine index of additional column (-1 if not found)
352 int index = column_index(colname);
353
354 // Throw exception if index not found
355 if (index == -1) {
356 std::string msg = "Could not find additional column with name \""+
357 colname+"\".";
359 }
360
361 // Get reference to vector column
362 const std::vector<double>& column = m_coldata[index];
363
364 // Perform log-log interpolation of vector column content
365 m_logetrue.set_value(energy.log10TeV());
366 double wgt_left = m_logetrue.wgt_left();
367 double wgt_right = m_logetrue.wgt_right();
368 double value_left = column[m_logetrue.inx_left()];
369 double value_right = column[m_logetrue.inx_right()];
370 double value = 0.0;
371 if (value_left > 0.0 && value_right > 0.0) {
372 value = std::exp(wgt_left * std::log(value_left) +
373 wgt_right * std::log(value_right));
374 }
375 if (value < 0.0) {
376 value = 0.0;
377 }
378
379 // Return value
380 return value;
381}
382
383
384/*==========================================================================
385 = =
386 = Public methods =
387 = =
388 ==========================================================================*/
389
390/***********************************************************************//**
391 * @brief Clear object.
392 *
393 * Reset object to a clean initial state.
394 ***************************************************************************/
395void GArf::clear(void)
396{
397 // Free memory and initialise members
398 free_members();
399 init_members();
400
401 // Return
402 return;
403}
404
405
406/***********************************************************************//**
407 * @brief Clone object
408 *
409 * @return Pointer to Auxiliary Response File.
410 ***************************************************************************/
411GArf* GArf::clone(void) const
412{
413 // Clone client
414 return new GArf(*this);
415}
416
417
418/***********************************************************************//**
419 * @brief Return content of spectral bin
420 *
421 * @param[in] index Spectral bin index [0,...,size()[.
422 *
423 * @exception GException::out_of_range
424 * Spectral bin index is out of range.
425 *
426 * Returns reference to content of spectral bin with specified @p index.
427 ***************************************************************************/
428double& GArf::at(const int& index)
429{
430 // Throw an exception if index is out of range
431 if (index < 0 || index >= size()) {
432 throw GException::out_of_range(G_AT1, "Spectral bin index",
433 index, size());
434 }
435
436 // Return reference
437 return (m_specresp[index]);
438}
439
440
441/***********************************************************************//**
442 * @brief Return content of spectral bin (const version)
443 *
444 * @param[in] index Spectral bin index [0,...,size()[.
445 *
446 * @exception GException::out_of_range
447 * Spectral bin index is out of range.
448 * *
449 * Returns reference to content of spectral bin with specified @p index.
450 ***************************************************************************/
451const double& GArf::at(const int& index) const
452{
453 // Throw an exception if index is out of range
454 if (index < 0 || index >= size()) {
455 throw GException::out_of_range(G_AT1, "Spectral bin index",
456 index, size());
457 }
458
459 // Return reference
460 return (m_specresp[index]);
461}
462
463
464/***********************************************************************//**
465 * @brief Return content of additional columns
466 *
467 * @param[in] index Bin index [0,...,size()-1].
468 * @param[in] col Columns index [0,...,columns()-1].
469 *
470 * @exception GException::out_of_range
471 * Spectral bin or column index is out of range.
472 *
473 * Returns reference to content of additional columns.
474 ***************************************************************************/
475double& GArf::at(const int& index, const int& col)
476{
477 // Throw an exception if bin or column index is out of range
478 if (index < 0 || index >= size()) {
479 throw GException::out_of_range(G_AT2, "Bin index", index, size());
480 }
481 if (col < 0 || col >= columns()) {
482 throw GException::out_of_range(G_AT2, "Column index", col, columns());
483 }
484
485 // Return reference
486 return (m_coldata[col][index]);
487}
488
489
490/***********************************************************************//**
491 * @brief Return content of additional columns (const version)
492 *
493 * @param[in] index Bin index [0,...,size()-1].
494 * @param[in] col Columns index [0,...,columns()-1].
495 *
496 * @exception GException::out_of_range
497 * Spectral bin or column index is out of range.
498 *
499 * Returns reference to content of additional columns.
500 ***************************************************************************/
501const double& GArf::at(const int& index, const int& col) const
502{
503 // Throw an exception if bin or column index is out of range
504 if (index < 0 || index >= size()) {
505 throw GException::out_of_range(G_AT2, "Bin index", index, size());
506 }
507 if (col < 0 || col >= columns()) {
508 throw GException::out_of_range(G_AT2, "Column index", col, columns());
509 }
510
511 // Return reference
512 return (m_coldata[col][index]);
513}
514
515
516/***********************************************************************//**
517 * @brief Append additional column to spectrum
518 *
519 * @param[in] name Additional column name.
520 * @param[in] column Additional column data.
521 ***************************************************************************/
522void GArf::append(const std::string& name, const std::vector<double>& column)
523{
524 // Throw an exception if the number of elements in the column does not
525 // correspond to the size of the spectrum
526 if (column.size() != size()) {
527 std::string msg = "Size of column "+gammalib::str(column.size())+
528 " is incompatible with size of spectrum "+
529 gammalib::str(size())+".";
531 }
532
533 // Append column name
534 m_colnames.push_back(name);
535
536 // Append column data
537 m_coldata.push_back(column);
538
539 // Return
540 return;
541}
542
543
544/***********************************************************************//**
545 * @brief Load Auxiliary Response File
546 *
547 * @param[in] filename File name.
548 *
549 * Loads the Auxiliary Response File from the `SPECRESP` extension of the
550 * FITS file.
551 ***************************************************************************/
552void GArf::load(const GFilename& filename)
553{
554 // Clear response
555 clear();
556
557 // Open FITS file (without extension name as the user is not allowed
558 // to modify the extension names)
559 GFits fits(filename.url());
560
561 // Read ARF data
562 read(fits);
563
564 // Close FITS file
565 fits.close();
566
567 // Store filename
569
570 // Return
571 return;
572}
573
574
575/***********************************************************************//**
576 * @brief Save Auxiliary Response File
577 *
578 * @param[in] filename File name.
579 * @param[in] clobber Overwrite existing file?
580 *
581 * Saves the Auxiliary Response File into a FITS file. If a file with the
582 * given @p filename does not yet exist it will be created. If the file
583 * exists it can be overwritten if the @p clobber flag is set to `true`.
584 * Otherwise an exception is thrown.
585 *
586 * The method will save the `SPECRESP` binary FITS table into the FITS file
587 * that contains the values of the Auxiliary Response File.
588 ***************************************************************************/
589void GArf::save(const GFilename& filename, const bool& clobber) const
590{
591 // Create FITS file
592 GFits fits;
593
594 // Write ARF into file
595 write(fits);
596
597 // Save to file (without extension name since the requested extension
598 // may not yet exist in the file)
599 fits.saveto(filename.url(), clobber);
600
601 // Store filename
603
604 // Return
605 return;
606}
607
608
609/***********************************************************************//**
610 * @brief Read Auxiliary Response File
611 *
612 * @param[in] fits FITS file.
613 *
614 * Loads the Auxiliary Response File from the `SPECRESP` extension of the
615 * FITS file.
616 ***************************************************************************/
617void GArf::read(const GFits& fits)
618{
619 // Clear response
620 clear();
621
622 // Get ARF table
623 const GFitsTable& table = *fits.table(gammalib::extname_arf);
624
625 // Read ARF data
626 read(table);
627
628 // Return
629 return;
630}
631
632
633/***********************************************************************//**
634 * @brief Read Auxiliary Response File
635 *
636 * @param[in] table ARF FITS table.
637 *
638 * Reads the Auxiliary Response File from a FITS table. The true energy
639 * boundaries are expected in the `ENERG_LO` and `ENERG_HI` columns, the
640 * response information is expected in the `SPECRESP` column.
641 *
642 * The method will analyze the unit of the `SPECRESP` column, and if either
643 * `m**2`, `m^2` or `m2` are encountered, multiply the values of the column
644 * by \f$10^4\f$ to convert the response into units of \f$cm^2\f$. Units of
645 * the `ENERG_LO` and `ENERG_HI` columns are also interpreted for conversion.
646 *
647 * See
648 * http://heasarc.gsfc.nasa.gov/docs/heasarc/caldb/docs/memos/cal_gen_92_002/cal_gen_92_002.html#tth_sEc4
649 * for details about the Auxiliary Response File format.
650 ***************************************************************************/
651void GArf::read(const GFitsTable& table)
652{
653 // Clear members
654 clear();
655
656 // Get pointer to data columns
657 const GFitsTableCol* energy_lo = table["ENERG_LO"];
658 const GFitsTableCol* energy_hi = table["ENERG_HI"];
659 const GFitsTableCol* specresp = table["SPECRESP"];
660
661 // Determine effective area conversion factor. Internal
662 // units are cm^2
663 std::string u_specresp =
665 double c_specresp = 1.0;
666 if (u_specresp == "m**2" || u_specresp == "m^2" || u_specresp == "m2") {
667 c_specresp = 10000.0;
668 }
669
670 // Extract number of energy bins
671 int num = energy_lo->nrows();
672
673 // Set energy bins
674 for (int i = 0; i < num; ++i) {
675
676 // Append energy bin
677 GEnergy emin(energy_lo->real(i), energy_lo->unit());
678 GEnergy emax(energy_hi->real(i), energy_hi->unit());
679 m_ebounds.append(emin, emax);
680
681 // Append effective area value
682 double aeff = specresp->real(i) * c_specresp;
683 m_specresp.push_back(aeff);
684
685 } // endfor: looped over energy bins
686
687 // Read any additional columns
688 for (int icol = 0; icol < table.ncols(); ++icol) {
689
690 // Fall through if the column is a standard column
691 std::string colname(table[icol]->name());
692 if ((colname == "ENERG_LO") ||
693 (colname == "ENERG_HI") ||
694 (colname == "SPECRESP")) {
695 continue;
696 }
697
698 // Get pointer to column
699 const GFitsTableCol* column = table[icol];
700
701 // Set column vector
702 std::vector<double> coldata;
703 for (int i = 0; i < num; ++i) {
704 coldata.push_back(column->real(i));
705 }
706
707 // Append column
708 append(colname, coldata);
709
710 } // endfor: looped over all additional columns
711
712 // Set log true energy node array
713 set_logetrue();
714
715 // Store FITS header
716 m_header = table.header();
717
718 // Return
719 return;
720}
721
722
723/***********************************************************************//**
724 * @brief Write Auxiliary Response File
725 *
726 * @param[in] fits FITS file.
727 *
728 * Writes the Auxiliary Response File into the `SPECRESP` extension of the
729 * FITS file. An existing extension with the same name will be removed from
730 * the FITS file before writing.
731 *
732 * The method writes the boundaries of the true energy bins into the
733 * `ENERG_LO` and `ENERG_HI` columns, response information will be written
734 * into the `SPECRESP` column.
735 *
736 * See
737 * http://heasarc.gsfc.nasa.gov/docs/heasarc/caldb/docs/memos/cal_gen_92_002/cal_gen_92_002.html#tth_sEc4
738 * for details about the Auxiliary Response File format.
739 ***************************************************************************/
740void GArf::write(GFits& fits) const
741{
742 // If the FITS object contains already an extension with the same
743 // name then remove now this extension
746 }
747
748 // Set column length
749 int length = size();
750
751 // Continue only if there are bins
752 if (length > 0) {
753
754 // Create new binary table
755 GFitsBinTable hdu;
756
757 // Allocate floating point vector columns
758 GFitsTableFloatCol energy_lo("ENERG_LO", length);
759 GFitsTableFloatCol energy_hi("ENERG_HI", length);
760 GFitsTableFloatCol specresp("SPECRESP", length);
761
762 // Fill columns
763 for (int i = 0; i < length; ++i) {
764 energy_lo(i) = (float)m_ebounds.emin(i).keV();
765 energy_hi(i) = (float)m_ebounds.emax(i).keV();
766 specresp(i) = (float)m_specresp[i];
767 }
768
769 // Set column units
770 energy_lo.unit("keV");
771 energy_hi.unit("keV");
772 specresp.unit("cm**2");
773
774 // Set table attributes
776
777 // Append columns to table
778 hdu.append(energy_lo);
779 hdu.append(energy_hi);
780 hdu.append(specresp);
781
782 // Append any additional columns
783 for (int icol = 0; icol < columns(); ++icol) {
784
785 // Allocate floating point vector columns
786 GFitsTableFloatCol column(m_colnames[icol], length);
787
788 // Fill columns
789 for (int i = 0; i < length; ++i) {
790 column(i) = (float)m_coldata[icol][i];
791 }
792
793 // Append columns to table
794 hdu.append(column);
795
796 } // endfor: looped over all additional columns
797
798 // Write mandatory header keywords
799 hdu.card("TELESCOP", "unknown", "Telescope");
800 hdu.card("INSTRUME", "unknown", "Instrument");
801 hdu.card("FILTER", "none", "Filter");
802 hdu.card("HDUCLASS", "OGIP", "Format conforms to OGIP standard");
803 hdu.card("HDUCLAS1", "RESPONSE", "Extension contains response data");
804 hdu.card("HDUCLAS2", "SPECRESP", "Extension contains an ARF");
805 hdu.card("HDUVERS", "1.1.0", "Version of the file format");
806
807 // Write additional header keywords (do not overwrite any existing
808 // keywords, except of "TELESCOP", "INSTRUME" and "FILTER")
809 for (int i = 0; i < m_header.size(); ++i) {
810 if ((!hdu.contains(m_header[i].keyname())) ||
811 (m_header[i].keyname() == "TELESCOP") ||
812 (m_header[i].keyname() == "INSTRUME") ||
813 (m_header[i].keyname() == "FILTER")) {
814 hdu.card(m_header[i]);
815 }
816 }
817
818 // Append HDU to FITS file
819 fits.append(hdu);
820
821 } // endif: there were data to write
822
823 // Return
824 return;
825}
826
827
828/***********************************************************************//**
829 * @brief Print Auxiliary Response File
830 *
831 * @param[in] chatter Chattiness.
832 * @return String containing Auxiliary Response File information.
833 ***************************************************************************/
834std::string GArf::print(const GChatter& chatter) const
835{
836 // Initialise result string
837 std::string result;
838
839 // Continue only if chatter is not silent
840 if (chatter != SILENT) {
841
842 // Append header
843 result.append("=== GArf ===");
844
845 // Append energy boundary information
846 result.append("\n"+gammalib::parformat("Number of bins"));
847 result.append(gammalib::str(m_ebounds.size()));
848 result.append("\n"+gammalib::parformat("Energy range"));
849 result.append(m_ebounds.emin().print());
850 result.append(" - ");
851 result.append(m_ebounds.emax().print());
852
853 } // endif: chatter was not silent
854
855 // Return result
856 return result;
857}
858
859
860/*==========================================================================
861 = =
862 = Private methods =
863 = =
864 ==========================================================================*/
865
866/***********************************************************************//**
867 * @brief Initialise class members
868 ***************************************************************************/
870{
871 // Initialise members
875 m_specresp.clear();
876 m_colnames.clear();
877 m_coldata.clear();
878 m_header.clear();
879
880 // Return
881 return;
882}
883
884
885/***********************************************************************//**
886 * @brief Copy class members
887 *
888 * @param[in] arf Auxiliary Response File.
889 ***************************************************************************/
890void GArf::copy_members(const GArf& arf)
891{
892 // Copy members
894 m_ebounds = arf.m_ebounds;
898 m_coldata = arf.m_coldata;
899 m_header = arf.m_header;
900
901 // Return
902 return;
903}
904
905
906/***********************************************************************//**
907 * @brief Delete class members
908 ***************************************************************************/
910{
911 // Return
912 return;
913}
914
915
916/***********************************************************************//**
917 * @brief Set true energy node array
918 ***************************************************************************/
920{
921 // Clear node array
923
924 // Continue only if there are true energies in Arf
925 int netrue = m_ebounds.size();
926 if (netrue > 0) {
927
928 // Reserve space in node array
929 m_logetrue.reserve(netrue);
930
931 // Append all log mean energies to node array
932 for (int i = 0; i < netrue; ++i) {
933
934 // Get log mean of true energy in TeV
935 double logE = m_ebounds.elogmean(i).log10TeV();
936
937 // Append energy to node array
938 m_logetrue.append(logE);
939
940 } // endfor: appended log mean energies
941
942 } // endif: there were true energies in Arf
943
944 // Return
945 return;
946}
947
948
949/***********************************************************************//**
950 * @brief Returns index of additional vector column
951 *
952 * @param[in] colname Vector column name.
953 * @return Vector column index.
954 *
955 * Returns index of additional vector column. Returns -1 if the vector column
956 * has not found.
957 ***************************************************************************/
958int GArf::column_index(const std::string& colname) const
959{
960 // Initialise index
961 int index(-1);
962
963 // Search vector column name
964 for (int i = 0; i < columns(); ++i) {
965 if (m_colnames[i] == colname) {
966 index = i;
967 break;
968 }
969 }
970
971 // Return index
972 return index;
973}
#define G_APPEND
#define G_OPERATOR
Definition GArf.cpp:44
#define G_OPERATOR_PLUS
Definition GArf.cpp:42
#define G_OPERATOR_MINUS
Definition GArf.cpp:43
XSPEC Auxiliary Response File class definition.
#define G_OPERATOR2
Definition GEnergy.cpp:42
Exception handler interface definition.
Filename class interface definition.
FITS binary table class definition.
FITS table float column class interface definition.
FITS table short integer column class interface definition.
FITS table abstract base class interface definition.
#define G_AT2
Definition GFits.cpp:52
#define G_AT1
Definition GFits.cpp:51
FITS file class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
Auxiliary Response File class.
Definition GArf.hpp:54
int column_index(const std::string &colname) const
Returns index of additional vector column.
Definition GArf.cpp:958
GFitsHeader m_header
FITS header cards.
Definition GArf.hpp:127
GArf & operator=(const GArf &arf)
Assignment operator.
Definition GArf.cpp:161
void read(const GFits &fits)
Read Auxiliary Response File.
Definition GArf.cpp:617
void save(const GFilename &filename, const bool &clobber=false) const
Save Auxiliary Response File.
Definition GArf.cpp:589
int size(void) const
Return number of spectral bins.
Definition GArf.hpp:209
GArf(void)
Void constructor.
Definition GArf.cpp:66
GArf & operator*=(const double &scale)
Scale Auxiliary Response File values.
Definition GArf.cpp:257
double & operator[](const int &index)
Return content of spectral bin.
Definition GArf.hpp:151
double & at(const int &index)
Return content of spectral bin.
Definition GArf.cpp:428
GArf & operator/=(const double &scale)
Divide Auxiliary Response File values.
Definition GArf.cpp:277
const GEbounds & ebounds(void) const
Return energy boundaries.
Definition GArf.hpp:237
void set_logetrue(void)
Set true energy node array.
Definition GArf.cpp:919
void append(const std::string &name, const std::vector< double > &column)
Append additional column to spectrum.
Definition GArf.cpp:522
virtual ~GArf(void)
Destructor.
Definition GArf.cpp:139
GEbounds m_ebounds
Energy boundaries.
Definition GArf.hpp:122
GNodeArray m_logetrue
Log10 energies in TeV.
Definition GArf.hpp:123
std::string print(const GChatter &chatter=NORMAL) const
Print Auxiliary Response File.
Definition GArf.cpp:834
GArf * clone(void) const
Clone object.
Definition GArf.cpp:411
void init_members(void)
Initialise class members.
Definition GArf.cpp:869
std::vector< double > m_specresp
Spectral response.
Definition GArf.hpp:124
GArf & operator-=(const GArf &arf)
Subtract Auxiliary Response File.
Definition GArf.cpp:230
void copy_members(const GArf &pha)
Copy class members.
Definition GArf.cpp:890
void write(GFits &fits) const
Write Auxiliary Response File.
Definition GArf.cpp:740
std::vector< std::vector< double > > m_coldata
Additional column data.
Definition GArf.hpp:126
int columns(void) const
Return number of additional columns.
Definition GArf.hpp:223
void clear(void)
Clear object.
Definition GArf.cpp:395
const GFilename & filename(void) const
Return file name.
Definition GArf.hpp:254
void free_members(void)
Delete class members.
Definition GArf.cpp:909
std::vector< std::string > m_colnames
Additional column names.
Definition GArf.hpp:125
double & operator()(const int &index, const int &col)
Return content of additional columns.
Definition GArf.hpp:180
GFilename m_filename
Filename of origin.
Definition GArf.hpp:121
GArf & operator+=(const GArf &arf)
Add Auxiliary Response File.
Definition GArf.cpp:196
void load(const GFilename &filename)
Load Auxiliary Response File.
Definition GArf.cpp:552
Energy boundaries container class.
Definition GEbounds.hpp:60
const GEnergy & emax(void) const
Return maximum energy of all intervals.
Definition GEbounds.hpp:199
void append(const GEnergy &emin, const GEnergy &emax)
Append energy interval.
Definition GEbounds.cpp:301
int size(void) const
Return number of energy boundaries.
Definition GEbounds.hpp:163
void clear(void)
Clear energy boundaries.
Definition GEbounds.cpp:268
GEnergy elogmean(const int &index) const
Returns logarithmic mean energy for a given energy interval.
const GEnergy & emin(void) const
Return minimum energy of all intervals.
Definition GEbounds.hpp:187
Class that handles energies in a unit independent way.
Definition GEnergy.hpp:48
double keV(void) const
Return energy in keV.
Definition GEnergy.cpp:306
double log10TeV(void) const
Return log10 of energy in TeV.
Definition GEnergy.cpp:457
std::string print(const GChatter &chatter=NORMAL) const
Print energy.
Definition GEnergy.cpp:748
Filename class.
Definition GFilename.hpp:62
std::string url(void) const
Return Uniform Resource Locator (URL)
void clear(void)
Clear file name.
FITS binary table class.
const GFitsHeader & header(void) const
Return extension header.
Definition GFitsHDU.hpp:205
const std::string & extname(void) const
Return extension name.
Definition GFitsHDU.hpp:162
GFitsHeaderCard & card(const int &cardno)
Return header card.
Definition GFitsHDU.hpp:259
void clear(void)
Clear header.
int size(void) const
Return number of cards in header.
Abstract interface for FITS table column.
virtual double real(const int &row, const int &inx=0) const =0
void unit(const std::string &unit)
Set column unit.
void nrows(const int &nrows)
Set number of rows in column.
FITS table float column.
Abstract interface for FITS table.
bool contains(const std::string &colname) const
Checks the presence of a column in table.
GFitsTableCol * append(const GFitsTableCol &column)
Append column to the table.
const int & ncols(void) const
Return number of columns in table.
FITS file class.
Definition GFits.hpp:63
void saveto(const GFilename &filename, const bool &clobber=false)
Saves to specified FITS file.
Definition GFits.cpp:1293
bool contains(const int &extno) const
Check if HDU exists in FITS file.
Definition GFits.hpp:282
GFitsHDU * append(const GFitsHDU &hdu)
Append HDU to FITS file.
Definition GFits.cpp:678
void close(void)
Close FITS file.
Definition GFits.cpp:1342
void remove(const int &extno)
Remove HDU from FITS file.
Definition GFits.cpp:862
GFitsTable * table(const int &extno)
Get pointer to table HDU.
Definition GFits.cpp:482
void set_value(const double &value) const
Set indices and weighting factors for interpolation.
const int & inx_right(void) const
Returns right node index.
const int & inx_left(void) const
Returns left node index.
void reserve(const int &num)
Reserves space for nodes in node array.
const double & wgt_right(void) const
Returns right node weight.
const double & wgt_left(void) const
Returns left node weight.
void clear(void)
Clear node array.
void append(const double &node)
Append one node to array.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
std::string tolower(const std::string &s)
Convert string to lower case.
Definition GTools.cpp:955
std::string strip_whitespace(const std::string &arg)
Strip leading and trailing whitespace from string.
Definition GTools.cpp:80
const std::string extname_arf
Definition GArf.hpp:45