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 71 * observations container.
72 72 ***************************************************************************/
73 73 ctbutterfly::ctbutterfly(const GObservations& obs) :
74   - ctlikelihood(CTBUTTERFLY_NAME, CTBUTTERFLY_VERSION, obs)
  74 + ctlikelihood(CTBUTTERFLY_NAME, CTBUTTERFLY_VERSION, obs)
75 75 {
76 76 // Initialise members
77 77 init_members();
... ... @@ -89,7 +89,7 @@ ctbutterfly::ctbutterfly(const GObservations& obs) :
89 89 * @param[in] argv Array of command line arguments.
90 90 ***************************************************************************/
91 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 94 // Initialise members
95 95 init_members();
... ... @@ -251,7 +251,7 @@ void ctbutterfly::run(void)
251 251 else {
252 252 m_covariance = likelihood.covariance();
253 253 }
254   -
  254 +
255 255 // Write optimizer, optimised model and covariance matrix into logger
256 256 log_string(NORMAL, m_opt.print(m_chatter));
257 257 log_string(NORMAL, m_obs.models().print(m_chatter));
... ... @@ -291,7 +291,7 @@ void ctbutterfly::run(void)
291 291 log_header1(TERSE, "Prepare butterfly computation");
292 292  
293 293 if (!m_gepmode) {
294   -
  294 +
295 295 // Find parameter indices. We do this by the memory location of the
296 296 // model parameters.
297 297 GModelSky* skymodel = dynamic_cast<GModelSky*>(models[m_srcname]);
... ... @@ -318,9 +318,9 @@ void ctbutterfly::run(void)
318 318  
319 319 // Write parameter indices into logger
320 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 322 log_value(NORMAL, "Index", gammalib::str(index_mean)+
323   - " ("+gammalib::str(inx_index)+")");
  323 + " ("+gammalib::str(inx_index)+")");
324 324 log_value(NORMAL, "Pivot energy", pivot.print());
325 325  
326 326 // Extract covariance elements
... ... @@ -334,7 +334,7 @@ void ctbutterfly::run(void)
334 334 GVector vector1(2);
335 335 GVector vector2(2);
336 336 eigenvectors(cov_pp, cov_pg, cov_pg, cov_gg,
337   - &lambda1, &lambda2, &vector1, &vector2);
  337 + &lambda1, &lambda2, &vector1, &vector2);
338 338  
339 339 // Write eigenvectors and eigenvalues into logger
340 340 log_value(NORMAL, "Eigenvalue 1", lambda1);
... ... @@ -375,16 +375,16 @@ void ctbutterfly::run(void)
375 375  
376 376 // Compute prefactor and index
377 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 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 384 // Write prefactor and index into logger
385 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 389 // Setup power law model
390 390 GModelSpectralPlaw plaw(prefactor, index, pivot);
... ... @@ -438,7 +438,7 @@ void ctbutterfly::run(void)
438 438 // Use gaussian error propagation scheme to calculate
439 439 // the butterfly
440 440 log_header2(TERSE, "Use gaussian error propagation to "
441   - "calculate butterfly");
  441 + "calculate butterfly");
442 442  
443 443 // Initialise dummy time to evaluate spectral model
444 444 GTime time = GTime();
... ... @@ -454,7 +454,7 @@ void ctbutterfly::run(void)
454 454  
455 455 // Get the energy of current bin
456 456 GEnergy energy = m_ebounds.elogmean(i);
457   -
  457 +
458 458 // Initialise model flux value
459 459 double model_flux = 0.0;
460 460  
... ... @@ -467,37 +467,44 @@ void ctbutterfly::run(void)
467 467 // Yes ...
468 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 470 // Set flux value of source of interest, evaluate gradients
477 471 if (skymodel->name() == m_srcname) {
  472 +
  473 + // Get spectral component of model
  474 + GModelSpectral *spectral = skymodel->spectral();
  475 +
478 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 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 509 } // endif: model was sky model
503 510  
... ... @@ -515,17 +522,21 @@ void ctbutterfly::run(void)
515 522 // Get the error from the scalar product
516 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 529 // Store flux, value and energy for saving
519 530 m_intensities.push_back(model_flux);
520 531 m_energies.push_back(energy.MeV());
521 532 m_min_intensities.push_back(model_flux-error);
522 533 m_max_intensities.push_back(model_flux+error);
523   -
  534 +
