Commit 16f5fca07411923b12ae9a0d7e3454b9fd78d015
1 parent
96602a11
ctbutterfly now takes into account all correlations with other models
Showing
3 changed files
with
103 additions
and
30 deletions
examples/show_butterfly.py
| ... | ... | @@ -63,14 +63,20 @@ 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)) | |
| 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 | + | |
| 67 | 71 | |
| 68 | 72 | # plot the butterfly and spectral line |
| 69 | 73 | plt.figure() |
| 74 | + plt.ylim([1e-26,1e-14]) | |
| 70 | 75 | plt.loglog() |
| 71 | 76 | plt.grid() |
| 72 | 77 | plt.plot(line_x,line_y,color='black',ls='-') |
| 73 | 78 | plt.fill(butterfly_x,butterfly_y,color='green',alpha=0.5) |
| 79 | + | |
| 74 | 80 | plt.xlabel("Energy [MeV]") |
| 75 | 81 | plt.ylabel(r"dN/dE [MeV$^{-1}$ s$^{-1}$ cm$^{-2}$]") |
| 76 | 82 | plt.show() |
| 77 | 83 | \ No newline at end of file | ... | ... |
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 | |
| ... | ... | @@ -279,47 +280,37 @@ void ctbutterfly::run(void) |
| 279 | 280 | log.header2(msg); |
| 280 | 281 | } |
| 281 | 282 | |
| 282 | - // Initialise model flux value | |
| 283 | + // Initialise flux value | |
| 283 | 284 | double model_flux = 0.0; |
| 284 | 285 | |
| 285 | 286 | // Loop over models |
| 286 | 287 | for (int j = 0; j < models.size(); ++j) { |
| 287 | 288 | |
| 288 | - // Check wether model is a skymodel | |
| 289 | - GModelSky* skymodel = dynamic_cast<GModelSky*>(models[j]); | |
| 289 | + if (models[j]->name() == m_srcname) { | |
| 290 | 290 | |
| 291 | - // Yes ... | |
| 292 | - if (skymodel != NULL) { | |
| 293 | - | |
| 294 | - // Skip spatial models | |
| 295 | - num_gradient += skymodel->spatial()->size(); | |
| 296 | - | |
| 297 | - // Get pointer to spectral model | |
| 291 | + // If source name is found retrieve the nominal flux | |
| 292 | + // Note that we have to compute the gradients here repetively to update the | |
| 293 | + // gradients in the vector | |
| 294 | + // No check for valid pointers necessary here as this was covered by get_model_parameter() | |
| 295 | + GModelSky* skymodel = dynamic_cast<GModelSky*>(models[j]); | |
| 298 | 296 | GModelSpectral* spectral = skymodel->spectral(); |
| 297 | + model_flux = spectral->eval_gradients(energy, time); | |
| 299 | 298 | |
| 300 | - // Set flux value of source of interest | |
| 301 | - if (skymodel->name() == m_srcname) { | |
| 302 | - model_flux = spectral->eval_gradients(energy, time); | |
| 303 | - } // endif: model was source of interest | |
| 304 | - | |
| 305 | - // Loop over model parameters, get gradients | |
| 306 | - // and assign them to the vector | |
| 307 | - for (int k = 0; k < spectral->size(); ++k) { | |
| 308 | - grad[num_gradient] = (*spectral)[k].gradient(); | |
| 309 | - num_gradient++; | |
| 310 | - } // endfor: looped over spectral parameters | |
| 299 | + } | |
| 311 | 300 | |
| 312 | - // Skip temporal models | |
| 313 | - num_gradient += skymodel->temporal()->size(); | |
| 301 | + // Loop over model parameters | |
| 302 | + for(int i = 0; i < models[j]->size(); ++i) { | |
| 314 | 303 | |
| 315 | - } // endif: model was sky model | |
| 304 | + // Get model parameter | |
| 305 | + GModelPar parameter = models[j]->at(i); | |
| 316 | 306 | |
| 317 | - else { | |
| 307 | + // Set gradient value to the vector | |
| 308 | + grad[num_gradient] = parameter.gradient(); | |
| 318 | 309 | |
| 319 | - // Skip other models (e.g. GModelData instances) | |
| 320 | - num_gradient += models[j]->size(); | |
| 310 | + // increment vector index | |
| 311 | + num_gradient++; | |
| 321 | 312 | |
| 322 | - } // endelse: Model was not GModelSky | |
| 313 | + } // endfor: Looped over model parameters | |
| 323 | 314 | |
| 324 | 315 | } // endfor: Looped over models |
| 325 | 316 | |
| ... | ... | @@ -329,6 +320,9 @@ void ctbutterfly::run(void) |
| 329 | 320 | // Get the error from the scalar product |
| 330 | 321 | double error = std::sqrt(grad * vector); |
| 331 | 322 | |
| 323 | + // Multiply in scale of spectral parameter | |
| 324 | + error *= m_par_scale; | |
| 325 | + | |
| 332 | 326 | // Store flux, value and energy for saving |
| 333 | 327 | m_fluxes.push_back(model_flux); |
| 334 | 328 | m_energies.push_back(energy.MeV()); |
| ... | ... | @@ -404,6 +398,8 @@ void ctbutterfly::init_members(void) |
| 404 | 398 | m_ebounds.clear(); |
| 405 | 399 | |
| 406 | 400 | // Initialise protected members |
| 401 | + m_skymodel = NULL; | |
| 402 | + m_par_scale = 0.0; | |
| 407 | 403 | m_obs.clear(); |
| 408 | 404 | m_covariance.clear(); |
| 409 | 405 | m_energies.clear(); |
| ... | ... | @@ -434,6 +430,9 @@ void ctbutterfly::copy_members(const ctbutterfly& app) |
| 434 | 430 | m_fluxes = app.m_fluxes; |
| 435 | 431 | m_errors = app.m_errors; |
| 436 | 432 | |
| 433 | + // Extract model parameter | |
| 434 | + get_model_parameter(); | |
| 435 | + | |
| 437 | 436 | // Return |
| 438 | 437 | return; |
| 439 | 438 | } |
| ... | ... | @@ -495,9 +494,12 @@ void ctbutterfly::get_parameters(void) |
| 495 | 494 | std::string msg = "Source \""+m_srcname+"\" not found in model " |
| 496 | 495 | "container. Please add a source with that name " |
| 497 | 496 | "or check for possible typos."; |
| 498 | - throw GException::invalid_value(G_GET_PARAMETERS, msg); | |
| 497 | + throw GException::invalid_value(G_GET_PARAMETERS, msg); | |
| 499 | 498 | } |
| 500 | 499 | |
| 500 | + // Get relevant model and parameter for model computation | |
| 501 | + get_model_parameter(); | |
| 502 | + | |
| 501 | 503 | // Create energy boundaries from user parameters |
| 502 | 504 | m_ebounds = create_ebounds(); |
| 503 | 505 | |
| ... | ... | @@ -520,3 +522,65 @@ void ctbutterfly::get_parameters(void) |
| 520 | 522 | // Return |
| 521 | 523 | return; |
| 522 | 524 | } |
| 525 | + | |
| 526 | + | |
| 527 | +/***********************************************************************//** | |
| 528 | + * @brief Get application parameters | |
| 529 | + * | |
| 530 | + * @exception GException::invalid_value | |
| 531 | + * Did not find a valid model parameter | |
| 532 | + * | |
| 533 | + * Extracts a pointer to the sky model (m_skymodel) and a pointer to the | |
| 534 | + * relevant model parameter (m_model_par) from the model container. | |
| 535 | + ***************************************************************************/ | |
| 536 | +void ctbutterfly::get_model_parameter(void) | |
| 537 | +{ | |
| 538 | + // Continue only if source model exists | |
| 539 | + if (m_obs.models().contains(m_srcname)) { | |
| 540 | + | |
| 541 | + // Get relevant model and parameter for upper limit computation. | |
| 542 | + GModels& models = const_cast<GModels&>(m_obs.models()); | |
| 543 | + m_skymodel = dynamic_cast<GModelSky*>(models[m_srcname]); | |
| 544 | + if (m_skymodel == NULL) { | |
| 545 | + std::string msg = "Source \""+m_srcname+"\" is not a sky model. " | |
| 546 | + "Please specify the name of a sky model for " | |
| 547 | + "butterfly computation."; | |
| 548 | + throw GException::invalid_value(G_GET_MODEL_PARAMETER, msg); | |
| 549 | + } | |
| 550 | + | |
| 551 | + GModelPar* modelpar; | |
| 552 | + | |
| 553 | + if (m_skymodel->spectral()->type() == "NodeFunction") { | |
| 554 | + std::string msg = "\"NodeFunction\" cannot be used as spectral " | |
| 555 | + "model for an butterfly computation. " | |
| 556 | + "Please specify another spectral model."; | |
| 557 | + throw GException::invalid_value(G_GET_MODEL_PARAMETER, msg); | |
| 558 | + } | |
| 559 | + if (m_skymodel->spectral()->has_par("Normalization")) { | |
| 560 | + modelpar = &(m_skymodel->spectral()->operator[]("Normalization")); | |
| 561 | + } | |
| 562 | + else if (m_skymodel->spectral()->has_par("Prefactor")) { | |
| 563 | + modelpar = &(m_skymodel->spectral()->operator[]("Prefactor")); | |
| 564 | + } | |
| 565 | + else if (m_skymodel->spectral()->has_par("Integral")) { | |
| 566 | + modelpar = &(m_skymodel->spectral()->operator[]("Integral")); | |
| 567 | + } | |
| 568 | + else if (m_skymodel->spectral()->has_par("Value")) { | |
| 569 | + modelpar = &(m_skymodel->spectral()->operator[]("Value")); | |
| 570 | + } | |
| 571 | + else { | |
| 572 | + std::string msg = "Require spectral parameter \"Normalization\", " | |
| 573 | + "\"Prefactor\", \"Integral\" or \"Value\" for " | |
| 574 | + "butterfly computation. The specified source " | |
| 575 | + "\""+m_srcname+"\" does not have such a parameter."; | |
| 576 | + throw GException::invalid_value(G_GET_MODEL_PARAMETER, msg); | |
| 577 | + } | |
| 578 | + | |
| 579 | + // Set scale value from parameter | |
| 580 | + m_par_scale = modelpar->scale(); | |
| 581 | + | |
| 582 | + } // endif: source model existed | |
| 583 | + | |
| 584 | + // Return | |
| 585 | + return; | |
| 586 | +} | ... | ... |
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 |
| ... | ... | @@ -87,6 +88,8 @@ protected: |
| 87 | 88 | // Protected members |
| 88 | 89 | GObservations m_obs; //!< Observation container |
| 89 | 90 | GMatrixSparse m_covariance; //!< Covariance matrix |
| 91 | + GModelSky* m_skymodel; //!< Pointer to sky model | |
| 92 | + double m_par_scale; //!< Scale of normalising parameter | |
| 90 | 93 | std::vector<double> m_energies; //!< Energy values for storage |
| 91 | 94 | std::vector<double> m_fluxes; //!< Flux values per energy bin |
| 92 | 95 | std::vector<double> m_errors; //!< Flux errors per energy bin | ... | ... |