Commit ca5c9a3639442bfb60b00fc48504190056b75040

Authored by Jürgen Knödlseder
1 parent fbba1ce7

Add hidden fix_ext_for_initial parameter

If the hidden fix_ext_for_initial parameter is set to yes the script will fix any spatial extension parameters for the initial fit iteration and then free the fixed parameters for any subsequent iterations. This stabilizes the fit for extended sources.
modules/comscripts/comlixfit.par
... ... @@ -26,14 +26,15 @@ outmodel, f, a, results.xml,,, "Output model definition file"
26 26 #
27 27 # Script parameters
28 28 #==================
29   -max_iter, i, h, 50,1,1000, "Maximum number of SRCLIX iterations"
30   -like_accuracy, r, h, 0.05,1.0e-30,1.0, "Absolute accuracy of maximum likelihood value"
31   -fix_spat_for_ts, b, h, no,,, "Fix spatial parameters for TS computation?"
32   -bkgmethod, s, a, BGDLIXE,PHINOR|BGDLIXA|BGDLIXE,, "Method for background computation"
33   -nrunav, i, h, 3,,, "Number of Chi/Psi bins used for running average"
34   -navgr, i, h, 9,,, "Number of Chi/Psi bins used for averaging"
35   -nincl, i, h, 5,,, "Number of Phibar layers to include"
36   -nexcl, i, h, 0,,, "Number of Phibar layers to exclude"
  29 +max_iter, i, h, 50,1,1000, "Maximum number of SRCLIX iterations"
  30 +like_accuracy, r, h, 0.05,1.0e-30,1.0, "Absolute accuracy of maximum likelihood value"
  31 +fix_spat_for_ts, b, h, no,,, "Fix spatial parameters for TS computation?"
  32 +fix_ext_for_initial, b, h, no,,, "Fix extension parameters for initial fit iteration?"
  33 +bkgmethod, s, a, BGDLIXE,PHINOR|BGDLIXA|BGDLIXE,, "Method for background computation"
  34 +nrunav, i, h, 3,,, "Number of Chi/Psi bins used for running average"
  35 +navgr, i, h, 5,,, "Number of Chi/Psi bins used for averaging"
  36 +nincl, i, h, 5,,, "Number of Phibar layers to include"
  37 +nexcl, i, h, 0,,, "Number of Phibar layers to exclude"
37 38  
38 39 #
39 40 # Standard parameters
... ...
modules/comscripts/comlixfit.py
... ... @@ -39,6 +39,9 @@ class comlixfit(ctools.cslikelihood):
39 39 # Initialise application by calling the base class constructor
40 40 self._init_cslikelihood(self.__class__.__name__, ctools.__version__, argv)
41 41  
  42 + # Initialise members
  43 + self._fixed_pars = []
  44 +
42 45 # Return
43 46 return
44 47  
... ... @@ -59,6 +62,7 @@ class comlixfit(ctools.cslikelihood):
59 62 self['max_iter'].integer()
60 63 self['like_accuracy'].real()
61 64 self['fix_spat_for_ts'].boolean()
  65 + self['fix_ext_for_initial'].boolean()
