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 2 # ==========================================================================
3 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 7 # This program is free software: you can redistribute it and/or modify
8 8 # it under the terms of the GNU General Public License as published by
... ... @@ -63,14 +63,19 @@ if __name__ == "__main__":
63 63 index = nrows - 1 - row
64 64  
65 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 71 # plot the butterfly and spectral line
69 72 plt.figure()
  73 + plt.ylim([1e-26,1e-14])
70 74 plt.loglog()
71 75 plt.grid()
72 76 plt.plot(line_x,line_y,color='black',ls='-')
73 77 plt.fill(butterfly_x,butterfly_y,color='green',alpha=0.5)
  78 +
74 79 plt.xlabel("Energy [MeV]")
75 80 plt.ylabel(r"dN/dE [MeV$^{-1}$ s$^{-1}$ cm$^{-2}$]")
76 81 plt.show()
... ...
src/ctbutterfly/ctbutterfly.cpp
... ... @@ -36,6 +36,7 @@
36 36 /* __ Method name definitions ____________________________________________ */
37 37 #define G_GET_PARAMETERS "ctbutterfly::get_parameters()"
38 38 #define G_SAVE "ctbutterfly::save()"
  39 +#define G_GET_MODEL_PARAMETER "ctbutterfly::get_model_parameter()"
39 40  
40 41 /* __ Debug definitions __________________________________________________ */
41 42  
... ... @@ -291,47 +292,38 @@ void ctbutterfly::run(void)
291 292 log.header2(msg);
292 293 }
293 294  
294   - // Initialise model flux value
  295 + // Initialise flux value
295 296 double model_flux = 0.0;
296 297  
297 298 // Loop over models
298 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 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 328 } // endfor: Looped over models
337 329  
... ... @@ -341,6 +333,9 @@ void ctbutterfly::run(void)
341 333 // Get the error from the scalar product
342 334 double error = std::sqrt(grad * vector);
343 335  
  336 + // Multiply in scale of spectral parameter
  337 + error *= m_par_scale;
  338 +
344 339 // Store flux, value and energy for saving
345 340 m_fluxes.push_back(model_flux);
346 341 m_energies.push_back(energy.MeV());
... ... @@ -425,6 +420,8 @@ void ctbutterfly::init_members(void)
425 420 m_apply_edisp = false;
426 421  
427 422 // Initialise protected members
  423 + m_skymodel = NULL;
  424 + m_par_scale = 0.0;
428 425 m_obs.clear();
429 426 m_covariance.clear();
430 427 m_energies.clear();
... ... @@ -456,6 +453,9 @@ void ctbutterfly::copy_members(const ctbutterfly&amp; app)
456 453 m_fluxes = app.m_fluxes;
457 454 m_errors = app.m_errors;
458 455  
  456 + // Extract model parameter
  457 + get_model_parameter();
  458 +
459 459 // Return
460 460 return;
461 461 }
... ... @@ -517,9 +517,12 @@ void ctbutterfly::get_parameters(void)
517 517 std::string msg = "Source \""+m_srcname+"\" not found in model "
518 518 "container. Please add a source with that name "
519 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 526 // Create energy boundaries from user parameters
524 527 m_ebounds = create_ebounds();
525 528  
... ... @@ -545,3 +548,65 @@ void ctbutterfly::get_parameters(void)
545 548 // Return
546 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 78 void copy_members(const ctbutterfly& app);
79 79 void free_members(void);
80 80 void get_parameters(void);
  81 + void get_model_parameter(void);
81 82  
82 83 // User parameters
83 84 std::string m_srcname; //!< Name of source to compute butterfly
... ... @@ -88,6 +89,8 @@ protected:
88 89 // Protected members
89 90 GObservations m_obs; //!< Observation container
90 91 GMatrixSparse m_covariance; //!< Covariance matrix
  92 + GModelSky* m_skymodel; //!< Pointer to sky model
  93 + double m_par_scale; //!< Scale of normalising parameter
91 94 std::vector<double> m_energies; //!< Energy values for storage
92 95 std::vector<double> m_fluxes; //!< Flux values per energy bin
93 96 std::vector<double> m_errors; //!< Flux errors per energy bin
... ...