Commit ebb6e1f672db870b1ef3760ae1359db6cb35d88a
1 parent
86294b84
Improve finding of parameter indices, add confidence scaling
Showing
1 changed file
with
82 additions
and
71 deletions
src/ctbutterfly/ctbutterfly.cpp
| @@ -71,7 +71,7 @@ ctbutterfly::ctbutterfly(void) : ctlikelihood(CTBUTTERFLY_NAME, CTBUTTERFLY_VERS | @@ -71,7 +71,7 @@ ctbutterfly::ctbutterfly(void) : ctlikelihood(CTBUTTERFLY_NAME, CTBUTTERFLY_VERS | ||
| 71 | * observations container. | 71 | * observations container. |
| 72 | ***************************************************************************/ | 72 | ***************************************************************************/ |
| 73 | ctbutterfly::ctbutterfly(const GObservations& obs) : | 73 | ctbutterfly::ctbutterfly(const GObservations& obs) : |
| 74 | - ctlikelihood(CTBUTTERFLY_NAME, CTBUTTERFLY_VERSION, obs) | 74 | + ctlikelihood(CTBUTTERFLY_NAME, CTBUTTERFLY_VERSION, obs) |
| 75 | { | 75 | { |
| 76 | // Initialise members | 76 | // Initialise members |
| 77 | init_members(); | 77 | init_members(); |
| @@ -89,7 +89,7 @@ ctbutterfly::ctbutterfly(const GObservations& obs) : | @@ -89,7 +89,7 @@ ctbutterfly::ctbutterfly(const GObservations& obs) : | ||
| 89 | * @param[in] argv Array of command line arguments. | 89 | * @param[in] argv Array of command line arguments. |
| 90 | ***************************************************************************/ | 90 | ***************************************************************************/ |
| 91 | ctbutterfly::ctbutterfly(int argc, char *argv[]) : | 91 | ctbutterfly::ctbutterfly(int argc, char *argv[]) : |
| 92 | - ctlikelihood(CTBUTTERFLY_NAME, CTBUTTERFLY_VERSION, argc, argv) | 92 | + ctlikelihood(CTBUTTERFLY_NAME, CTBUTTERFLY_VERSION, argc, argv) |
| 93 | { | 93 | { |
| 94 | // Initialise members | 94 | // Initialise members |
| 95 | init_members(); | 95 | init_members(); |
| @@ -251,7 +251,7 @@ void ctbutterfly::run(void) | @@ -251,7 +251,7 @@ void ctbutterfly::run(void) | ||
| 251 | else { | 251 | else { |
| 252 | m_covariance = likelihood.covariance(); | 252 | m_covariance = likelihood.covariance(); |
| 253 | } | 253 | } |
| 254 | - | 254 | + |
| 255 | // Write optimizer, optimised model and covariance matrix into logger | 255 | // Write optimizer, optimised model and covariance matrix into logger |
| 256 | log_string(NORMAL, m_opt.print(m_chatter)); | 256 | log_string(NORMAL, m_opt.print(m_chatter)); |
| 257 | log_string(NORMAL, m_obs.models().print(m_chatter)); | 257 | log_string(NORMAL, m_obs.models().print(m_chatter)); |
| @@ -291,7 +291,7 @@ void ctbutterfly::run(void) | @@ -291,7 +291,7 @@ void ctbutterfly::run(void) | ||
| 291 | log_header1(TERSE, "Prepare butterfly computation"); | 291 | log_header1(TERSE, "Prepare butterfly computation"); |
| 292 | 292 | ||
| 293 | if (!m_gepmode) { | 293 | if (!m_gepmode) { |
| 294 | - | 294 | + |
| 295 | // Find parameter indices. We do this by the memory location of the | 295 | // Find parameter indices. We do this by the memory location of the |
| 296 | // model parameters. | 296 | // model parameters. |
| 297 | GModelSky* skymodel = dynamic_cast<GModelSky*>(models[m_srcname]); | 297 | GModelSky* skymodel = dynamic_cast<GModelSky*>(models[m_srcname]); |
| @@ -318,9 +318,9 @@ void ctbutterfly::run(void) | @@ -318,9 +318,9 @@ void ctbutterfly::run(void) | ||
| 318 | 318 | ||
| 319 | // Write parameter indices into logger | 319 | // Write parameter indices into logger |
| 320 | log_value(NORMAL, "Prefactor", gammalib::str(prefactor_mean)+ | 320 | log_value(NORMAL, "Prefactor", gammalib::str(prefactor_mean)+ |
| 321 | - " ph/cm2/s/MeV ("+gammalib::str(inx_prefactor)+")"); | 321 | + " ph/cm2/s/MeV ("+gammalib::str(inx_prefactor)+")"); |
| 322 | log_value(NORMAL, "Index", gammalib::str(index_mean)+ | 322 | log_value(NORMAL, "Index", gammalib::str(index_mean)+ |
| 323 | - " ("+gammalib::str(inx_index)+")"); | 323 | + " ("+gammalib::str(inx_index)+")"); |
| 324 | log_value(NORMAL, "Pivot energy", pivot.print()); | 324 | log_value(NORMAL, "Pivot energy", pivot.print()); |
| 325 | 325 | ||
| 326 | // Extract covariance elements | 326 | // Extract covariance elements |
| @@ -334,7 +334,7 @@ void ctbutterfly::run(void) | @@ -334,7 +334,7 @@ void ctbutterfly::run(void) | ||
| 334 | GVector vector1(2); | 334 | GVector vector1(2); |
| 335 | GVector vector2(2); | 335 | GVector vector2(2); |
| 336 | eigenvectors(cov_pp, cov_pg, cov_pg, cov_gg, | 336 | eigenvectors(cov_pp, cov_pg, cov_pg, cov_gg, |
| 337 | - &lambda1, &lambda2, &vector1, &vector2); | 337 | + &lambda1, &lambda2, &vector1, &vector2); |
| 338 | 338 | ||
| 339 | // Write eigenvectors and eigenvalues into logger | 339 | // Write eigenvectors and eigenvalues into logger |
| 340 | log_value(NORMAL, "Eigenvalue 1", lambda1); | 340 | log_value(NORMAL, "Eigenvalue 1", lambda1); |
| @@ -375,16 +375,16 @@ void ctbutterfly::run(void) | @@ -375,16 +375,16 @@ void ctbutterfly::run(void) | ||
| 375 | 375 | ||
| 376 | // Compute prefactor and index | 376 | // Compute prefactor and index |
| 377 | double prefactor = (major * cos_t * vector1[0] + | 377 | double prefactor = (major * cos_t * vector1[0] + |
| 378 | - minor * sin_t * vector2[0]) * prefactor_scale + | ||
| 379 | - prefactor_mean; | 378 | + minor * sin_t * vector2[0]) * prefactor_scale + |
| 379 | + prefactor_mean; | ||
| 380 | double index = (major * cos_t * vector1[1] + | 380 | double index = (major * cos_t * vector1[1] + |
| 381 | - minor * sin_t * vector2[1]) * index_scale + | ||
| 382 | - index_mean; | 381 | + minor * sin_t * vector2[1]) * index_scale + |
| 382 | + index_mean; | ||
| 383 | 383 | ||
| 384 | // Write prefactor and index into logger | 384 | // Write prefactor and index into logger |
| 385 | log_value(EXPLICIT, "Angle "+gammalib::str(t*gammalib::rad2deg), | 385 | log_value(EXPLICIT, "Angle "+gammalib::str(t*gammalib::rad2deg), |
| 386 | - gammalib::str(prefactor)+" ph/cm2/s/MeV; "+ | ||
| 387 | - gammalib::str(index)); | 386 | + gammalib::str(prefactor)+" ph/cm2/s/MeV; "+ |
| 387 | + gammalib::str(index)); | ||
| 388 | 388 | ||
| 389 | // Setup power law model | 389 | // Setup power law model |
| 390 | GModelSpectralPlaw plaw(prefactor, index, pivot); | 390 | GModelSpectralPlaw plaw(prefactor, index, pivot); |
| @@ -438,7 +438,7 @@ void ctbutterfly::run(void) | @@ -438,7 +438,7 @@ void ctbutterfly::run(void) | ||
| 438 | // Use gaussian error propagation scheme to calculate | 438 | // Use gaussian error propagation scheme to calculate |
| 439 | // the butterfly | 439 | // the butterfly |
| 440 | log_header2(TERSE, "Use gaussian error propagation to " | 440 | log_header2(TERSE, "Use gaussian error propagation to " |
| 441 | - "calculate butterfly"); | 441 | + "calculate butterfly"); |
| 442 | 442 | ||
| 443 | // Initialise dummy time to evaluate spectral model | 443 | // Initialise dummy time to evaluate spectral model |
| 444 | GTime time = GTime(); | 444 | GTime time = GTime(); |
| @@ -454,7 +454,7 @@ void ctbutterfly::run(void) | @@ -454,7 +454,7 @@ void ctbutterfly::run(void) | ||
| 454 | 454 | ||
| 455 | // Get the energy of current bin | 455 | // Get the energy of current bin |
| 456 | GEnergy energy = m_ebounds.elogmean(i); | 456 | GEnergy energy = m_ebounds.elogmean(i); |
| 457 | - | 457 | + |
| 458 | // Initialise model flux value | 458 | // Initialise model flux value |
| 459 | double model_flux = 0.0; | 459 | double model_flux = 0.0; |
| 460 | 460 | ||
| @@ -467,37 +467,44 @@ void ctbutterfly::run(void) | @@ -467,37 +467,44 @@ void ctbutterfly::run(void) | ||
| 467 | // Yes ... | 467 | // Yes ... |
| 468 | if (skymodel != NULL) { | 468 | if (skymodel != NULL) { |
| 469 | 469 | ||
| 470 | - // Skip spatial models | ||
| 471 | - num_gradient += skymodel->spatial()->size(); | ||
| 472 | - | ||
| 473 | - // Get pointer to spectral model | ||
| 474 | - GModelSpectral* spectral = skymodel->spectral(); | ||
| 475 | - | ||
| 476 | // Set flux value of source of interest, evaluate gradients | 470 | // Set flux value of source of interest, evaluate gradients |
| 477 | if (skymodel->name() == m_srcname) { | 471 | if (skymodel->name() == m_srcname) { |
| 472 | + | ||
| 473 | + // Get spectral component of model | ||
| 474 | + GModelSpectral *spectral = skymodel->spectral(); | ||
| 475 | + | ||
| 478 | model_flux = spectral->eval(energy, time, true); | 476 | model_flux = spectral->eval(energy, time, true); |
| 477 | + | ||
| 478 | + // Loop over all model parameters | ||
| 479 | + for (int k = 0; k < skymodel->size(); ++k) { | ||
| 480 | + | ||
| 481 | + // set gradient if we deal with spectral component | ||
| 482 | + bool parIsSpectral = false; | ||
| 483 | + | ||
| 484 | + for (int l = 0; l < spectral->size(); ++l) { | ||
| 485 | + | ||
| 486 | + if ((&((*spectral)[l])) == (&((*skymodel)[k]))) { | ||
| 487 | + grad[num_gradient] = (*spectral)[l].gradient(); | ||
| 488 | + num_gradient++; | ||
| 489 | + parIsSpectral = true; | ||
| 490 | + break; | ||
| 491 | + } | ||
| 492 | + } // endfor: looped over spectral parameters | ||
| 493 | + | ||
| 494 | + | ||
| 495 | + if (!parIsSpectral) { | ||
| 496 | + // If parameter is spatial or temporal, count up | ||
| 497 | + num_gradient++; | ||
| 498 | + } | ||
| 499 | + | ||
| 500 | + } // endfor: looped over all model parameters | ||
| 501 | + | ||
| 502 | + | ||
| 503 | + | ||
| 479 | } // endif: model was source of interest | 504 | } // endif: model was source of interest |
| 480 | - | ||
| 481 | - // Loop over model parameters, get gradients | ||
| 482 | - // and assign them to the vector | ||
| 483 | - if(skymodel->name() == m_srcname) { | ||
| 484 | - | ||
| 485 | - // set gradient if we deal with source of interest | ||
| 486 | - for (int k = 0; k < spectral->size(); ++k) { | ||
| 487 | - grad[num_gradient] = (*spectral)[k].gradient(); | ||
| 488 | - num_gradient++; | ||
| 489 | - | ||
| 490 | - } // endfor: looped over spectral parameters | ||
| 491 | - | ||
| 492 | - } //endif: spectrum was of source of interest | ||
| 493 | - else{ | ||
| 494 | - // Skip gradient of other models (0=default) | ||
| 495 | - num_gradient += skymodel->spectral()->size(); | ||
| 496 | - | ||
| 497 | - } //endelse: Model was not model of interest | ||
| 498 | - | ||
| 499 | - // Skip temporal models | ||
| 500 | - num_gradient += skymodel->temporal()->size(); | 505 | + else { |
| 506 | + num_gradient += skymodel->size(); | ||
| 507 | + } | ||
| 501 | 508 | ||
| 502 | } // endif: model was sky model | 509 | } // endif: model was sky model |
| 503 | 510 | ||
| @@ -515,17 +522,21 @@ void ctbutterfly::run(void) | @@ -515,17 +522,21 @@ void ctbutterfly::run(void) | ||
| 515 | // Get the error from the scalar product | 522 | // Get the error from the scalar product |
| 516 | double error = std::sqrt(grad * vector); | 523 | double error = std::sqrt(grad * vector); |
| 517 | 524 | ||
| 525 | + // Confidence scaling | ||
| 526 | + double sigma = gammalib::erfinv(m_confidence) * gammalib::sqrt_two; | ||
| 527 | + error *= sigma; | ||
| 528 | + | ||
| 518 | // Store flux, value and energy for saving | 529 | // Store flux, value and energy for saving |
| 519 | m_intensities.push_back(model_flux); | 530 | m_intensities.push_back(model_flux); |
| 520 | m_energies.push_back(energy.MeV()); | 531 | m_energies.push_back(energy.MeV()); |
| 521 | m_min_intensities.push_back(model_flux-error); | 532 | m_min_intensities.push_back(model_flux-error); |
| 522 | m_max_intensities.push_back(model_flux+error); | 533 | m_max_intensities.push_back(model_flux+error); |
| 523 | - | 534 | + |
| 524 | } //endfor: loop over energy bin | 535 | } //endfor: loop over energy bin |
| 525 | - | 536 | + |
| 526 | } //endelse: use gaussian error propagation | 537 | } //endelse: use gaussian error propagation |
| 527 | 538 | ||
| 528 | - | 539 | + |
| 529 | // Write header into logger | 540 | // Write header into logger |
| 530 | log_header1(TERSE, "Results"); | 541 | log_header1(TERSE, "Results"); |
| 531 | 542 | ||
| @@ -534,14 +545,14 @@ void ctbutterfly::run(void) | @@ -534,14 +545,14 @@ void ctbutterfly::run(void) | ||
| 534 | 545 | ||
| 535 | // Write results into logger | 546 | // Write results into logger |
| 536 | log_value(NORMAL, "Intensity at "+gammalib::str(m_energies[k])+" MeV", | 547 | log_value(NORMAL, "Intensity at "+gammalib::str(m_energies[k])+" MeV", |
| 537 | - gammalib::str(m_intensities[k])+" ("+ | ||
| 538 | - gammalib::str(m_min_intensities[k])+", "+ | ||
| 539 | - gammalib::str(m_max_intensities[k])+") ph/cm2/s/MeV"); | ||
| 540 | - | 548 | + gammalib::str(m_intensities[k])+" ("+ |
| 549 | + gammalib::str(m_min_intensities[k])+", "+ | ||
| 550 | + gammalib::str(m_max_intensities[k])+") ph/cm2/s/MeV"); | ||
| 551 | + | ||
| 541 | } //endfor: loop over energy bin | 552 | } //endfor: loop over energy bin |
| 542 | - | ||
| 543 | 553 | ||
| 544 | - | 554 | + |
| 555 | + | ||
| 545 | // Restore energy dispersion flag for all CTA observations | 556 | // Restore energy dispersion flag for all CTA observations |
| 546 | for (int i = 0; i < m_obs.size(); ++i) { | 557 | for (int i = 0; i < m_obs.size(); ++i) { |
| 547 | GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]); | 558 | GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]); |
| @@ -651,7 +662,7 @@ void ctbutterfly::copy_members(const ctbutterfly& app) | @@ -651,7 +662,7 @@ void ctbutterfly::copy_members(const ctbutterfly& app) | ||
| 651 | m_chatter = app.m_chatter; | 662 | m_chatter = app.m_chatter; |
| 652 | m_ebounds = app.m_ebounds; | 663 | m_ebounds = app.m_ebounds; |
| 653 | m_outfile = app.m_outfile; | 664 | m_outfile = app.m_outfile; |
| 654 | - | 665 | + |
| 655 | // Copy protected members | 666 | // Copy protected members |
| 656 | m_covariance = app.m_covariance; | 667 | m_covariance = app.m_covariance; |
| 657 | m_energies = app.m_energies; | 668 | m_energies = app.m_energies; |
| @@ -690,7 +701,7 @@ void ctbutterfly::get_parameters(void) | @@ -690,7 +701,7 @@ void ctbutterfly::get_parameters(void) | ||
| 690 | { | 701 | { |
| 691 | // Setup observations from "inobs" parameter | 702 | // Setup observations from "inobs" parameter |
| 692 | setup_observations(m_obs); | 703 | setup_observations(m_obs); |
| 693 | - | 704 | + |
| 694 | // Setup models from "inmodel" parameter | 705 | // Setup models from "inmodel" parameter |
| 695 | setup_models(m_obs, (*this)["srcname"].string()); | 706 | setup_models(m_obs, (*this)["srcname"].string()); |
| 696 | 707 | ||
| @@ -704,8 +715,8 @@ void ctbutterfly::get_parameters(void) | @@ -704,8 +715,8 @@ void ctbutterfly::get_parameters(void) | ||
| 704 | std::string matrixfilename = (*this)["matrix"].filename(); | 715 | std::string matrixfilename = (*this)["matrix"].filename(); |
| 705 | if (matrixfilename != "NONE") { | 716 | if (matrixfilename != "NONE") { |
| 706 | std::string msg = "Loading of matrix from file not implemented yet. " | 717 | std::string msg = "Loading of matrix from file not implemented yet. " |
| 707 | - "Use filename = \"NONE\" to induce a recomputation of " | ||
| 708 | - "the matrix internally."; | 718 | + "Use filename = \"NONE\" to induce a recomputation of " |
| 719 | + "the matrix internally."; | ||
| 709 | throw GException::feature_not_implemented(G_GET_PARAMETERS, msg); | 720 | throw GException::feature_not_implemented(G_GET_PARAMETERS, msg); |
| 710 | // m_covariance.load(matrixfilename); | 721 | // m_covariance.load(matrixfilename); |
| 711 | } | 722 | } |
| @@ -719,7 +730,7 @@ void ctbutterfly::get_parameters(void) | @@ -719,7 +730,7 @@ void ctbutterfly::get_parameters(void) | ||
| 719 | 730 | ||
| 720 | // Check model name and type | 731 | // Check model name and type |
| 721 | check_model(); | 732 | check_model(); |
| 722 | - | 733 | + |
| 723 | // Optionally read ahead parameters so that they get correctly | 734 | // Optionally read ahead parameters so that they get correctly |
| 724 | // dumped into the log file | 735 | // dumped into the log file |
| 725 | if (read_ahead()) { | 736 | if (read_ahead()) { |
| @@ -753,8 +764,8 @@ void ctbutterfly::check_model(void) | @@ -753,8 +764,8 @@ void ctbutterfly::check_model(void) | ||
| 753 | GModelSky* model = dynamic_cast<GModelSky*>(models[m_srcname]); | 764 | GModelSky* model = dynamic_cast<GModelSky*>(models[m_srcname]); |
| 754 | if (model == NULL) { | 765 | if (model == NULL) { |
| 755 | std::string msg = "Source \""+m_srcname+"\" is not a sky model. " | 766 | std::string msg = "Source \""+m_srcname+"\" is not a sky model. " |
| 756 | - "Please specify the name of a sky model for " | ||
| 757 | - "butterfly computation."; | 767 | + "Please specify the name of a sky model for " |
| 768 | + "butterfly computation."; | ||
| 758 | throw GException::invalid_value(G_CHECK_MODEL, msg); | 769 | throw GException::invalid_value(G_CHECK_MODEL, msg); |
| 759 | } | 770 | } |
| 760 | 771 | ||
| @@ -762,9 +773,9 @@ void ctbutterfly::check_model(void) | @@ -762,9 +773,9 @@ void ctbutterfly::check_model(void) | ||
| 762 | if(!m_gepmode){ | 773 | if(!m_gepmode){ |
| 763 | if (model->spectral()->type() != "PowerLaw") { | 774 | if (model->spectral()->type() != "PowerLaw") { |
| 764 | std::string msg = "\""+model->spectral()->type()+"\" cannot be " | 775 | std::string msg = "\""+model->spectral()->type()+"\" cannot be " |
| 765 | - "used as spectral model for an butterfly " | ||
| 766 | - "computation in default mode. Please specify a " | ||
| 767 | - "power law model or switch to gep mode."; | 776 | + "used as spectral model for an butterfly " |
| 777 | + "computation in default mode. Please specify a " | ||
| 778 | + "power law model or switch to gep mode."; | ||
| 768 | throw GException::invalid_value(G_CHECK_MODEL, msg); | 779 | throw GException::invalid_value(G_CHECK_MODEL, msg); |
| 769 | } | 780 | } |
| 770 | } | 781 | } |
| @@ -774,8 +785,8 @@ void ctbutterfly::check_model(void) | @@ -774,8 +785,8 @@ void ctbutterfly::check_model(void) | ||
| 774 | // Otherwise throw an exception | 785 | // Otherwise throw an exception |
| 775 | else { | 786 | else { |
| 776 | std::string msg = "Source \""+m_srcname+"\" not found in model " | 787 | std::string msg = "Source \""+m_srcname+"\" not found in model " |
| 777 | - "container. Please add a source with that name " | ||
| 778 | - "or check for possible typos."; | 788 | + "container. Please add a source with that name " |
| 789 | + "or check for possible typos."; | ||
| 779 | throw GException::invalid_value(G_CHECK_MODEL, msg); | 790 | throw GException::invalid_value(G_CHECK_MODEL, msg); |
| 780 | } | 791 | } |
| 781 | 792 | ||
| @@ -800,13 +811,13 @@ void ctbutterfly::check_model(void) | @@ -800,13 +811,13 @@ void ctbutterfly::check_model(void) | ||
| 800 | * http://www.math.harvard.edu/archive/21b_fall_04/exhibits/2dmatrices/index.html | 811 | * http://www.math.harvard.edu/archive/21b_fall_04/exhibits/2dmatrices/index.html |
| 801 | ***************************************************************************/ | 812 | ***************************************************************************/ |
| 802 | void ctbutterfly::eigenvectors(const double& a, | 813 | void ctbutterfly::eigenvectors(const double& a, |
| 803 | - const double& b, | ||
| 804 | - const double& c, | ||
| 805 | - const double& d, | ||
| 806 | - double* lambda1, | ||
| 807 | - double* lambda2, | ||
| 808 | - GVector* vector1, | ||
| 809 | - GVector* vector2) | 814 | + const double& b, |
| 815 | + const double& c, | ||
| 816 | + const double& d, | ||
| 817 | + double* lambda1, | ||
| 818 | + double* lambda2, | ||
| 819 | + GVector* vector1, | ||
| 820 | + GVector* vector2) | ||
| 810 | { | 821 | { |
| 811 | // Compute trace and determinant | 822 | // Compute trace and determinant |
| 812 | double trace = a + d; | 823 | double trace = a + d; |
| @@ -841,7 +852,7 @@ void ctbutterfly::eigenvectors(const double& a, | @@ -841,7 +852,7 @@ void ctbutterfly::eigenvectors(const double& a, | ||
| 841 | // Normalize eigenvectors | 852 | // Normalize eigenvectors |
| 842 | *vector1 /= norm(*vector1); | 853 | *vector1 /= norm(*vector1); |
| 843 | *vector2 /= norm(*vector2); | 854 | *vector2 /= norm(*vector2); |
| 844 | - | 855 | + |
| 845 | // Return | 856 | // Return |
| 846 | return; | 857 | return; |
| 847 | } | 858 | } |