ctools 2.1.0.dev
Loading...
Searching...
No Matches
csmodelinfo.py
Go to the documentation of this file.
1#!/usr/bin/env python
2# ==========================================================================
3# Shows the content of a model container
4#
5# Copyright (C) 2015-2022 Michael Mayer
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# ==========================================================================
21import sys
22import gammalib
23import ctools
24from cscripts import modutils
25
26
27# ================= #
28# csmodelinfo class #
29# ================= #
30class csmodelinfo(ctools.cscript):
31 """
32 Shows the content of a model container
33
34 The script is useful to show, e.g., the number of sources in a model
35 container, the background models, free and fixed parameters etc.
36 The script can also dump the models into a region file to for display
37 with DS9.
38 """
39
40 # Constructor
41 def __init__(self, *argv):
42 """
43 Constructor
44 """
45 # Initialise application by calling the base class constructor
46 self._init_cscript(self.__class__.__name__, ctools.__version__, argv)
47
48 # Initialise class members
49 self._models = gammalib.GModels()
50
51 # Return
52 return
53
54
55 # Private methods
56 def _get_parameters(self):
57 """
58 Get parameters from parfile and setup the observation
59 """
60 # Get models
61 self._models = gammalib.GModels(self['inmodel'].filename())
62
63 # Query hidden parameters for region file
64 self['pnt_type'].string()
65 self['pnt_mark_size'].integer()
66 self['show_labels'].boolean()
67 self['width'].integer()
68 self['fontfamily'].string()
69 self['fontsize'].integer()
70 self['fontweight'].string()
71 self['fontslant'].string()
72 self['show_ext_type'].boolean()
73 self['free_color'].string()
74 self['fixed_color'].string()
75
76 # Query ahead DS9 filename
77 if self._read_ahead():
78 self['outds9file'].query()
79
80 # Write input parameters into logger
81 self._log_parameters(gammalib.TERSE)
82
83 # Return
84 return
85
86
87 # Public methods
88 def process(self):
89 """
90 Process the script
91 """
92 # Get parameters
93 self._get_parameters()
94
95 # Optionally log models
96 if self._logVerbose():
97 self._log('\n')
98 self._log.header1('Models')
99 self._log('\n')
100 self._log(str(self._models))
101 self._log('\n')
102
103 # Initialise output values
104 types = {}
105 instruments = {}
106 ts = {}
107 pars_at_limit = {}
108 free_src_pars = {}
109 n_par_total = 0
110 n_par_free = 0
111 n_par_fixed = 0
112 n_par_at_limit = 0
113 n_par_free_bkg = 0
114 n_par_free_src = 0
115 n_par_free_spec = 0
116 n_par_free_spat = 0
117 n_par_free_temp = 0
118
119 # Loop over models and initialise dictionaries with model names
120 for model in self._models:
121 types[model.type()] = 0
122 instruments[model.instruments()] = 0
123 pars_at_limit[model.name()] = []
124
125 # Loop over models again and fill values to be dumped
126 for model in self._models:
127
128 # Model types
129 types[model.type()] += 1
130
131 # Model instruments
132 instruments[model.instruments()] += 1
133
134 # TS
135 if model.has_ts():
136 ts[model.name()] = model.ts()
137
138 # Skymodel?
139 skymodel = (model.classname() == 'GModelSky')
140 if skymodel:
141 free_src_pars[model.name()] = []
142
143 # Loop over model parameters
144 for par in model:
145
146 # Increment total parameters
147 n_par_total += 1
148
149 # Check if parameter is at limit
150 if par.has_range():
151 if par.value() == par.min() or par.value() == par.max():
152 pars_at_limit[model.name()].append(par.name())
153 n_par_at_limit += 1
154
155 # Check if model parameter is free/fixed and
156 # increment respective variable
157 if par.is_free():
158 n_par_free += 1
159 if skymodel:
160 free_src_pars[model.name()].append(par)
161 n_par_free_src += 1
162 else:
163 n_par_free_bkg += 1
164 else:
165 n_par_fixed += 1
166
167 # If sky model, divide free parameters into spatial, spectral
168 # and temporal
169 if skymodel:
170 for par in model.spectral():
171 if par.is_free():
172 n_par_free_spec += 1
173 for par in model.spatial():
174 if par.is_free():
175 n_par_free_spat += 1
176 for par in model.temporal():
177 if par.is_free():
178 n_par_free_temp += 1
179
180 # Optionally log model information
181 if self._logTerse():
182
183 # Log summary
184 self._log_header1(gammalib.TERSE, 'Summary')
185
186 # Log instruments
187 self._log.header3('Instrument specific models')
188 for inst, n_inst in instruments.items():
189 if inst == '':
190 inst = 'All'
191 self._log_value(gammalib.TERSE, inst, n_inst)
192
193 # Log model types
194 self._log_header3(gammalib.TERSE, 'Model types')
195 for modeltype, n_types in types.items():
196 self._log_value(gammalib.TERSE, modeltype, n_types)
197
198 # Log model parameter information
199 self._log_header1(gammalib.TERSE,'Parameter information')
200 self._log_value(gammalib.TERSE,'All parameters', n_par_total)
201 self._log_value(gammalib.TERSE,'Fixed parameters', n_par_fixed)
202 self._log_value(gammalib.TERSE,'Free parameters (total)', n_par_free)
203 self._log_value(gammalib.TERSE,'Free background parameters', n_par_free_bkg)
204 self._log_value(gammalib.TERSE,'Free source parameters', n_par_free_src)
205 if n_par_free_spec > 0:
206 self._log_value(gammalib.TERSE,'Free spectral parameters', n_par_free_spec)
207 if n_par_free_spat > 0:
208 self._log_value(gammalib.TERSE,'Free spatial parameters', n_par_free_spat)
209 if n_par_free_temp > 0:
210 self._log_value(gammalib.TERSE,'Free temporal parameters', n_par_free_temp)
211 self._log_value(gammalib.TERSE,'Parameters at limit', n_par_at_limit)
212
213 # Log parameters at limit (if any)
214 if n_par_at_limit > 0:
215 self._log_header3(gammalib.TERSE, 'Parameters at limit')
216 for source, parameter in pars_at_limit.items():
217 if len(parameter):
218 for par in parameter:
219 self._log_value(gammalib.TERSE, source, par)
220
221 # Optionally log free parameters
222 if len(free_src_pars):
223 self._log_header2(gammalib.EXPLICIT, 'Free source parameters')
224 for source, parameter in free_src_pars.items():
225 if len(parameter):
226 self._log.header3(source)
227 for par in parameter:
228 self._log_string(gammalib.EXPLICIT, str(par)+'\n')
229
230 # Log TS values if available
231 if len(ts):
232 self._log_header3(gammalib.TERSE, 'Test statistics')
233 for source, tsvalue in ts.items():
234 self._log_value(gammalib.TERSE, source, tsvalue)
235
236 # Return
237 return
238
239 def save(self):
240 """
241 Save models to ds9 region file
242 """
243 # Check if DS9 file is valid
244 if self['outds9file'].is_valid():
245
246 # Get output filename
247 ds9file = self['outds9file'].filename()
248
249 # Write header
250 self._log_header1(gammalib.TERSE, 'Save models in DS9 file')
251
252 # Log filename
253 self._log_value(gammalib.NORMAL, 'DS9 filename', ds9file.url())
254
255 # Get ds9 parameters
256 pnt_type = self['pnt_type'].string()
257 pnt_mark_size = self['pnt_mark_size'].integer()
258 show_labels = self['show_labels'].boolean()
259 free_color = self['free_color'].string()
260 fixed_color = self['fixed_color'].string()
261 width = self['width'].integer()
262 fontfamily = self['fontfamily'].string()
263 fontsize = self['fontsize'].integer()
264 fontweight = self['fontweight'].string()
265 fontslant = self['fontslant'].string()
266
267 # Save DS9 region file
268 errors = modutils.models2ds9file(self._models, ds9file.url(),
269 pnt_type=pnt_type,
270 pnt_mark_size=pnt_mark_size,
271 show_labels=show_labels,
272 free_color=free_color,
273 fixed_color=fixed_color,
274 width=width,
275 fontfamily=fontfamily,
276 fontsize=fontsize,
277 fontweight=fontweight,
278 fontslant=fontslant)
279
280 # Log errors
281 if len(errors):
282 self._log(errors)
283
284 # Return
285 return
286
287
288# ======================== #
289# Main routine entry point #
290# ======================== #
291if __name__ == '__main__':
292
293 # Create instance of application
294 app = csmodelinfo(sys.argv)
295
296 # Execute application
297 app.execute()