Commit c5b2ebf7de4821047d8435bbac116da58cc16022

Authored by Jürgen Knödlseder
2 parents 42c52ade 1cf7b40b

Merge branch '1498-ctbutterfly-should-consider-all-correlations' into 1498-fix-ctbutterfly

Conflicts:
	examples/show_butterfly.py
examples/show_butterfly.py
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 # ========================================================================== 2 # ==========================================================================
3 # This script shows how to plot a butterfly created with ctbutterfly 3 # This script shows how to plot a butterfly created with ctbutterfly
4 # 4 #
5 -# Copyright (C) 2014 Michael Mayer 5 +# Copyright (C) 2014-2015 Michael Mayer
6 # 6 #
7 # This program is free software: you can redistribute it and/or modify 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 8 # it under the terms of the GNU General Public License as published by
@@ -63,14 +63,19 @@ if __name__ == "__main__": @@ -63,14 +63,19 @@ if __name__ == "__main__":
63 index = nrows - 1 - row 63 index = nrows - 1 - row
64 64
65 butterfly_x.append(csv.real(index,0)) 65 butterfly_x.append(csv.real(index,0))
66 - butterfly_y.append(csv.real(index,1)-csv.real(index,2))  
67 - 66 + low_error = csv.real(index,1)-csv.real(index,2)
  67 + if low_error < 1e-26:
  68 + low_error = 1e-26
  69 + butterfly_y.append(low_error)
  70 +
68 # plot the butterfly and spectral line 71 # plot the butterfly and spectral line
69 plt.figure() 72 plt.figure()
  73 + plt.ylim([1e-26,1e-14])
70 plt.loglog() 74 plt.loglog()
71 plt.grid() 75 plt.grid()
72 plt.plot(line_x,line_y,color='black',ls='-') 76 plt.plot(line_x,line_y,color='black',ls='-')
73 plt.fill(butterfly_x,butterfly_y,color='green',alpha=0.5) 77 plt.fill(butterfly_x,butterfly_y,color='green',alpha=0.5)
  78 +
74 plt.xlabel("Energy [MeV]") 79 plt.xlabel("Energy [MeV]")
75 plt.ylabel(r"dN/dE [MeV$^{-1}$ s$^{-1}$ cm$^{-2}$]") 80 plt.ylabel(r"dN/dE [MeV$^{-1}$ s$^{-1}$ cm$^{-2}$]")
76 plt.show() 81 plt.show()
src/ctbutterfly/ctbutterfly.cpp
@@ -36,6 +36,7 @@ @@ -36,6 +36,7 @@
36 /* __ Method name definitions ____________________________________________ */ 36 /* __ Method name definitions ____________________________________________ */
37 #define G_GET_PARAMETERS "ctbutterfly::get_parameters()" 37 #define G_GET_PARAMETERS "ctbutterfly::get_parameters()"
38 #define G_SAVE "ctbutterfly::save()" 38 #define G_SAVE "ctbutterfly::save()"
  39 +#define G_GET_MODEL_PARAMETER "ctbutterfly::get_model_parameter()"
