Commit ebb6e1f672db870b1ef3760ae1359db6cb35d88a

Authored by Domenico Tiziani
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&amp; app) @@ -651,7 +662,7 @@ void ctbutterfly::copy_members(const ctbutterfly&amp; 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&amp; a, @@ -841,7 +852,7 @@ void ctbutterfly::eigenvectors(const double&amp; 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 }