62 66  
63 67 # Get parameters
64 68 bkgmethod = self['bkgmethod'].string()
... ... @@ -156,6 +160,65 @@ class comlixfit(ctools.cslikelihood):
156 160 # Return
157 161 return
158 162  
  163 + def _fix_ext_pars(self):
  164 + """
  165 + Fix spatial extension parameters
  166 + """
  167 + # Initialise list of fixed parameters
  168 + self._fixed_pars = []
  169 +
  170 + # Set list of spatial extension parameters
  171 + pars = ['Radius', 'Width', 'Sigma', 'PA', 'MajorRadius', 'MinorRadius']
  172 +
  173 + # Loop over all sky models
  174 + for model in self.obs().models():
  175 + if model.classname() == 'GModelSky':
  176 +
  177 + # Loop over all parameters and fix all encountered spatial
  178 + # extension parameters
  179 + for par in pars:
  180 + if model.spatial().has_par(par):
  181 + if model[par].is_free():
  182 +
  183 + # Fix parameter
  184 + model[par].fix()
  185 +
  186 + # Bookkeeping fixed parameters
  187 + fixed = {'name': model.name(), 'par': par}
  188 + self._fixed_pars.append(fixed)
  189 +
  190 + # Log action
  191 + value = '%s[%s]' % (model.name(), par)
  192 + self._log_value(gammalib.EXPLICIT, 'Fixed parameter', value)
  193 +
  194 + # Return
  195 + return
  196 +
  197 + def _free_fixed_ext_pars(self):
  198 + """
  199 + Free fixed spatial extension parameters
  200 + """
  201 + # Continue only if there are fixed spatial extension parameters
  202 + if len(self._fixed_pars) > 0:
  203 +
  204 + # Loop over fixed parameters
  205 + for fixed_par in self._fixed_pars:
  206 +
  207 + # Free parameter
  208 + name = fixed_par['name']
  209 + par = fixed_par['par']
  210 + self.obs().models()[name][par].free()
  211 +
  212 + # Log action
  213 + value = '%s[%s]' % (name, par)
  214 + self._log_value(gammalib.EXPLICIT, 'Free fixed parameter', value)
  215 +
  216 + # Clear list of fixed parameters
  217 + self._fixed_pars = []
  218 +
  219 + # Return
  220 + return
  221 +
159 222 # Public methods
160 223 def run(self):
161 224 """
... ... @@ -179,19 +242,26 @@ class comlixfit(ctools.cslikelihood):
179 242 eps = self['like_accuracy'].real()
180 243 delta = 0.0
181 244  
182   - # Write header
  245 + # Log header
183 246 self._log_header1(gammalib.NORMAL,
184 247 'Iterative maximum likelihood model fitting')
185 248  
186 249 # Loop over iterations
187 250 for iter in range(niter):
188 251  
189   - # Write iteration header
  252 + # Log iteration header
190 253 self._log_header2(gammalib.EXPLICIT, 'Iteration %d' % (iter+1))
191 254  
192 255 # Update observations
193 256 self._update_obs()
194 257  
  258 + # Optionally fix or free fixed spatial extension parameters
  259 + if self['fix_ext_for_initial'].boolean():
  260 + if iter == 0:
  261 + self._fix_ext_pars()
  262 + else:
  263 + self._free_fixed_ext_pars()
  264 +
195 265 # Fit model
196 266 self.obs().optimize(self.opt())
197 267  
... ... @@ -210,12 +280,15 @@ class comlixfit(ctools.cslikelihood):
210 280 self._log_value(gammalib.NORMAL, 'logL after iteration %d' % (iter+1),
211 281 result)
212 282  
  283 + # Optionally log results
  284 + self._log_string(gammalib.VERBOSE, str(self.obs().models()))
  285 +
213 286 # Check for convergence
214 287 if iter > 0:
215 288 if delta < eps:
216 289 break
217 290  
218   - # Write header
  291 + # Log header
219 292 self._log_header1(gammalib.EXPLICIT,
220 293 'Final maximum likelihood model fitting')
221 294  
... ... @@ -231,7 +304,7 @@ class comlixfit(ctools.cslikelihood):
231 304 self._log_value(gammalib.NORMAL, 'logL after final iteration',
232 305 result)
233 306  
234   - # Log header
  307 + # Log results
235 308 self._log_header1(gammalib.NORMAL,
236 309 'Maximum likelihood optimisation results')
237 310 self._log_string(gammalib.NORMAL, str(self.opt()))
... ... @@ -244,7 +317,7 @@ class comlixfit(ctools.cslikelihood):
244 317 """
245 318 Save observation definition file
246 319 """
247   - # Write header
  320 + # Log header
248 321 self._log_header1(gammalib.TERSE, 'Save observations')
249 322  
250 323 # Get output filenames
... ...