524 535 } //endfor: loop over energy bin
525   -
  536 +
526 537 } //endelse: use gaussian error propagation
527 538  
528   -
  539 +
529 540 // Write header into logger
530 541 log_header1(TERSE, "Results");
531 542  
... ... @@ -534,14 +545,14 @@ void ctbutterfly::run(void)
534 545  
535 546 // Write results into logger
536 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 552 } //endfor: loop over energy bin
542   -
543 553  
544   -
  554 +
  555 +
545 556 // Restore energy dispersion flag for all CTA observations
546 557 for (int i = 0; i < m_obs.size(); ++i) {
547 558 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
... ... @@ -651,7 +662,7 @@ void ctbutterfly::copy_members(const ctbutterfly&amp; app)
651 662 m_chatter = app.m_chatter;
652 663 m_ebounds = app.m_ebounds;
653 664 m_outfile = app.m_outfile;
654   -
  665 +
655 666 // Copy protected members
656 667 m_covariance = app.m_covariance;
657 668 m_energies = app.m_energies;
... ... @@ -690,7 +701,7 @@ void ctbutterfly::get_parameters(void)
690 701 {
691 702 // Setup observations from "inobs" parameter
692 703 setup_observations(m_obs);
693   -
  704 +
694 705 // Setup models from "inmodel" parameter
695 706 setup_models(m_obs, (*this)["srcname"].string());
696 707  
... ... @@ -704,8 +715,8 @@ void ctbutterfly::get_parameters(void)
704 715 std::string matrixfilename = (*this)["matrix"].filename();
705 716 if (matrixfilename != "NONE") {
706 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 720 throw GException::feature_not_implemented(G_GET_PARAMETERS, msg);
710 721 // m_covariance.load(matrixfilename);
711 722 }
... ... @@ -719,7 +730,7 @@ void ctbutterfly::get_parameters(void)
719 730  
720 731 // Check model name and type
721 732 check_model();
722   -
  733 +
723 734 // Optionally read ahead parameters so that they get correctly
724 735 // dumped into the log file
725 736 if (read_ahead()) {
... ... @@ -753,8 +764,8 @@ void ctbutterfly::check_model(void)
753 764 GModelSky* model = dynamic_cast<GModelSky*>(models[m_srcname]);
754 765 if (model == NULL) {
755 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 769 throw GException::invalid_value(G_CHECK_MODEL, msg);
759 770 }
760 771  
... ... @@ -762,9 +773,9 @@ void ctbutterfly::check_model(void)
762 773 if(!m_gepmode){
763 774 if (model->spectral()->type() != "PowerLaw") {
764 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 779 throw GException::invalid_value(G_CHECK_MODEL, msg);
769 780 }
770 781 }
... ... @@ -774,8 +785,8 @@ void ctbutterfly::check_model(void)
774 785 // Otherwise throw an exception
775 786 else {
776 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 790 throw GException::invalid_value(G_CHECK_MODEL, msg);
780 791 }
781 792  
... ... @@ -800,13 +811,13 @@ void ctbutterfly::check_model(void)
800 811 * http://www.math.harvard.edu/archive/21b_fall_04/exhibits/2dmatrices/index.html
801 812 ***************************************************************************/
802 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 822 // Compute trace and determinant
812 823 double trace = a + d;
... ... @@ -841,7 +852,7 @@ void ctbutterfly::eigenvectors(const double&amp; a,
841 852 // Normalize eigenvectors
842 853 *vector1 /= norm(*vector1);
843 854 *vector2 /= norm(*vector2);
844   -
  855 +
845 856 // Return
846 857 return;
847 858 }
... ...