Passed
Push — master ( 573345...9597ff )
by Giacomo
06:15
created

hal_fit_point_source   A

Complexity

Total Complexity 0

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 0
eloc 82
dl 0
loc 140
rs 10
c 0
b 0
f 0
1
#!/usr/bin/env python
2
3
# If ROOT is active, we need to skip its own command line parsing
4
try:
5
6
    import ROOT
7
    ROOT.PyConfig.IgnoreCommandLineOptions = True
8
9
except ImportError:
10
11
    pass
12
13
try:
14
    from hawc import hawcnest
15
16
    hawcnest.SetLoggingLevel(2, True)
17
18
except ImportError:
19
20
    pass
21
22
import argparse
23
import astropy.units as u
24
25
from hawc_hal.convenience_functions.fit_point_source import fit_point_source
26
from hawc_hal import HealpixConeROI
27
28
import astromodels
29
from astromodels import PointSource, Model
30
from threeML import plot_point_source_spectra
31
32
import pandas as pd
33
pd.options.display.max_columns = 80
34
35
36
if __name__ == "__main__":
37
38
    help = """
39
    
40
    Example:
41
        
42
        - Fit the Crab with a power law spectrum starting from a normalization of 2.6e-11 TeV^-1 cm^-2 s^-1 and a 
43
          photon index of -2.0:
44
            
45
            > hal_fit_point_source.py --ra 83.633080 --dec 22.01450 --spectrum Powerlaw --params 'K=2.6e-11 1 / (TeV cm2 s), index=-2.0'
46
    
47
    """
48
49
    parser = argparse.ArgumentParser(description='bla', epilog=help)
50
51
    parser.add_argument("--ra_roi", help="R.A. of center of ROI", type=float, required=False, default=None)
52
    parser.add_argument("--dec_roi", help="Dec of center of ROI", type=float, required=False, default=None)
53
    parser.add_argument("--ra", help="R.A. of source", type=float, required=True, default=None)
54
    parser.add_argument("--dec", help="Dec of source", type=float, required=True, default=None)
55
    parser.add_argument("--data_radius", help="Radius for data selection", type=float, required=False, default=3.0)
56
    parser.add_argument("--model_radius", help="Radius for model computation", type=float, required=False, default=8.0)
57
    parser.add_argument("--pixel_size", help="Size of the 'flat sky' pixels", type=float, required=False, default=0.17)
58
    parser.add_argument("--maptree", help="Path to maptree (root or hd5)", type=str, required=True)
59
    parser.add_argument("--response", help="Path to response (root or hd5)", type=str, required=True)
60
    parser.add_argument("--spectrum", help="Spectral model, for example Powerlaw. "
61
                                           "Any astromodels function is accepted",
62
                        required=False, default='Power_law')
63
    parser.add_argument("--params", help="Parameter specification. For example, for the Power_law spectrum, "
64
                                         "you can use: '2e.5e-11 1/(TeV cm2 s)' '-2.0'", required=True)
65
    parser.add_argument("--bin_list", help="Bin list to use for analysis", required=False,
66
                        default=map(str, range(1, 10)),
67
                        nargs='+')
68
    parser.add_argument("--display_model", help="Whether to display or not the model before fitting",
69
                        action="store_true", default=False)
70
    parser.add_argument("--use_liff", help="Use LiFF instead of HAL",
71
                        action="store_true", default=False)
72
    parser.add_argument("--confidence_intervals",
73
                        help="Compute confidence intervals with the profile likelihood method",
74
                        action="store_true", default=False)
75
    parser.add_argument("--verbose",
76
                        help="Print all the steps of the likelihood maximization",
77
                        action="store_true", default=False)
78
    parser.add_argument("--spectrum_plot",
79
                        help="Name for output spectrum file (.png). If not provided, no plot will be made",
80
                        type=str, required=False,
81
                        default=None)
82
83
    args = parser.parse_args()
84
85
    if args.ra_roi is None:
86
87
        args.ra_roi = args.ra
88
89
    if args.dec_roi is None:
90
91
        args.dec_roi = args.dec
92
93
    roi = HealpixConeROI(args.data_radius, args.model_radius, ra=args.ra_roi, dec=args.dec_roi)
94
95
    # Build point source model
96
97
    # Get spectrum function
98
    spectrum = astromodels.get_function_class(args.spectrum)()
99
100
    src = PointSource("pts", ra=args.ra, dec=args.dec, spectral_shape=spectrum)
101
102
    model = Model(src)
103
104
    # Parse parameters
105
    tokens = args.params.split(",")
106
107
    for token in tokens:
108
109
        key, value = token.split("=")
110
111
        # The path of this parameter in the final model will be:
112
        path = "pts.spectrum.main.%s.%s" % (args.spectrum, key.strip())
113
114
        assert path in model, "Could not find parameter %s in function %s" % (key, args.spectrum)
115
116
        p = model[path]
117
118
        p.value = u.Quantity(value)
119
120
        if p.is_normalization:
121
122
            p.bounds = (p.value / 100.0, p.value * 100)
123
124
    if args.display_model:
125
126
        model.display()
127
128
    param_df, like_df, ci, results = fit_point_source(roi, args.maptree, args.response, model, args.bin_list,
129
                                                      args.confidence_intervals,
130
                                                      args.use_liff, args.pixel_size, args.verbose)
131
132
    if args.spectrum_plot is not None:
133
134
        fig = plot_point_source_spectra(results,
135
                                        ene_min=0.1 * u.TeV, ene_max=100 * u.TeV,
136
                                        flux_unit='erg/(cm2 s)',
137
                                        show_legend=False)
138
139
        fig.savefig(args.spectrum_plot)
140