Commit 2d6c355346543c191dcc6700ea3bfa01e56a1fe1

Authored by Jürgen Knödlseder
2 parents ad9fa30c 78192ad8

Merge branch '1863_CovMat' into integration

# Conflicts:
#	ChangeLog
#	NEWS
ChangeLog
1 -2016-10-16 1 +2016-10-17
2 2
3 * Version 1.2.0 released 3 * Version 1.2.0 released
4 ========================= 4 =========================
5 5
  6 + Add GObservations::save_covmat() method (#1863)
6 Add GFft and GFftWavetable classes (#1731) 7 Add GFft and GFftWavetable classes (#1731)
7 Add GNdarray class (#1768) 8 Add GNdarray class (#1768)
8 Increase precision of gammalib::str() floating point functions 9 Increase precision of gammalib::str() floating point functions
1 New Features and Important Changes in GammaLib 1.2.0 1 New Features and Important Changes in GammaLib 1.2.0
2 2
3 -16 October 2016 3 +17 October 2016
4 4
5 5
6 1. Introduction 6 1. Introduction
@@ -54,6 +54,7 @@ The following methods have been added: @@ -54,6 +54,7 @@ The following methods have been added:
54 - GTime::now() 54 - GTime::now()
55 - GFits::publish() 55 - GFits::publish()
56 - gammalib::rstrip_chars() 56 - gammalib::rstrip_chars()
  57 +- GObservations::save_covmat()
57 58
58 The following methods have been removed: 59 The following methods have been removed:
59 - <all classes>::eval_gradients() 60 - <all classes>::eval_gradients()
@@ -179,6 +180,9 @@ times that depend on the geographic longitude. Finally, a now() method has @@ -179,6 +180,9 @@ times that depend on the geographic longitude. Finally, a now() method has
179 been added to the GTime class that sets the time to the current time (see 180 been added to the GTime class that sets the time to the current time (see
180 #1856). 181 #1856).
181 182
  183 +The GObservations::save_covmat() method computes and saves the covariance
  184 +matrix into a FITS file (#1863).
  185 +
182 186
183 11. Optimization module 187 11. Optimization module
184 ----------------------- 188 -----------------------
include/GObservations.hpp
@@ -129,6 +129,7 @@ public: @@ -129,6 +129,7 @@ public:
129 void optimize(GOptimizer& opt); 129 void optimize(GOptimizer& opt);
130 void errors(GOptimizer& opt); 130 void errors(GOptimizer& opt);
131 void errors_hessian(void); 131 void errors_hessian(void);
  132 + void save_covmat(const GFilename& filename) const;
132 void eval(void); 133 void eval(void);
133 double logL(void) const; 134 double logL(void) const;
134 int nobserved(void) const; 135 int nobserved(void) const;
src/obs/GObservations.cpp
@@ -35,6 +35,9 @@ @@ -35,6 +35,9 @@
35 #include "GObservationRegistry.hpp" 35 #include "GObservationRegistry.hpp"
36 #include "GMatrixSparse.hpp" 36 #include "GMatrixSparse.hpp"
37 #include "GOptimizer.hpp" 37 #include "GOptimizer.hpp"
  38 +#include "GFitsBinTable.hpp"
  39 +#include "GFitsTableStringCol.hpp"
  40 +#include "GFitsTableDoubleCol.hpp"
38 41
39 /* __ Method name definitions ____________________________________________ */ 42 /* __ Method name definitions ____________________________________________ */
40 #define G_AT "GObservations::at(int&)" 43 #define G_AT "GObservations::at(int&)"
@@ -837,6 +840,77 @@ void GObservations::errors_hessian(void) @@ -837,6 +840,77 @@ void GObservations::errors_hessian(void)
837 840
838 841
839 /***********************************************************************//** 842 /***********************************************************************//**
  843 + * @brief Save covariance matrix into FITS file
  844 + *
  845 + * @param[in] filename FITS filename.
  846 + *
  847 + * Saves the covariance matrix into FITS file. The covariance matrix is
  848 + * calculated as the inverse of the curvature matrix.
  849 + ***************************************************************************/
  850 +void GObservations::save_covmat(const GFilename& filename) const
  851 +{
  852 + // Calculate covariance matrix (circumvent const correctness)
  853 + GMatrixSparse covmat =
  854 + const_cast<GObservations*>(this)->m_fct.curvature()->invert();
  855 +
  856 + // Create covariance matrix entry names
  857 + std::vector<std::string> covmat_entries;
  858 + for (int i = 0 ; i < m_models.size(); ++i) {
  859 + for (int j = 0; j < m_models[i]->size(); ++j) {
  860 + covmat_entries.push_back(m_models[i]->at(j).name() + "(" +
  861 + m_models[i]->name() + ")");
  862 + }
  863 + }
  864 +
  865 + // Create binary table and columns
  866 + int size = covmat_entries.size();
  867 + GFitsBinTable covmat_table;
  868 + GFitsTableStringCol par("Parameters", 1, 50, size);
  869 + GFitsTableDoubleCol cov("Covariance", 1, size*size);
  870 +
  871 + // Fill tables. We need to take the scale factors into account since the
  872 + // covariance matrix is for the unscaled parameters
  873 + int counter = 0;
  874 + for (int i = 0; i < size; ++i) {
  875 + par(0, i) = covmat_entries[i];
  876 + for (int j = 0; j < size; ++j) {
  877 + cov(0, counter) = covmat(i,j) * m_models.pars()[i]->scale()
  878 + * m_models.pars()[j]->scale();
  879 + ++counter;
  880 + }
  881 + }
  882 +
  883 + // Set dimension for covariance matrix column
  884 + std::vector<int> dim;
  885 + dim.push_back(size);
  886 + dim.push_back(size);
  887 + cov.dim(dim);
  888 +
  889 + // Append columns to table
  890 + covmat_table.append(par);
  891 + covmat_table.append(cov);
  892 +
  893 + // Set extension name
  894 + covmat_table.extname("Covariance Matrix");
  895 +
  896 + // Allocate FITS object
  897 + GFits fits;
  898 +
  899 + // Append covariance matrix table to FITS object
  900 + fits.append(covmat_table);
  901 +
  902 + // Save FITS file to disk
  903 + fits.saveto(filename, true);
  904 +
  905 + // Close FITS object
  906 + fits.close();
  907 +
  908 + // Return
  909 + return;
  910 +}
  911 +
  912 +
  913 +/***********************************************************************//**
840 * @brief Evaluate function 914 * @brief Evaluate function
841 * 915 *
842 * Evaluates the likelihood funtion at the actual set of parameters. 916 * Evaluates the likelihood funtion at the actual set of parameters.