ctools  2.0.0
 All Classes Namespaces Files Functions Variables Macros Pages
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 # ==========================================================================
21 import sys
22 import gammalib
23 import ctools
24 from cscripts import modutils
25 
26 
27 # ================= #
28 # csmodelinfo class #
29 # ================= #
30 class 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 # ======================== #
291 if __name__ == '__main__':
292 
293  # Create instance of application
294  app = csmodelinfo(sys.argv)
295 
296  # Execute application
297  app.execute()