Commit f522be3ac0b17b470e5a56a3e9875ce320c54fbb

Authored by Jürgen Knödlseder
1 parent ab4461b6

Finalize response optimization.

inst/cta/src/GCTAResponseCube.cpp
@@ -64,6 +64,7 @@ @@ -64,6 +64,7 @@
64 /* __ Macros _____________________________________________________________ */ 64 /* __ Macros _____________________________________________________________ */
65 65
66 /* __ Coding definitions _________________________________________________ */ 66 /* __ Coding definitions _________________________________________________ */
  67 +#define G_RADIAL_PSF_BASED //!< Use Psf-based integration for radial model
67 68
68 /* __ Debug definitions __________________________________________________ */ 69 /* __ Debug definitions __________________________________________________ */
69 70
@@ -237,11 +238,12 @@ GCTAResponseCube* GCTAResponseCube::clone(void) const @@ -237,11 +238,12 @@ GCTAResponseCube* GCTAResponseCube::clone(void) const
237 238
238 239
239 /***********************************************************************//** 240 /***********************************************************************//**
240 - * @brief Return value of instrument response function 241 + * @brief Return instrument response
241 * 242 *
242 * @param[in] event Observed event. 243 * @param[in] event Observed event.
243 * @param[in] photon Incident photon. 244 * @param[in] photon Incident photon.
244 * @param[in] obs Observation. 245 * @param[in] obs Observation.
  246 + * @return Instrument response.
245 ***************************************************************************/ 247 ***************************************************************************/
246 double GCTAResponseCube::irf(const GEvent& event, 248 double GCTAResponseCube::irf(const GEvent& event,
247 const GPhoton& photon, 249 const GPhoton& photon,
@@ -308,14 +310,14 @@ double GCTAResponseCube::irf(const GEvent&amp; event, @@ -308,14 +310,14 @@ double GCTAResponseCube::irf(const GEvent&amp; event,
308 310
309 311
310 /***********************************************************************//** 312 /***********************************************************************//**
311 - * @brief Return value of instrument response function 313 + * @brief Return instrument response
312 * 314 *
313 * @param[in] event Event. 315 * @param[in] event Event.
314 * @param[in] source Source. 316 * @param[in] source Source.
315 * @param[in] obs Observation. 317 * @param[in] obs Observation.
  318 + * @return Instrument response.
316 * 319 *
317 - * Returns the instrument response function for a given event, source and  
318 - * observation. 320 + * Returns the instrument response for a given event, source and observation.
319 ***************************************************************************/ 321 ***************************************************************************/
320 double GCTAResponseCube::irf(const GEvent& event, 322 double GCTAResponseCube::irf(const GEvent& event,
321 const GSource& source, 323 const GSource& source,
@@ -348,15 +350,14 @@ double GCTAResponseCube::irf(const GEvent&amp; event, @@ -348,15 +350,14 @@ double GCTAResponseCube::irf(const GEvent&amp; event,
348 350
349 351
350 /***********************************************************************//** 352 /***********************************************************************//**
351 - * @brief Return value of point source instrument response function 353 + * @brief Return instrument response to point source
352 * 354 *
353 * @param[in] event Observed event. 355 * @param[in] event Observed event.
354 * @param[in] source Source. 356 * @param[in] source Source.
355 * @param[in] obs Observation. 357 * @param[in] obs Observation.
356 - * @return Value of instrument response function for a point source. 358 + * @return Instrument response to point source.
357 * 359 *
358 - * This method returns the value of the instrument response function for a  
359 - * point source. 360 + * Returns the instrument response to a specified point source.
360 ***************************************************************************/ 361 ***************************************************************************/
361 double GCTAResponseCube::irf_ptsrc(const GEvent& event, 362 double GCTAResponseCube::irf_ptsrc(const GEvent& event,
362 const GSource& source, 363 const GSource& source,
@@ -426,15 +427,14 @@ double GCTAResponseCube::irf_ptsrc(const GEvent&amp; event, @@ -426,15 +427,14 @@ double GCTAResponseCube::irf_ptsrc(const GEvent&amp; event,
426 427
427 428
428 /***********************************************************************//** 429 /***********************************************************************//**
429 - * @brief Return value of radial source instrument response function 430 + * @brief Return instrument response to radial source
430 * 431 *
431 * @param[in] event Observed event. 432 * @param[in] event Observed event.
432 * @param[in] source Source. 433 * @param[in] source Source.
433 * @param[in] obs Observation. 434 * @param[in] obs Observation.
434 - * @return Value of instrument response function for a radial source. 435 + * @return Instrument response to radial source.
435 * 436 *
436 - * This method returns the value of the instrument response function for a  
437 - * radial source. Response values are computed on the fly. 437 + * Returns the instrument response to a specified radial source.
438 ***************************************************************************/ 438 ***************************************************************************/
439 double GCTAResponseCube::irf_radial(const GEvent& event, 439 double GCTAResponseCube::irf_radial(const GEvent& event,
440 const GSource& source, 440 const GSource& source,
@@ -497,15 +497,14 @@ double GCTAResponseCube::irf_radial(const GEvent&amp; event, @@ -497,15 +497,14 @@ double GCTAResponseCube::irf_radial(const GEvent&amp; event,
497 497
498 498
499 /***********************************************************************//** 499 /***********************************************************************//**
500 - * @brief Return value of elliptical source instrument response function 500 + * @brief Return instrument response to elliptical source
501 * 501 *
502 * @param[in] event Observed event. 502 * @param[in] event Observed event.
503 * @param[in] source Source. 503 * @param[in] source Source.
504 * @param[in] obs Observation. 504 * @param[in] obs Observation.
505 - * @return Value of instrument response function for an elliptical source. 505 + * @return Instrument response to elliptical source.
506 * 506 *
507 - * This method returns the value of the instrument response function for an  
508 - * elliptical source. Response values are computed on the fly. 507 + * Returns the instrument response to a specified elliptical source.
509 ***************************************************************************/ 508 ***************************************************************************/
510 double GCTAResponseCube::irf_elliptical(const GEvent& event, 509 double GCTAResponseCube::irf_elliptical(const GEvent& event,
511 const GSource& source, 510 const GSource& source,
@@ -569,21 +568,20 @@ double GCTAResponseCube::irf_elliptical(const GEvent&amp; event, @@ -569,21 +568,20 @@ double GCTAResponseCube::irf_elliptical(const GEvent&amp; event,
569 568
570 569
571 /***********************************************************************//** 570 /***********************************************************************//**
572 - * @brief Return value of extended source instrument response function 571 + * @brief Return instrument response to diffuse source
573 * 572 *
574 * @param[in] event Observed event. 573 * @param[in] event Observed event.
575 * @param[in] source Source. 574 * @param[in] source Source.
576 * @param[in] obs Observation. 575 * @param[in] obs Observation.
577 - * @return Value of instrument response function for an extended source. 576 + * @return Instrument response to diffuse source.
578 * 577 *
579 - * This method returns the value of the instrument response function for an  
580 - * extended source. It uses a pre-computation cache to store the IRF for  
581 - * the spatial model component. 578 + * Returns the instrument response to a specified diffuse source.
582 * 579 *
583 - * The pre-computation cache is initialised if no cache has yet been  
584 - * allocated, or if at the beginning of a scan over the events, the model  
585 - * parameters have changed. The beginning of a scan is defined by an event  
586 - * bin index of 0. 580 + * The method uses a pre-computation cache to store the instrument response
  581 + * for the spatial model component. The pre-computation cache is initialised
  582 + * if no cache has yet been allocated, or if at the beginning of a scan over
  583 + * the events, the model parameters have changed. The beginning of a scan is
  584 + * defined by an event bin index of 0.
587 ***************************************************************************/ 585 ***************************************************************************/
588 double GCTAResponseCube::irf_diffuse(const GEvent& event, 586 double GCTAResponseCube::irf_diffuse(const GEvent& event,
589 const GSource& source, 587 const GSource& source,
@@ -652,9 +650,13 @@ double GCTAResponseCube::irf_diffuse(const GEvent&amp; event, @@ -652,9 +650,13 @@ double GCTAResponseCube::irf_diffuse(const GEvent&amp; event,
652 * 650 *
653 * @param[in] photon Incident photon. 651 * @param[in] photon Incident photon.
654 * @param[in] obs Observation. 652 * @param[in] obs Observation.
  653 + * @return Spatial integral of point spread function.
655 * 654 *
656 * @exception GException::feature_not_implemented 655 * @exception GException::feature_not_implemented
657 * Method not implemented. 656 * Method not implemented.
  657 + *
  658 + * This method is a dummy method that is required for a class derived from
  659 + * GResponse but that needs not to be implemented for a binned response.
658 ***************************************************************************/ 660 ***************************************************************************/
659 double GCTAResponseCube::npred(const GPhoton& photon, 661 double GCTAResponseCube::npred(const GPhoton& photon,
660 const GObservation& obs) const 662 const GObservation& obs) const
@@ -669,21 +671,21 @@ double GCTAResponseCube::npred(const GPhoton&amp; photon, @@ -669,21 +671,21 @@ double GCTAResponseCube::npred(const GPhoton&amp; photon,
669 671
670 672
671 /***********************************************************************//** 673 /***********************************************************************//**
672 - * @brief Read response 674 + * @brief Read response information from Xml element
673 * 675 *
674 * @param[in] xml XML element. 676 * @param[in] xml XML element.
675 * 677 *
676 * @exception GException::xml_invalid_parnames 678 * @exception GException::xml_invalid_parnames
677 * Invalid parameter names found in XML element. 679 * Invalid parameter names found in XML element.
678 * 680 *
679 - * Reads information for a CTA observation from an XML element. The exposure  
680 - * and PSF cubes are specified using 681 + * Reads response information from an Xml element. The Exposure and Psf cubes
  682 + * are specified using
681 * 683 *
682 - * <observation name="..." id="..." instrument="...">  
683 - * ...  
684 - * <parameter name="ExposureCube" file="..."/>  
685 - * <parameter name="PsfCube" file="..."/>  
686 - * </observation> 684 + * <observation name="..." id="..." instrument="...">
  685 + * ...
  686 + * <parameter name="ExposureCube" file="..."/>
  687 + * <parameter name="PsfCube" file="..."/>
  688 + * </observation>
687 * 689 *
688 ***************************************************************************/ 690 ***************************************************************************/
689 void GCTAResponseCube::read(const GXmlElement& xml) 691 void GCTAResponseCube::read(const GXmlElement& xml)
@@ -738,18 +740,18 @@ void GCTAResponseCube::read(const GXmlElement&amp; xml) @@ -738,18 +740,18 @@ void GCTAResponseCube::read(const GXmlElement&amp; xml)
738 740
739 741
740 /***********************************************************************//** 742 /***********************************************************************//**
741 - * @brief Write response 743 + * @brief Write response information into Xml element
742 * 744 *
743 * @param[in] xml XML element. 745 * @param[in] xml XML element.
744 * 746 *
745 - * Writes information for a CTA observation into an XML element. The exposure  
746 - * and PSF cubes are specified using 747 + * Writes response information into an Xml element. The Exposure and Psf
  748 + * cubes are specified using
747 * 749 *
748 - * <observation name="..." id="..." instrument="...">  
749 - * ...  
750 - * <parameter name="ExposureCube" file="..."/>  
751 - * <parameter name="PsfCube" file="..."/>  
752 - * </observation> 750 + * <observation name="..." id="..." instrument="...">
  751 + * ...
  752 + * <parameter name="ExposureCube" file="..."/>
  753 + * <parameter name="PsfCube" file="..."/>
  754 + * </observation>
753 * 755 *
754 ***************************************************************************/ 756 ***************************************************************************/
755 void GCTAResponseCube::write(GXmlElement& xml) const 757 void GCTAResponseCube::write(GXmlElement& xml) const
@@ -774,10 +776,10 @@ void GCTAResponseCube::write(GXmlElement&amp; xml) const @@ -774,10 +776,10 @@ void GCTAResponseCube::write(GXmlElement&amp; xml) const
774 776
775 777
776 /***********************************************************************//** 778 /***********************************************************************//**
777 - * @brief Print CTA response information 779 + * @brief Print response information
778 * 780 *
779 * @param[in] chatter Chattiness (defaults to NORMAL). 781 * @param[in] chatter Chattiness (defaults to NORMAL).
780 - * @return String containing CTA response information. 782 + * @return String containing response information.
781 ***************************************************************************/ 783 ***************************************************************************/
782 std::string GCTAResponseCube::print(const GChatter& chatter) const 784 std::string GCTAResponseCube::print(const GChatter& chatter) const
783 { 785 {
@@ -819,20 +821,6 @@ std::string GCTAResponseCube::print(const GChatter&amp; chatter) const @@ -819,20 +821,6 @@ std::string GCTAResponseCube::print(const GChatter&amp; chatter) const
819 821
820 /*========================================================================== 822 /*==========================================================================
821 = = 823 = =
822 - = Model type dependent CTA response methods =  
823 - = =  
824 - ==========================================================================*/  
825 -  
826 -  
827 -/*==========================================================================  
828 - = =  
829 - = Low-level CTA response methods =  
830 - = =  
831 - ==========================================================================*/  
832 -  
833 -  
834 -/*==========================================================================  
835 - = =  
836 = Private methods = 824 = Private methods =
837 = = 825 = =
838 ==========================================================================*/ 826 ==========================================================================*/
@@ -858,7 +846,7 @@ void GCTAResponseCube::init_members(void) @@ -858,7 +846,7 @@ void GCTAResponseCube::init_members(void)
858 /***********************************************************************//** 846 /***********************************************************************//**
859 * @brief Copy class members 847 * @brief Copy class members
860 * 848 *
861 - * @param[in] rsp Response to be copied 849 + * @param[in] rsp Response.
862 ***************************************************************************/ 850 ***************************************************************************/
863 void GCTAResponseCube::copy_members(const GCTAResponseCube& rsp) 851 void GCTAResponseCube::copy_members(const GCTAResponseCube& rsp)
864 { 852 {
@@ -894,10 +882,12 @@ void GCTAResponseCube::free_members(void) @@ -894,10 +882,12 @@ void GCTAResponseCube::free_members(void)
894 882
895 883
896 /***********************************************************************//** 884 /***********************************************************************//**
897 - * @brief Determines the cache index for a given model name 885 + * @brief Determine cache index for model
898 * 886 *
899 * @param[in] name Model name. 887 * @param[in] name Model name.
900 * @return Cache index (-1 if model has not been found). 888 * @return Cache index (-1 if model has not been found).
  889 + *
  890 + * Determines the cache index for a given model @p name.
901 ***************************************************************************/ 891 ***************************************************************************/
902 int GCTAResponseCube::cache_index(const std::string& name) const 892 int GCTAResponseCube::cache_index(const std::string& name) const
903 { 893 {
@@ -922,8 +912,114 @@ int GCTAResponseCube::cache_index(const std::string&amp; name) const @@ -922,8 +912,114 @@ int GCTAResponseCube::cache_index(const std::string&amp; name) const
922 } 912 }
923 913
924 914
  915 +#if defined(G_RADIAL_PSF_BASED)
925 /***********************************************************************//** 916 /***********************************************************************//**
926 - * @brief Integrate PSF over radial model 917 + * @brief Integrate Psf over radial model
  918 + *
  919 + * @param[in] model Radial model.
  920 + * @param[in] delta_mod Angle between model centre and measured photon
  921 + * direction (radians).
  922 + * @param[in] obsDir Observed event direction.
  923 + * @param[in] srcEng True photon energy.
  924 + * @param[in] srcTime True photon arrival time.
  925 + *
  926 + * Integrates the product of the spatial model and the point spread
  927 + * function over the true photon arrival direction using
  928 + *
  929 + * \f[
  930 + * \int_{\delta_{\rm min}}^{\delta_{\rm max}}
  931 + * \sin \delta \times {\rm Psf}(\delta) \times
  932 + * \int_{\phi_{\rm min}}^{\phi_{\rm max}}
  933 + * S_{\rm p}(\delta, \phi | E, t) d\phi d\delta
  934 + * \f]
  935 + *
  936 + * where
  937 + * \f$S_{\rm p}(\delta, \phi | E, t)\f$ is the radial spatial model,
  938 + * \f${\rm Psf}(\delta)\f$ is the point spread function,
  939 + * \f$\delta\f$ is angular distance between the true and the measured
  940 + * photon direction, and
  941 + * \f$\phi\f$ is the position angle around the observed photon direction
  942 + * measured counterclockwise from the connecting line between the model
  943 + * centre and the observed photon arrival direction.
  944 + ***************************************************************************/
  945 +double GCTAResponseCube::psf_radial(const GModelSpatialRadial* model,
  946 + const double& delta_mod,
  947 + const GSkyDir& obsDir,
  948 + const GEnergy& srcEng,
  949 + const GTime& srcTime) const
  950 +{
  951 + // Set number of iterations for Romberg integration.
  952 + // These values have been determined after careful testing, see
  953 + // https://cta-redmine.irap.omp.eu/issues/1291
  954 + static const int iter_delta = 5;
  955 + static const int iter_phi = 6;
  956 +
  957 + // Initialise value
  958 + double value = 0.0;
  959 +
  960 + // Get maximum Psf radius (radians)
  961 + double psf_max = psf().delta_max();
  962 +
  963 + // Get maximum model radius (radians)
  964 + double theta_max = model->theta_max();
  965 +
  966 + // Set offset angle integration range (radians)
  967 + double delta_min = (delta_mod > theta_max) ? delta_mod - theta_max : 0.0;
  968 + double delta_max = delta_mod + theta_max;
  969 + if (delta_max > psf_max) {
  970 + delta_max = psf_max;
  971 + }
  972 +
  973 + // Setup integration kernel. We take here the observed photon arrival
  974 + // direction as the true photon arrival direction because the PSF does
  975 + // not vary significantly over a small region.
  976 + cta_psf_radial_kern_delta integrand(this,
  977 + model,
  978 + obsDir,
  979 + srcEng,
  980 + srcTime,
  981 + delta_mod,
  982 + theta_max,
  983 + iter_phi);
  984 +
  985 + // Integrate over model's zenith angle
  986 + GIntegral integral(&integrand);
  987 + integral.fixed_iter(iter_delta);
  988 +
  989 + // Setup integration boundaries
  990 + std::vector<double> bounds;
  991 + bounds.push_back(delta_min);
  992 + bounds.push_back(delta_max);
  993 +
  994 + // If the integration range includes a transition between full
  995 + // containment of Psf within model and partial containment, then
  996 + // add a boundary at this location
  997 + double transition_point = theta_max - delta_mod;
  998 + if (transition_point > delta_min && transition_point < delta_max) {
  999 + bounds.push_back(transition_point);
  1000 + }
  1001 +
  1002 + // Integrate kernel
  1003 + value = integral.romberg(bounds, iter_delta);
  1004 +
  1005 + // Compile option: Check for NaN/Inf
  1006 + #if defined(G_NAN_CHECK)
  1007 + if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
  1008 + std::cout << "*** ERROR: GCTAResponseCube::psf_radial:";
  1009 + std::cout << " NaN/Inf encountered";
  1010 + std::cout << " (value=" << value;
  1011 + std::cout << ", delta_min=" << delta_min;
  1012 + std::cout << ", delta_max=" << delta_max << ")";
  1013 + std::cout << std::endl;
  1014 + }
  1015 + #endif
  1016 +
  1017 + // Return integral
  1018 + return value;
  1019 +}
  1020 +#else
  1021 +/***********************************************************************//**
  1022 + * @brief Integrate Psf over radial model
927 * 1023 *
928 * @param[in] model Radial model. 1024 * @param[in] model Radial model.
929 * @param[in] rho_obs Angle between model centre and measured photon direction 1025 * @param[in] rho_obs Angle between model centre and measured photon direction
@@ -932,21 +1028,23 @@ int GCTAResponseCube::cache_index(const std::string&amp; name) const @@ -932,21 +1028,23 @@ int GCTAResponseCube::cache_index(const std::string&amp; name) const
932 * @param[in] srcEng True photon energy. 1028 * @param[in] srcEng True photon energy.
933 * @param[in] srcTime True photon arrival time. 1029 * @param[in] srcTime True photon arrival time.
934 * 1030 *
935 - * Computes the integral 1031 + * Integrates the product of the spatial model and the point spread
  1032 + * function over the true photon arrival direction using
936 * 1033 *
937 * \f[ 1034 * \f[
938 - * \int_0^{\delta_{\rm max}}  
939 - * {\rm PSF}(\delta) \times  
940 - * \int_0^{2\pi} {\rm M}(\delta, \phi) \sin \delta  
941 - * {\rm d}\phi {\rm d}\delta 1035 + * \int_{\rho_{\rm min}}^{\rho_{\rm max}}
  1036 + * \sin \rho \times S_{\rm p}(\rho | E, t) \times
  1037 + * \int_{\omega_{\rm min}}^{\omega_{\rm max}}
  1038 + * {\rm Psf}(\rho, \omega) d\omega d\rho
942 * \f] 1039 * \f]
943 * 1040 *
944 - * where \f${\rm M}(\delta, \phi)\f$ is a radial model in the coordinate  
945 - * system of the point spread function, defined by the angle \f$\delta\f$  
946 - * between the true and the measured photon direction and the azimuth angle  
947 - * \f$\phi\f$ around the measured photon direction.  
948 - * \f${\rm PSF}(\delta)\f$ is the azimuthally symmetric point spread  
949 - * function. 1041 + * where
  1042 + * \f$S_{\rm p}(\rho | E, t)\f$ is the radial spatial model,
  1043 + * \f${\rm Psf}(\rho, \omega)\f$ is the point spread function,
  1044 + * \f$\rho\f$ is the radial distance from the model centre, and
  1045 + * \f$\omega\f$ is the position angle around the model centre measured
  1046 + * counterclockwise from the connecting line between the model centre and
  1047 + * the observed photon arrival direction.
950 ***************************************************************************/ 1048 ***************************************************************************/
951 double GCTAResponseCube::psf_radial(const GModelSpatialRadial* model, 1049 double GCTAResponseCube::psf_radial(const GModelSpatialRadial* model,
952 const double& rho_obs, 1050 const double& rho_obs,
@@ -1006,14 +1104,6 @@ double GCTAResponseCube::psf_radial(const GModelSpatialRadial* model, @@ -1006,14 +1104,6 @@ double GCTAResponseCube::psf_radial(const GModelSpatialRadial* model,
1006 bounds.push_back(transition_point); 1104 bounds.push_back(transition_point);
1007 } 1105 }
1008 1106
1009 - // If the integration range includes a transition between full  
1010 - // containment of Psf within model and partial containment, then  
1011 - // add a boundary at this location  
1012 - transition_point = src_max - delta_max;  
1013 - if (transition_point > rho_min && transition_point < rho_max) {  
1014 - bounds.push_back(transition_point);  
1015 - }  
1016 -  
1017 // If we have a shell model then add an integration boundary for the 1107 // If we have a shell model then add an integration boundary for the
1018 // shell radius as a function discontinuity will occur at this 1108 // shell radius as a function discontinuity will occur at this
1019 // location 1109 // location
@@ -1045,10 +1135,11 @@ double GCTAResponseCube::psf_radial(const GModelSpatialRadial* model, @@ -1045,10 +1135,11 @@ double GCTAResponseCube::psf_radial(const GModelSpatialRadial* model,
1045 // Return PSF 1135 // Return PSF
1046 return irf; 1136 return irf;
1047 } 1137 }
  1138 +#endif
1048 1139
1049 1140
1050 /***********************************************************************//** 1141 /***********************************************************************//**
1051 - * @brief Integrate PSF over elliptical model 1142 + * @brief Integrate Psf over elliptical model
1052 * 1143 *
1053 * @param[in] model Elliptical model. 1144 * @param[in] model Elliptical model.
1054 * @param[in] rho_obs Angle between model centre and measured photon direction 1145 * @param[in] rho_obs Angle between model centre and measured photon direction
@@ -1059,36 +1150,24 @@ double GCTAResponseCube::psf_radial(const GModelSpatialRadial* model, @@ -1059,36 +1150,24 @@ double GCTAResponseCube::psf_radial(const GModelSpatialRadial* model,
1059 * @param[in] srcEng True photon energy. 1150 * @param[in] srcEng True photon energy.
1060 * @param[in] srcTime True photon arrival time. 1151 * @param[in] srcTime True photon arrival time.
1061 * 1152 *
1062 - * Computes the integral 1153 + * Integrates the product of the spatial model and the point spread
  1154 + * function over the true photon arrival direction using
1063 * 1155 *
1064 * \f[ 1156 * \f[
1065 * \int_{\rho_{\rm min}}^{\rho_{\rm max}} 1157 * \int_{\rho_{\rm min}}^{\rho_{\rm max}}
1066 - * \sin \rho \times 1158 + * \sin \rho \times
1067 * \int_{\omega} 1159 * \int_{\omega}
1068 - * S_{\rm p}(\rho, \omega | E, t) \, PSF(\rho, \omega) d\omega d\rho 1160 + * S_{\rm p}(\rho, \omega | E, t) \times
  1161 + * {\rm Psf}(\rho, \omega) d\omega d\rho
1069 * \f] 1162 * \f]
1070 * 1163 *
1071 * where 1164 * where
1072 - * \f$S_{\rm p}(\rho, \omega | E, t)\f$ is the elliptical model,  
1073 - * \f$PSF(\rho, \omega)\f$ is the point spread function,  
1074 - * \f$\rho\f$ is the distance from the model centre, and  
1075 - * \f$\omega\f$ is the position angle with respect to the connecting line  
1076 - * between the model centre and the observed photon arrival direction.  
1077 - ***************************************************************************/  
1078 -/*  
1079 - * \f[  
1080 - * \int_0^{\delta_{\rm max}}  
1081 - * {\rm PSF}(\delta) \times  
1082 - * \int_0^{2\pi} {\rm M}(\delta, \phi) \sin \delta  
1083 - * {\rm d}\phi {\rm d}\delta  
1084 - * \f]  
1085 - *  
1086 - * where \f${\rm M}(\delta, \phi)\f$ is an elliptical model in the coordinate  
1087 - * system of the point spread function, defined by the angle \f$\delta\f$  
1088 - * between the true and the measured photon direction and the azimuth angle  
1089 - * \f$\phi\f$ around the measured photon direction.  
1090 - * \f${\rm PSF}(\delta)\f$ is the azimuthally symmetric point spread  
1091 - * function. 1165 + * \f$S_{\rm p}(\rho, \omega | E, t)\f$ is the elliptical spatial model,
  1166 + * \f${\rm Psf}(\rho, \omega)\f$ is the point spread function,
  1167 + * \f$\rho\f$ is the radial distance from the model centre, and
  1168 + * \f$\omega\f$ is the position angle around the model centre measured
  1169 + * counterclockwise from the connecting line between the model centre and
  1170 + * the observed photon arrival direction.
1092 ***************************************************************************/ 1171 ***************************************************************************/
1093 double GCTAResponseCube::psf_elliptical(const GModelSpatialElliptical* model, 1172 double GCTAResponseCube::psf_elliptical(const GModelSpatialElliptical* model,
1094 const double& rho_obs, 1173 const double& rho_obs,
inst/cta/src/GCTAResponseIrf.cpp
@@ -1268,7 +1268,7 @@ std::string GCTAResponseIrf::print(const GChatter&amp; chatter) const @@ -1268,7 +1268,7 @@ std::string GCTAResponseIrf::print(const GChatter&amp; chatter) const
1268 1268
1269 /*========================================================================== 1269 /*==========================================================================
1270 = = 1270 = =
1271 - = Model type dependent CTA response methods = 1271 + = Model type dependent CTA response methods =
1272 = = 1272 = =
1273 ==========================================================================*/ 1273 ==========================================================================*/
1274 1274
@@ -1282,24 +1282,22 @@ std::string GCTAResponseIrf::print(const GChatter&amp; chatter) const @@ -1282,24 +1282,22 @@ std::string GCTAResponseIrf::print(const GChatter&amp; chatter) const
1282 * @exception GCTAException::bad_model_type 1282 * @exception GCTAException::bad_model_type
1283 * Model is not a radial model. 1283 * Model is not a radial model.
1284 * 1284 *
1285 - * Integrates the product of the model and the Irf over the true photon  
1286 - * arrival direction using 1285 + * Integrates the product of the spatial model and the instrument response
  1286 + * function over the true photon arrival direction using
1287 * 1287 *
1288 * \f[ 1288 * \f[
1289 * \int_{\rho_{\rm min}}^{\rho_{\rm max}} 1289 * \int_{\rho_{\rm min}}^{\rho_{\rm max}}
1290 * \sin \rho \times S_{\rm p}(\rho | E, t) \times 1290 * \sin \rho \times S_{\rm p}(\rho | E, t) \times
1291 * \int_{\omega_{\rm min}}^{\omega_{\rm max}} 1291 * \int_{\omega_{\rm min}}^{\omega_{\rm max}}
1292 - * Irf(\rho, \omega) d\omega d\rho 1292 + * {\rm Irf}(\rho, \omega) d\omega d\rho
1293 * \f] 1293 * \f]
1294 * 1294 *
1295 * where 1295 * where
1296 - *  
1297 - * \f$S_{\rm p}(\rho | E, t)\f$ is the radial model,  
1298 - * \f$Irf(\rho, \omega)\f$ is the IRF  
1299 - * \f$\rho\f$ is the distance from the model centre, and  
1300 - * \f$\omega\f$ is the azimuth angle is the position angle with respect  
1301 - * to the connecting line between the model centre and the observed  
1302 - * photon arrival direction. 1296 + * \f$S_{\rm p}(\rho | E, t)\f$ is the radial spatial model,
  1297 + * \f${\rm Irf}(\rho, \omega)\f$ is the instrument response function,
  1298 + * \f$\rho\f$ is the radial distance from the model centre, and
  1299 + * \f$\omega\f$ is the position angle with respect to the connecting line
  1300 + * between the model centre and the observed photon arrival direction.
1303 * 1301 *
1304 * The integration is performed in the coordinate system of the source 1302 * The integration is performed in the coordinate system of the source
1305 * model spanned by \f$\rho\f$ and \f$\omega\f$ which allows to benefit 1303 * model spanned by \f$\rho\f$ and \f$\omega\f$ which allows to benefit
@@ -1436,14 +1434,6 @@ double GCTAResponseIrf::irf_radial(const GEvent&amp; event, @@ -1436,14 +1434,6 @@ double GCTAResponseIrf::irf_radial(const GEvent&amp; event,
1436 bounds.push_back(transition_point); 1434 bounds.push_back(transition_point);
1437 } 1435 }
1438 1436
1439 - // If the integration range includes a transition between full  
1440 - // containment of Psf within model and partial containment, then  
1441 - // add a boundary at this location  
1442 - transition_point = src_max - delta_max;  
1443 - if (transition_point > rho_min && transition_point < rho_max) {  
1444 - bounds.push_back(transition_point);  
1445 - }  
1446 -  
1447 // If we have a shell model then add an integration boundary for the 1437 // If we have a shell model then add an integration boundary for the
1448 // shell radius as a function discontinuity will occur at this 1438 // shell radius as a function discontinuity will occur at this
1449 // location 1439 // location
@@ -1498,7 +1488,7 @@ double GCTAResponseIrf::irf_radial(const GEvent&amp; event, @@ -1498,7 +1488,7 @@ double GCTAResponseIrf::irf_radial(const GEvent&amp; event,
1498 1488
1499 1489
1500 /***********************************************************************//** 1490 /***********************************************************************//**
1501 - * @brief Return IRF value for elliptical source model 1491 + * @brief Return Irf value for elliptical source model
1502 * 1492 *
1503 * @param[in] event Observed event. 1493 * @param[in] event Observed event.
1504 * @param[in] source Source. 1494 * @param[in] source Source.
inst/cta/src/GCTAResponse_helpers.cpp
@@ -692,7 +692,7 @@ double cta_irf_elliptical_kern_rho::eval(const double&amp; rho) @@ -692,7 +692,7 @@ double cta_irf_elliptical_kern_rho::eval(const double&amp; rho)
692 // If the radius rho is not larger than the semiminor axis 692 // If the radius rho is not larger than the semiminor axis
693 // boundary, the circle with that radius is fully contained in 693 // boundary, the circle with that radius is fully contained in
694 // the ellipse and we can just integrate over the relevant arc 694 // the ellipse and we can just integrate over the relevant arc
695 - if (rho < m_semiminor) { 695 + if (rho <= m_semiminor) {
696 696
697 // Compute omega integration range 697 // Compute omega integration range
698 double omega_min = -domega; 698 double omega_min = -domega;
@@ -984,7 +984,7 @@ double cta_npred_elliptical_kern_rho::eval(const double&amp; rho) @@ -984,7 +984,7 @@ double cta_npred_elliptical_kern_rho::eval(const double&amp; rho)
984 // If the radius rho is not larger than the semiminor axis 984 // If the radius rho is not larger than the semiminor axis
985 // boundary, the circle with that radius is fully contained in 985 // boundary, the circle with that radius is fully contained in
986 // the ellipse and we can just integrate over the relevant arc 986 // the ellipse and we can just integrate over the relevant arc
987 - if (rho < m_semiminor) { 987 + if (rho <= m_semiminor) {
988 988
989 // Compute omega integration range 989 // Compute omega integration range
990 double omega_min = -domega; 990 double omega_min = -domega;
@@ -1699,6 +1699,165 @@ double cta_psf_radial_kern_omega::eval(const double&amp; omega) @@ -1699,6 +1699,165 @@ double cta_psf_radial_kern_omega::eval(const double&amp; omega)
1699 1699
1700 1700
1701 /***********************************************************************//** 1701 /***********************************************************************//**
  1702 + * @brief Kernel for PSF integration of radial model
  1703 + *
  1704 + * @param[in] delta PSF offset angle (radians).
  1705 + * @return Azimuthally integrated product between PSF and radial model.
  1706 + *
  1707 + * Computes the azimuthally integrated product of point spread function and
  1708 + * the radial model intensity. As the PSF is azimuthally symmetric, it is
  1709 + * not included in the azimuthally integration, but just multiplied on the
  1710 + * azimuthally integrated model. The method returns thus
  1711 + *
  1712 + * \f[
  1713 + * {\rm PSF}(\delta) \times
  1714 + * \int_0^{2\pi} {\rm M}(\delta, \phi) \sin \delta {\rm d}\phi
  1715 + * \f]
  1716 + *
  1717 + * where \f${\rm M}(\delta, \phi)\f$ is the radial model in the coordinate
  1718 + * system of the point spread function, defined by the angle \f$\delta\f$
  1719 + * between the true and the measured photon direction and the azimuth angle
  1720 + * \f$\phi\f$ around the measured photon direction.
  1721 + ***************************************************************************/
  1722 +double cta_psf_radial_kern_delta::eval(const double& delta)
  1723 +{
  1724 + // Initialise value
  1725 + double value = 0.0;
  1726 +
  1727 + // If we're at the Psf peak the model is zero (due to the sin(delta)
  1728 + // term. We thus only integrate for positive deltas.
  1729 + if (delta > 0.0) {
  1730 +
  1731 + // Get Psf for this delta
  1732 + double psf = m_rsp->psf()(m_srcDir, delta, m_srcEng);
  1733 +
  1734 + // Continue only if Psf is positive
  1735 + if (psf > 0.0) {
  1736 +
  1737 + // Compute half length of the arc (in radians) from a circle with
  1738 + // radius delta that intersects with the model, defined as a circle
  1739 + // with maximum radius m_theta_max
  1740 + double dphi = 0.5 * gammalib::cta_roi_arclength(delta,
  1741 + m_delta_mod,
  1742 + m_cos_delta_mod,
  1743 + m_sin_delta_mod,
  1744 + m_theta_max,
  1745 + m_cos_theta_max);
  1746 +
  1747 + // Continue only if arc length is positive
  1748 + if (dphi > 0.0) {
  1749 +
  1750 + // Compute phi integration range
  1751 + double phi_min = -dphi;
  1752 + double phi_max = +dphi;
  1753 +
  1754 + // Precompute cosine and sine terms for azimuthal integration
  1755 + double sin_delta = std::sin(delta);
  1756 + double cos_delta = std::cos(delta);
  1757 + double sin_fact = sin_delta * m_sin_delta_mod;
  1758 + double cos_fact = cos_delta * m_cos_delta_mod;
  1759 +
  1760 + // Setup kernel for azimuthal integration of the spatial model
  1761 + cta_psf_radial_kern_phi integrand(m_model,
  1762 + m_srcEng,
  1763 + m_srcTime,
  1764 + sin_fact,
  1765 + cos_fact);
  1766 +
  1767 + // Setup integrator
  1768 + GIntegral integral(&integrand);
  1769 + integral.fixed_iter(m_iter);
  1770 +
  1771 + // Integrate over azimuth
  1772 + value = integral.romberg(phi_min, phi_max, m_iter) *
  1773 + psf * sin_delta;
  1774 +
  1775 + // Debug: Check for NaN
  1776 + #if defined(G_NAN_CHECK)
  1777 + if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
  1778 + std::cout << "*** ERROR: cta_psf_radial_kern_delta::eval";
  1779 + std::cout << "(delta=" << delta << "):";
  1780 + std::cout << " NaN/Inf encountered";
  1781 + std::cout << " (value=" << value;
  1782 + std::cout << ")" << std::endl;
  1783 + }
  1784 + #endif
  1785 +
  1786 + } // endif: Psf value was positive
  1787 +
  1788 + } // endif: arc length was positive
  1789 +
  1790 + } // endif: delta was positive
  1791 +
  1792 + // Return kernel value
  1793 + return value;
  1794 +}
  1795 +
  1796 +
  1797 +/***********************************************************************//**
  1798 + * @brief Kernel for azimuthal radial model integration
  1799 + *
  1800 + * @param[in] phi Azimuth angle (radians).
  1801 + * @return Radial model value.
  1802 + *
  1803 + * Computes the value of the radial model at the position \f$(\delta,\phi)\f$
  1804 + * given in point spread function coordinates. The \f$\theta\f$ angle of the
  1805 + * radial model is computed using
  1806 + *
  1807 + * \f[
  1808 + * \theta = \arccos \left( \cos \delta \cos \zeta +
  1809 + * \sin \delta \sin \zeta \cos \phi \right)
  1810 + * \f]
  1811 + *
  1812 + * where \f$\delta\f$ is the angle between true and measured photon
  1813 + * direction, \f$\zeta\f$ is the angle between model centre and measured
  1814 + * photon direction, and \f$\phi\f$ is the azimuth angle with respect to the
  1815 + * measured photon direction, where \f$\phi=0\f$ corresponds to the
  1816 + * connecting line between model centre and measured photon direction.
  1817 + ***************************************************************************/
  1818 +double cta_psf_radial_kern_phi::eval(const double& phi)
  1819 +{
  1820 + // Compute radial model theta angle
  1821 + double theta = std::acos(m_cos_fact + m_sin_fact * std::cos(phi));
  1822 +
  1823 + // Reduce theta by an infinite amount to avoid rounding errors at the
  1824 + // boundary of a sharp edged model
  1825 + double theta_kluge = theta - 1.0e-12;
  1826 + if (theta_kluge < 0.0) {
  1827 + theta_kluge = 0.0;
  1828 + }
  1829 +
  1830 + // Get radial model value
  1831 + double value = m_model->eval(theta_kluge, m_srcEng, m_srcTime);
  1832 +
  1833 + // Debug: test if model is non positive
  1834 + #if defined(G_DEBUG_MODEL_ZERO)
  1835 + if (value <= 0.0) {
  1836 + std::cout << "*** WARNING: cta_psf_radial_kern_phi::eval";
  1837 + std::cout << " zero model for (phi)=(";
  1838 + std::cout << phi*gammalib::rad2deg << ")";
  1839 + std::cout << " theta-r_model=" << (theta-m_model->theta_max());
  1840 + std::cout << " radians" << std::endl;
  1841 + }
  1842 + #endif
  1843 +
  1844 + // Debug: Check for NaN
  1845 + #if defined(G_NAN_CHECK)
  1846 + if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
  1847 + std::cout << "*** ERROR: cta_psf_radial_kern_phi::eval";
  1848 + std::cout << "(phi=" << phi << "):";
  1849 + std::cout << " NaN/Inf encountered";
  1850 + std::cout << " (value=" << value;
  1851 + std::cout << ")" << std::endl;
  1852 + }
  1853 + #endif
  1854 +
  1855 + // Return kernel value
  1856 + return value;
  1857 +}
  1858 +
  1859 +
  1860 +/***********************************************************************//**
1702 * @brief Kernel for elliptical model integration over zenith angle 1861 * @brief Kernel for elliptical model integration over zenith angle
1703 * 1862 *
1704 * @param[in] rho Radial distance from model centre (radians). 1863 * @param[in] rho Radial distance from model centre (radians).
@@ -1777,7 +1936,7 @@ double cta_psf_elliptical_kern_rho::eval(const double&amp; rho) @@ -1777,7 +1936,7 @@ double cta_psf_elliptical_kern_rho::eval(const double&amp; rho)
1777 // If the radius rho is not larger than the semiminor axis 1936 // If the radius rho is not larger than the semiminor axis
1778 // boundary, the circle with that radius is fully contained in 1937 // boundary, the circle with that radius is fully contained in
1779 // the ellipse and we can just integrate over the relevant arc 1938 // the ellipse and we can just integrate over the relevant arc
1780 - if (rho < m_semiminor) { 1939 + if (rho <= m_semiminor) {
1781 1940
1782 // Compute omega integration range 1941 // Compute omega integration range
1783 double omega_min = -domega; 1942 double omega_min = -domega;
inst/cta/src/GCTAResponse_helpers.hpp
@@ -1091,6 +1091,75 @@ public: @@ -1091,6 +1091,75 @@ public:
1091 1091
1092 1092
1093 /***********************************************************************//** 1093 /***********************************************************************//**
  1094 + * @class cta_psf_radial_kern_delta
  1095 + *
  1096 + * @brief Kernel for Psf delta angle integration used for stacked analysis
  1097 + ***************************************************************************/
  1098 +class cta_psf_radial_kern_delta : public GFunction {
  1099 +public:
  1100 + cta_psf_radial_kern_delta(const GCTAResponseCube* rsp,
  1101 + const GModelSpatialRadial* model,
  1102 + const GSkyDir& srcDir,
  1103 + const GEnergy& srcEng,
  1104 + const GTime& srcTime,
  1105 + const double& delta_mod,
  1106 + const double& theta_max,
  1107 + const int& iter) :
  1108 + m_rsp(rsp),
  1109 + m_model(model),
  1110 + m_srcDir(srcDir),
  1111 + m_srcEng(srcEng),
  1112 + m_srcTime(srcTime),
  1113 + m_delta_mod(delta_mod),
  1114 + m_cos_delta_mod(std::cos(delta_mod)),
  1115 + m_sin_delta_mod(std::sin(delta_mod)),
  1116 + m_theta_max(theta_max),
  1117 + m_cos_theta_max(std::cos(theta_max)),
  1118 + m_iter(iter) { }
  1119 + double eval(const double& delta);
  1120 +protected:
  1121 + const GCTAResponseCube* m_rsp; //!< Response cube
  1122 + const GModelSpatialRadial* m_model; //!< Radial model
  1123 + const GSkyDir& m_srcDir; //!< True photon arrival direction
  1124 + const GEnergy& m_srcEng; //!< True photon energy
  1125 + const GTime& m_srcTime; //!< True photon arrival time
  1126 + const double& m_delta_mod; //!< Distance of model from Psf
  1127 + double m_cos_delta_mod; //!< Cosine of m_delta_mod
  1128 + double m_sin_delta_mod; //!< Sine of m_delta_mod
  1129 + const double& m_theta_max; //!< Maximum model radius
  1130 + double m_cos_theta_max; //!< Cosine of m_theta_max
  1131 + const int& m_iter; //!< Integration iterations
  1132 +};
  1133 +
  1134 +
  1135 +/***********************************************************************//**
  1136 + * @class cta_psf_radial_kern_phi
  1137 + *
  1138 + * @brief Kernel for Psf phi angle integration used for stacked analysis
  1139 + ***************************************************************************/
  1140 +class cta_psf_radial_kern_phi : public GFunction {
  1141 +public:
  1142 + cta_psf_radial_kern_phi(const GModelSpatialRadial* model,
  1143 + const GEnergy& srcEng,
  1144 + const GTime& srcTime,
  1145 + const double& sin_fact,
  1146 + const double& cos_fact) :
  1147 + m_model(model),
  1148 + m_srcEng(srcEng),
  1149 + m_srcTime(srcTime),
  1150 + m_sin_fact(sin_fact),
  1151 + m_cos_fact(cos_fact) { }
  1152 + double eval(const double& phi);
  1153 +protected:
  1154 + const GModelSpatialRadial* m_model; //!< Radial model
  1155 + const GEnergy& m_srcEng; //!< True photon energy
  1156 + const GTime& m_srcTime; //!< True photon arrival time
  1157 + const double& m_sin_fact; //!< sin(delta)*sin(delta_mod)
  1158 + const double& m_cos_fact; //!< cos(delta)*cos(delta_mod)
  1159 +};
  1160 +
  1161 +
  1162 +/***********************************************************************//**
1094 * @class cta_irf_elliptical_kern_rho 1163 * @class cta_irf_elliptical_kern_rho
1095 * 1164 *
1096 * @brief Kernel for elliptical model zenith angle integration 1165 * @brief Kernel for elliptical model zenith angle integration
inst/cta/test/test_irf_radial.py
@@ -210,18 +210,19 @@ if __name__ == &#39;__main__&#39;: @@ -210,18 +210,19 @@ if __name__ == &#39;__main__&#39;:
210 sys.exit() 210 sys.exit()
211 211
212 # Set Psf size 212 # Set Psf size
213 - delta_max = 0.6 213 + delta_max = 0.8
214 214
215 # Set model parameters 215 # Set model parameters
216 centre = gammalib.GSkyDir() 216 centre = gammalib.GSkyDir()
217 centre.radec_deg(0.0, 0.0) 217 centre.radec_deg(0.0, 0.0)
218 - radius = 0.8 218 + radius = 1.0
219 219
220 # Set observed photon direction 220 # Set observed photon direction
221 obsDir = gammalib.GSkyDir() 221 obsDir = gammalib.GSkyDir()
222 - obsDir.radec_deg(0.4, -0.3) 222 + #obsDir.radec_deg(0.4, -0.3)
223 #obsDir.radec_deg(-0.4, -0.3) 223 #obsDir.radec_deg(-0.4, -0.3)
224 #obsDir.radec_deg(0.4, 0.4) 224 #obsDir.radec_deg(0.4, 0.4)
  225 + obsDir.radec_deg(0.0, 0.3)
225 226
226 # Show elliptical response geometry 227 # Show elliptical response geometry
227 show_response(centre, radius, obsDir, delta_max) 228 show_response(centre, radius, obsDir, delta_max)
inst/cta/test/test_likelihood_profile.py
@@ -82,7 +82,7 @@ def show_likelihood_profile(result): @@ -82,7 +82,7 @@ def show_likelihood_profile(result):
82 # ========================== # 82 # ========================== #
83 # Compute likelihood profile # 83 # Compute likelihood profile #
84 # ========================== # 84 # ========================== #
85 -def compute_likelihood_profile(obs, parname="RA", scale=1.0e-4, steps=10): 85 +def compute_likelihood_profile(obs, parname="Radius", scale=1.0e-5, steps=10):
86 """ 86 """
87 Compute the log-likelihood profile for a given parameter. 87 Compute the log-likelihood profile for a given parameter.
88 88
@@ -93,12 +93,12 @@ def compute_likelihood_profile(obs, parname=&quot;RA&quot;, scale=1.0e-4, steps=10): @@ -93,12 +93,12 @@ def compute_likelihood_profile(obs, parname=&quot;RA&quot;, scale=1.0e-4, steps=10):
93 """ 93 """
94 # Free parameter for which profile is to be determined 94 # Free parameter for which profile is to be determined
95 obs.models()[0][parname].free() 95 obs.models()[0][parname].free()
96 - obs.models()[0]["DEC"].free()  
97 96
98 # Allocate Levenberg-Marquardt optimizer 97 # Allocate Levenberg-Marquardt optimizer
99 log = gammalib.GLog() 98 log = gammalib.GLog()
100 log.cout(True) 99 log.cout(True)
101 opt = gammalib.GOptimizerLM(log) 100 opt = gammalib.GOptimizerLM(log)
  101 + opt.eps(5.0e-3)
102 102
103 # Optimize model parameters 103 # Optimize model parameters
104 obs.optimize(opt) 104 obs.optimize(opt)
@@ -256,8 +256,8 @@ if __name__ == &#39;__main__&#39;: @@ -256,8 +256,8 @@ if __name__ == &#39;__main__&#39;:
256 256
257 # Set test 257 # Set test
258 #test = "point" 258 #test = "point"
259 - test = "gauss"  
260 - #test = "disk" 259 + #test = "gauss"
  260 + test = "disk"
261 #test = "ldisk" 261 #test = "ldisk"
262 #test = "shell" 262 #test = "shell"
263 #test = "ellipse" 263 #test = "ellipse"
@@ -309,10 +309,10 @@ if __name__ == &#39;__main__&#39;: @@ -309,10 +309,10 @@ if __name__ == &#39;__main__&#39;:
309 cntref = 337.5 # +/- 1.8 (from ctobssim) 309 cntref = 337.5 # +/- 1.8 (from ctobssim)
310 310
311 # Perform unbinned computation 311 # Perform unbinned computation
312 - original_likelihood_profile(model, events, irf, gammalib.GCaldb(caldb), cntref) 312 + #original_likelihood_profile(model, events, irf, gammalib.GCaldb(caldb), cntref)
313 313
314 # Perform binned computation 314 # Perform binned computation
315 #original_likelihood_profile(model, cntmap, irf, gammalib.GCaldb(caldb), cntref) 315 #original_likelihood_profile(model, cntmap, irf, gammalib.GCaldb(caldb), cntref)
316 316
317 # Perform stacked computation 317 # Perform stacked computation
318 - #stacked_likelihood_profile(model, cntmap, expcube, psfcube, cntref) 318 + stacked_likelihood_profile(model, cntmap, expcube, psfcube, cntref)
inst/cta/test/test_npred_elliptical.py
@@ -279,7 +279,7 @@ def show_response(centre, semimajor, semiminor, posang, roiDir, pntDir, roi_radi @@ -279,7 +279,7 @@ def show_response(centre, semimajor, semiminor, posang, roiDir, pntDir, roi_radi
279 if (domega > 0.0): 279 if (domega > 0.0):
280 280
281 # Full containment within ellipse 281 # Full containment within ellipse
282 - if (rho < bound_minor): 282 + if (rho <= bound_minor):
283 283
284 # Compute phi integration range 284 # Compute phi integration range
285 omega_min = -domega 285 omega_min = -domega
@@ -400,17 +400,16 @@ if __name__ == &#39;__main__&#39;: @@ -400,17 +400,16 @@ if __name__ == &#39;__main__&#39;:
400 # Set model parameters 400 # Set model parameters
401 centre = gammalib.GSkyDir() 401 centre = gammalib.GSkyDir()
402 centre.radec_deg(0.0, 0.0) 402 centre.radec_deg(0.0, 0.0)
403 - #semimajor = 1.0  
404 - #semiminor = 0.50  
405 - semiminor = 1.0  
406 - semimajor = 0.50  
407 - posang = 310.0 403 + semimajor = 1.0
  404 + semiminor = 0.50
  405 + posang = 30.0
408 406
409 # Set ROI direction 407 # Set ROI direction
410 roiDir = gammalib.GSkyDir() 408 roiDir = gammalib.GSkyDir()
411 - #roiDir.radec_deg(-0.4, -0.3)  
412 - roiDir.radec_deg(+0.4, -0.3) 409 + roiDir.radec_deg(-0.4, -0.3)
  410 + #roiDir.radec_deg(+0.4, -0.3)
413 #roiDir.radec_deg(+0.4, +0.3) 411 #roiDir.radec_deg(+0.4, +0.3)
  412 + #roiDir.radec_deg(0.0, 0.1)
414 413
415 # Set pointing direction 414 # Set pointing direction
416 pntDir = gammalib.GSkyDir() 415 pntDir = gammalib.GSkyDir()