Commit c5b2ebf7de4821047d8435bbac116da58cc16022
Merge branch '1498-ctbutterfly-should-consider-all-correlations' into 1498-fix-ctbutterfly
Conflicts: examples/show_butterfly.py
Showing
3 changed files
with
105 additions
and
32 deletions
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& app) | @@ -456,6 +453,9 @@ void ctbutterfly::copy_members(const ctbutterfly& 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 |