39 40
40 /* __ Debug definitions __________________________________________________ */ 41 /* __ Debug definitions __________________________________________________ */
41 42
@@ -291,47 +292,38 @@ void ctbutterfly::run(void) @@ -291,47 +292,38 @@ void ctbutterfly::run(void)
291 log.header2(msg); 292 log.header2(msg);
292 } 293 }
293 294
294 - // Initialise model flux value 295 + // Initialise flux value
295 double model_flux = 0.0; 296 double model_flux = 0.0;
296 297
297 // Loop over models 298 // Loop over models
298 for (int j = 0; j < models.size(); ++j) { 299 for (int j = 0; j < models.size(); ++j) {
299 300
300 - // Check wether model is a skymodel  
301 - GModelSky* skymodel = dynamic_cast<GModelSky*>(models[j]); 301 + // If source name is found, retrieve the nominal flux
  302 + if (models[j]->name() == m_srcname) {
302 303
303 - // Yes ...  
304 - if (skymodel != NULL) {  
305 -  
306 - // Skip spatial models  
307 - num_gradient += skymodel->spatial()->size();  
308 -  
309 - // Get pointer to spectral model 304 + // Note that we have to compute the gradients here
  305 + // repetively to update the gradients in the vector
  306 + // No check for valid pointers necessary here as this
  307 + // was covered by get_model_parameter()
  308 + GModelSky* skymodel = dynamic_cast<GModelSky*>(models[j]);
310 GModelSpectral* spectral = skymodel->spectral(); 309 GModelSpectral* spectral = skymodel->spectral();
  310 + model_flux = spectral->eval_gradients(energy, time);
311 311
312 - // Set flux value of source of interest  
313 - if (skymodel->name() == m_srcname) {  
314 - model_flux = spectral->eval_gradients(energy, time);  
315 - } // endif: model was source of interest  
316 -  
317 - // Loop over model parameters, get gradients  
318 - // and assign them to the vector  
319 - for (int k = 0; k < spectral->size(); ++k) {  
320 - grad[num_gradient] = (*spectral)[k].gradient();  
321 - num_gradient++;  
322 - } // endfor: looped over spectral parameters 312 + }
323 313
324 - // Skip temporal models  
325 - num_gradient += skymodel->temporal()->size(); 314 + // Loop over model parameters
  315 + for (int i = 0; i < models[j]->size(); ++i) {
326 316
327 - } // endif: model was sky model 317 + // Get model parameter
  318 + GModelPar parameter = models[j]->at(i);
328 319
329 - else { 320 + // Set gradient value to the vector
  321 + grad[num_gradient] = parameter.gradient();
330 322
331 - // Skip other models (e.g. GModelData instances)  
332 - num_gradient += models[j]->size(); 323 + // increment vector index
  324 + num_gradient++;
333 325
334 - } // endelse: Model was not GModelSky 326 + } // endfor: Looped over model parameters
335 327
336 } // endfor: Looped over models 328 } // endfor: Looped over models
337 329
@@ -341,6 +333,9 @@ void ctbutterfly::run(void) @@ -341,6 +333,9 @@ void ctbutterfly::run(void)
341 // Get the error from the scalar product 333 // Get the error from the scalar product
342 double error = std::sqrt(grad * vector); 334 double error = std::sqrt(grad * vector);
343 335
  336 + // Multiply in scale of spectral parameter
  337 + error *= m_par_scale;
  338 +
344 // Store flux, value and energy for saving 339 // Store flux, value and energy for saving
345 m_fluxes.push_back(model_flux); 340 m_fluxes.push_back(model_flux);
346 m_energies.push_back(energy.MeV()); 341 m_energies.push_back(energy.MeV());
@@ -425,6 +420,8 @@ void ctbutterfly::init_members(void) @@ -425,6 +420,8 @@ void ctbutterfly::init_members(void)
425 m_apply_edisp = false; 420 m_apply_edisp = false;
426 421
427 // Initialise protected members 422 // Initialise protected members
  423 + m_skymodel = NULL;
  424 + m_par_scale = 0.0;
428 m_obs.clear(); 425 m_obs.clear();
429 m_covariance.clear(); 426 m_covariance.clear();
430 m_energies.clear(); 427 m_energies.clear();
@@ -456,6 +453,9 @@ void ctbutterfly::copy_members(const ctbutterfly&amp; app) @@ -456,6 +453,9 @@ void ctbutterfly::copy_members(const ctbutterfly&amp; app)
456 m_fluxes = app.m_fluxes; 453 m_fluxes = app.m_fluxes;
457 m_errors = app.m_errors; 454 m_errors = app.m_errors;
458 455
  456 + // Extract model parameter
  457 + get_model_parameter();
  458 +
459 // Return 459 // Return
460 return; 460 return;
461 } 461 }
@@ -517,9 +517,12 @@ void ctbutterfly::get_parameters(void) @@ -517,9 +517,12 @@ void ctbutterfly::get_parameters(void)
517 std::string msg = "Source \""+m_srcname+"\" not found in model " 517 std::string msg = "Source \""+m_srcname+"\" not found in model "
518 "container. Please add a source with that name " 518 "container. Please add a source with that name "
519 "or check for possible typos."; 519 "or check for possible typos.";
520 - throw GException::invalid_value(G_GET_PARAMETERS, msg); 520 + throw GException::invalid_value(G_GET_PARAMETERS, msg);
521 } 521 }
522 522
  523 + // Get relevant model and parameter for model computation
  524 + get_model_parameter();
  525 +
