Commit ca5c9a3639442bfb60b00fc48504190056b75040
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.
Showing
2 changed files
with
87 additions
and
13 deletions
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 | ... | ... |