Commit 31d34ecd3763ff910d5d3f6322291a99d13fced2
1 parent
f9342fcb
Add "POW" energy binning to ctool::create_energies() method and csbkgmodel script
Showing
4 changed files
with
61 additions
and
8 deletions
cscripts/csbkgmodel.par
| ... | ... | @@ -31,11 +31,12 @@ smin, r, a, 0.1,,, "Lower energy limit of energy nodes for GAUSS(E) spatia |
| 31 | 31 | smax, r, a, 10.0,,, "Upper energy limit of energy nodes for GAUSS(E) spatial model (TeV)" |
| 32 | 32 | gradient, b, a, yes,,, "Allow for spatial gradient?" |
| 33 | 33 | spectral, s, a, NODES,PLAW|NODES,, "Spectral model component" |
| 34 | -ebinalg, s, a, LOG,FILE|LIN|LOG,, "Algorithm for defining spectral energy nodes" | |
| 34 | +ebinalg, s, a, LOG,FILE|LIN|LOG|POW,, "Algorithm for defining spectral energy nodes" | |
| 35 | 35 | emin, r, a, 0.1,,, "Lower energy limit (TeV)" |
| 36 | 36 | emax, r, a, 100.0,,, "Upper energy limit (TeV)" |
| 37 | 37 | enumbins, i, a, 8,1,200, "Number of spectral energy nodes" |
| 38 | 38 | ebinfile, f, a, NONE,,, "Name of the file containing the energy node definition" |
| 39 | +ebingamma, r, a, 1.0,,, "Exponent for POW energy node definition" | |
| 39 | 40 | runwise, b, a, yes,,, "Generate runwise background model?" |
| 40 | 41 | rad, r, h, 2.0,,, "Radius for event selection (degrees)" |
| 41 | 42 | ... | ... |
cscripts/csspec.py
| ... | ... | @@ -652,7 +652,7 @@ class csspec(ctools.csobservation): |
| 652 | 652 | 'Npred': 0.0} |
| 653 | 653 | |
| 654 | 654 | # Write header for fitting |
| 655 | - self._log_header3(gammalib.EXPLICIT, 'Performing fit') | |
| 655 | + self._log_header3(gammalib.EXPLICIT, 'Performing fit in energy bin') | |
| 656 | 656 | |
| 657 | 657 | # Setup maximum likelihood fit |
| 658 | 658 | like = ctools.ctlike(obs) |
| ... | ... | @@ -667,6 +667,9 @@ class csspec(ctools.csobservation): |
| 667 | 667 | # Perform maximum likelihood fit |
| 668 | 668 | like.run() |
| 669 | 669 | |
| 670 | + # Write model results for explicit chatter level | |
| 671 | + self._log_string(gammalib.EXPLICIT, str(like.obs().models())) | |
| 672 | + | |
| 670 | 673 | # Continue only if log-likelihood is non-zero |
| 671 | 674 | if like.obs().logL() != 0.0: |
| 672 | 675 | |
| ... | ... | @@ -688,7 +691,8 @@ class csspec(ctools.csobservation): |
| 688 | 691 | if self['calc_ulim'].boolean(): |
| 689 | 692 | |
| 690 | 693 | # Logging information |
| 691 | - self._log_header3(gammalib.EXPLICIT, 'Computing upper limit') | |
| 694 | + self._log_header3(gammalib.EXPLICIT, | |
| 695 | + 'Computing upper limit for energy bin') | |
| 692 | 696 | |
| 693 | 697 | # Create upper limit object |
| 694 | 698 | ulimit = ctools.ctulimit(like.obs()) |
| ... | ... | @@ -801,7 +805,7 @@ class csspec(ctools.csobservation): |
| 801 | 805 | self._log_header1(gammalib.TERSE, 'Generate spectrum') |
| 802 | 806 | |
| 803 | 807 | # Write header for fitting |
| 804 | - self._log_header3(gammalib.EXPLICIT, 'Performing fit') | |
| 808 | + self._log_header3(gammalib.EXPLICIT, 'Performing model fit') | |
| 805 | 809 | |
| 806 | 810 | # Perform maximum likelihood fit |
| 807 | 811 | like = ctools.ctlike(self.obs()) |
| ... | ... | @@ -816,6 +820,9 @@ class csspec(ctools.csobservation): |
| 816 | 820 | spectrum = model.spectral() |
| 817 | 821 | logL0 = like.obs().logL() |
| 818 | 822 | |
| 823 | + # Write model results for explicit chatter level | |
| 824 | + self._log_string(gammalib.EXPLICIT, str(like.obs().models())) | |
| 825 | + | |
| 819 | 826 | # Loop over all nodes |
| 820 | 827 | for i in range(spectrum.nodes()): |
| 821 | 828 | |
| ... | ... | @@ -844,7 +851,9 @@ class csspec(ctools.csobservation): |
| 844 | 851 | if self['calc_ulim'].boolean(): |
| 845 | 852 | |
| 846 | 853 | # Logging information |
| 847 | - self._log_header3(gammalib.EXPLICIT, 'Computing upper limit') | |
| 854 | + self._log_header3(gammalib.EXPLICIT, | |
| 855 | + 'Computing upper limit for node energy %f TeV' % | |
| 856 | + result['energy']) | |
| 848 | 857 | |
| 849 | 858 | # Copy observation container |
| 850 | 859 | obs = like.obs().copy() | ... | ... |
doc/source/users/reference_manual/csbkgmodel.rst
| ... | ... | @@ -75,11 +75,17 @@ General parameters |
| 75 | 75 | Spectral model component. ``PLAW`` specifies a simple power law model, |
| 76 | 76 | ``NODES`` specifies a piecewise broken power-law. |
| 77 | 77 | |
| 78 | -``ebinalg <FILE|LIN|LOG> [string]`` | |
| 78 | +``ebinalg <FILE|LIN|LOG|POW> [string]`` | |
| 79 | 79 | Algorithm for defining energy nodes. For ``FILE``, the energy nodes are |
| 80 | 80 | defined in a FITS file that is specified by the ``ebinfile`` parameter, |
| 81 | 81 | for ``LIN`` and ``LOG`` there will be ``enumbins`` energy nodes spaced |
| 82 | 82 | linearly or logarithmically between ``emin`` and ``emax``, respectively. |
| 83 | + For ``POW`` a spacing with ``enumbins`` nodes between ``emin`` and ``emax`` | |
| 84 | + will be defined so that the integral over a power law with a spectral index | |
| 85 | + defined by the parameter ``ebingamma`` will be constant. A value of | |
| 86 | + ``ebingamma=1`` correspond to the ``LOG`` algorithm, a smaller value provides | |
| 87 | + a finer binning for larger energies while a larger value provides a finer | |
| 88 | + binning for smaller energies. | |
| 83 | 89 | |
| 84 | 90 | ``emin [real]`` |
| 85 | 91 | Lower energy limit (in TeV). |
| ... | ... | @@ -88,11 +94,15 @@ General parameters |
| 88 | 94 | Upper energy limit (in TeV). |
| 89 | 95 | |
| 90 | 96 | ``enumbins [integer]`` |
| 91 | - Number of energy nodes if ``LIN`` or ``LOG`` energy algorithms are used. | |
| 97 | + Number of energy nodes if ``LIN``, ``LOG`` or ``POW`` energy algorithms are | |
| 98 | + used. | |
| 92 | 99 | |
| 93 | 100 | ``ebinfile [file]`` |
| 94 | 101 | Name of the file containing the energy node definition if ``ebinalg=FILE``. |
| 95 | 102 | |
| 103 | +``ebingamma [real]`` | |
| 104 | + Power law index for energy node definition if ``ebinalg=POW``. | |
| 105 | + | |
| 96 | 106 | ``runwise [boolean]`` |
| 97 | 107 | Generate runwise background model? If ``yes`` is specified a background |
| 98 | 108 | model component for each observation in the observation definition XML | ... | ... |
src/support/ctool.cpp
| ... | ... | @@ -696,10 +696,11 @@ GEbounds ctool::create_ebounds(void) |
| 696 | 696 | * The following parameters are read: |
| 697 | 697 | * |
| 698 | 698 | * ebinalg - Energy binning algorithm |
| 699 | - * ebinfile - Name of file with energy binning | |
| 699 | + * ebinfile - Name of file with energy binning (if ebinalg == FILE) | |
| 700 | 700 | * emin - Minimum energy (if ebinalg != FILE) |
| 701 | 701 | * emax - Maximum energy (if ebinalg != FILE) |
| 702 | 702 | * enumbins - Number of energy bins (if ebinalg != FILE) |
| 703 | + * ebingamma - Power law index (if ebinalg == POW) | |
| 703 | 704 | ***************************************************************************/ |
| 704 | 705 | GEnergies ctool::create_energies(void) |
| 705 | 706 | { |
| ... | ... | @@ -783,6 +784,38 @@ GEnergies ctool::create_energies(void) |
| 783 | 784 | |
| 784 | 785 | } // endif: ebinalg was "FILE" |
| 785 | 786 | |
| 787 | + // ... otherwise, if energy binning algorithm is of type "POW" (case | |
| 788 | + // sensitive), then set the energy binning according to a power-law | |
| 789 | + else if (ebinalg == "POW") { | |
| 790 | + | |
| 791 | + // Get task parameters | |
| 792 | + double emin = (*this)["emin"].real(); | |
| 793 | + double emax = (*this)["emax"].real(); | |
| 794 | + int enumbins = (*this)["enumbins"].integer(); | |
| 795 | + double ebingamma = (*this)["ebingamma"].real(); | |
| 796 | + | |
| 797 | + // Precomputation | |
| 798 | + double a = 1.0 - ebingamma; | |
| 799 | + double c = (a == 0.0) | |
| 800 | + ? 1.0 / (std::log(emax) - std::log(emin)) | |
| 801 | + : a / (std::pow(emax,a) - std::pow(emin,a)); | |
| 802 | + double b = double(c*(enumbins-1.0)); | |
| 803 | + | |
| 804 | + // Initialise first energy | |
| 805 | + double e = emin; | |
| 806 | + energies.append(GEnergy(e, "TeV")); | |
| 807 | + | |
| 808 | + // Loop over energy bins | |
| 809 | + for (int i = 0; i < enumbins-1; ++i) { | |
| 810 | + double log_e_next = (a == 0.0) | |
| 811 | + ? 1.0/b + std::log(e) | |
| 812 | + : std::log(a/b + std::pow(e,a)) / a; | |
| 813 | + double e_next = std::exp(log_e_next); | |
| 814 | + energies.append(GEnergy(e_next, "TeV")); | |
| 815 | + e = e_next; | |
| 816 | + } | |
| 817 | + } | |
| 818 | + | |
| 786 | 819 | // ... otherwise use a linear or a logarithmically-spaced energy binning |
| 787 | 820 | else { |
| 788 | 821 | ... | ... |