523 // Create energy boundaries from user parameters 526 // Create energy boundaries from user parameters
524 m_ebounds = create_ebounds(); 527 m_ebounds = create_ebounds();
525 528
@@ -545,3 +548,65 @@ void ctbutterfly::get_parameters(void) @@ -545,3 +548,65 @@ void ctbutterfly::get_parameters(void)
545 // Return 548 // Return
546 return; 549 return;
547 } 550 }
  551 +
  552 +
  553 +/***********************************************************************//**
  554 + * @brief Get application parameters
  555 + *
  556 + * @exception GException::invalid_value
  557 + * Did not find a valid model parameter
  558 + *
  559 + * Extracts a pointer to the sky model (m_skymodel) and a pointer to the
  560 + * relevant model parameter (m_model_par) from the model container.
  561 + ***************************************************************************/
  562 +void ctbutterfly::get_model_parameter(void)
  563 +{
  564 + // Continue only if source model exists
  565 + if (m_obs.models().contains(m_srcname)) {
  566 +
  567 + // Get relevant model and parameter for upper limit computation.
  568 + GModels& models = const_cast<GModels&>(m_obs.models());
  569 + m_skymodel = dynamic_cast<GModelSky*>(models[m_srcname]);
  570 + if (m_skymodel == NULL) {
  571 + std::string msg = "Source \""+m_srcname+"\" is not a sky model. "
  572 + "Please specify the name of a sky model for "
  573 + "butterfly computation.";
  574 + throw GException::invalid_value(G_GET_MODEL_PARAMETER, msg);
  575 + }
  576 +
  577 + GModelPar* modelpar;
  578 +
  579 + if (m_skymodel->spectral()->type() == "NodeFunction") {
  580 + std::string msg = "\"NodeFunction\" cannot be used as spectral "
  581 + "model for an butterfly computation. "
  582 + "Please specify another spectral model.";
  583 + throw GException::invalid_value(G_GET_MODEL_PARAMETER, msg);
  584 + }
  585 + if (m_skymodel->spectral()->has_par("Normalization")) {
  586 + modelpar = &(m_skymodel->spectral()->operator[]("Normalization"));
  587 + }
  588 + else if (m_skymodel->spectral()->has_par("Prefactor")) {
  589 + modelpar = &(m_skymodel->spectral()->operator[]("Prefactor"));
  590 + }
  591 + else if (m_skymodel->spectral()->has_par("Integral")) {
  592 + modelpar = &(m_skymodel->spectral()->operator[]("Integral"));
  593 + }
  594 + else if (m_skymodel->spectral()->has_par("Value")) {
  595 + modelpar = &(m_skymodel->spectral()->operator[]("Value"));
  596 + }
  597 + else {
  598 + std::string msg = "Require spectral parameter \"Normalization\", "
  599 + "\"Prefactor\", \"Integral\" or \"Value\" for "
  600 + "butterfly computation. The specified source "
  601 + "\""+m_srcname+"\" does not have such a parameter.";
  602 + throw GException::invalid_value(G_GET_MODEL_PARAMETER, msg);
  603 + }
  604 +
  605 + // Set scale value from parameter
  606 + m_par_scale = modelpar->scale();
  607 +
  608 + } // endif: source model existed
  609 +
  610 + // Return
  611 + return;
  612 +}
src/ctbutterfly/ctbutterfly.hpp
@@ -78,6 +78,7 @@ protected: @@ -78,6 +78,7 @@ protected:
78 void copy_members(const ctbutterfly& app); 78 void copy_members(const ctbutterfly& app);
79 void free_members(void); 79 void free_members(void);
80 void get_parameters(void); 80 void get_parameters(void);
  81 + void get_model_parameter(void);
81 82
82 // User parameters 83 // User parameters
83 std::string m_srcname; //!< Name of source to compute butterfly 84 std::string m_srcname; //!< Name of source to compute butterfly
@@ -88,6 +89,8 @@ protected: @@ -88,6 +89,8 @@ protected:
88 // Protected members 89 // Protected members
89 GObservations m_obs; //!< Observation container 90 GObservations m_obs; //!< Observation container
90 GMatrixSparse m_covariance; //!< Covariance matrix 91 GMatrixSparse m_covariance; //!< Covariance matrix
  92 + GModelSky* m_skymodel; //!< Pointer to sky model
  93 + double m_par_scale; //!< Scale of normalising parameter
91 std::vector<double> m_energies; //!< Energy values for storage 94 std::vector<double> m_energies; //!< Energy values for storage
92 std::vector<double> m_fluxes; //!< Flux values per energy bin 95 std::vector<double> m_fluxes; //!< Flux values per energy bin
93 std::vector<double> m_errors; //!< Flux errors per energy bin 96 std::vector<double> m_errors; //!< Flux errors per energy bin