Commit 74bcfe43362af53c2d26c0766c6ad4724cb3eb61
1 parent
7de3c72c
Tune cspull scripts and associated scripts
(still need to remove some debug statements later)
Showing
5 changed files
with
289 additions
and
209 deletions
cscripts/cspull.py
| ... | ... | @@ -30,22 +30,16 @@ from cscripts import obsutils |
| 30 | 30 | # ============ # |
| 31 | 31 | class cspull(ctools.cscript): |
| 32 | 32 | """ |
| 33 | - Generates pull distributions for a model. | |
| 34 | - | |
| 35 | - This class implements the pull distribution generation script. It derives | |
| 36 | - from the ctools.cscript class which provides support for parameter | |
| 37 | - files, command line arguments, and logging. In that way the Python | |
| 38 | - script behaves just as a regular ctool. | |
| 33 | + Generates pull distributions for a model | |
| 39 | 34 | """ |
| 40 | - | |
| 41 | 35 | # Constructor |
| 42 | 36 | def __init__(self, *argv): |
| 43 | 37 | """ |
| 44 | 38 | Constructor. |
| 45 | 39 | """ |
| 46 | 40 | # Set name |
| 47 | - self._name = "cspull" | |
| 48 | - self._version = "1.1.0" | |
| 41 | + self._name = 'cspull' | |
| 42 | + self._version = '1.1.0' | |
| 49 | 43 | |
| 50 | 44 | # Initialise some members |
| 51 | 45 | self._edisp = False |
| ... | ... | @@ -54,15 +48,15 @@ class cspull(ctools.cscript): |
| 54 | 48 | self._bckcube = None |
| 55 | 49 | self._edispcube = None |
| 56 | 50 | self._stackmodels = None |
| 57 | - self._coordsys = "CEL" | |
| 58 | - self._proj = "TAN" | |
| 59 | - self._log_clients = False | |
| 51 | + self._coordsys = 'CEL' | |
| 52 | + self._proj = 'TAN' | |
| 53 | + self._log_clients = False # Static parameter | |
| 60 | 54 | self._offset = 0.0 |
| 61 | 55 | self._ntrials = 0 |
| 62 | 56 | self._outfile = gammalib.GFilename() |
| 63 | 57 | self._npix = 0 |
| 64 | 58 | self._binsz = 0.0 |
| 65 | - self._pattern = "single" | |
| 59 | + self._pattern = 'single' | |
| 66 | 60 | self._enumbins = 0 |
| 67 | 61 | self._seed = 1 |
| 68 | 62 | self._chatter = 2 |
| ... | ... | @@ -81,7 +75,7 @@ class cspull(ctools.cscript): |
| 81 | 75 | # Private methods |
| 82 | 76 | def _get_parameters(self): |
| 83 | 77 | """ |
| 84 | - Get parameters from parfile. | |
| 78 | + Get parameters from parfile | |
| 85 | 79 | """ |
| 86 | 80 | # If there are no observations in container then get some ... |
| 87 | 81 | if self._obs.size() == 0: |
| ... | ... | @@ -89,8 +83,8 @@ class cspull(ctools.cscript): |
| 89 | 83 | |
| 90 | 84 | # Check for requested pattern and use above |
| 91 | 85 | # observation parameters to set wobble pattern |
| 92 | - self._pattern = self["pattern"].string() | |
| 93 | - if self._pattern == "four": | |
| 86 | + self._pattern = self['pattern'].string() | |
| 87 | + if self._pattern == 'four': | |
| 94 | 88 | self._obs = self._set_obs() |
| 95 | 89 | |
| 96 | 90 | # ... otherwise add response information and energy boundaries |
| ... | ... | @@ -99,153 +93,173 @@ class cspull(ctools.cscript): |
| 99 | 93 | self._setup_observations(self._obs) |
| 100 | 94 | |
| 101 | 95 | # Get number of energy bins |
| 102 | - self._enumbins = self["enumbins"].integer() | |
| 96 | + self._enumbins = self['enumbins'].integer() | |
| 103 | 97 | |
| 104 | 98 | # Read parameters for binned if requested |
| 105 | 99 | if self._enumbins != 0: |
| 106 | - self._npix = self["npix"].integer() | |
| 107 | - self._binsz = self["binsz"].real() | |
| 108 | - self._coordsys = self["coordsys"].string() | |
| 109 | - self._proj = self["proj"].string() | |
| 100 | + self._npix = self['npix'].integer() | |
| 101 | + self._binsz = self['binsz'].real() | |
| 102 | + self._coordsys = self['coordsys'].string() | |
| 103 | + self._proj = self['proj'].string() | |
| 110 | 104 | |
| 111 | 105 | # Set models if we have none |
| 112 | 106 | if self._obs.models().size() == 0: |
| 113 | - self._obs.models(self["inmodel"].filename()) | |
| 107 | + self._obs.models(self['inmodel'].filename()) | |
| 114 | 108 | |
| 115 | 109 | # Read other parameters |
| 116 | - self._outfile = self["outfile"].filename() | |
| 117 | - self._ntrials = self["ntrials"].integer() | |
| 118 | - self._edisp = self["edisp"].boolean() | |
| 119 | - self._offset = self["offset"].real() | |
| 120 | - self._seed = self["seed"].integer() | |
| 121 | - self._chatter = self["chatter"].integer() | |
| 110 | + self._outfile = self['outfile'].filename() | |
| 111 | + self._ntrials = self['ntrials'].integer() | |
| 112 | + self._edisp = self['edisp'].boolean() | |
| 113 | + self._offset = self['offset'].real() | |
| 114 | + self._seed = self['seed'].integer() | |
| 115 | + self._chatter = self['chatter'].integer() | |
| 122 | 116 | |
| 123 | 117 | # Query some parameters |
| 124 | - self["profile"].boolean() | |
| 118 | + self['profile'].boolean() | |
| 125 | 119 | |
| 126 | 120 | # Write input parameters into logger |
| 127 | 121 | if self._logTerse(): |
| 128 | 122 | self._log_parameters() |
| 129 | - self._log("\n") | |
| 123 | + self._log('\n') | |
| 130 | 124 | |
| 131 | 125 | # Return |
| 132 | 126 | return |
| 133 | 127 | |
| 134 | 128 | def _set_obs(self): |
| 135 | 129 | """ |
| 136 | - Set CTA observation(s). | |
| 130 | + Set CTA observation(s) | |
| 137 | 131 | |
| 138 | - Returns: | |
| 139 | - An observation container. | |
| 132 | + Returns | |
| 133 | + ------- | |
| 134 | + obs : `~gammalib.GObservations` | |
| 135 | + Observation container. | |
| 140 | 136 | """ |
| 141 | 137 | # Setup observation definition list |
| 142 | 138 | obsdeflist = obsutils.set_obs_patterns(self._pattern, |
| 143 | - ra=self["ra"].real(), | |
| 144 | - dec=self["dec"].real(), | |
| 145 | - offset=self["offset"].real()) | |
| 139 | + ra=self['ra'].real(), | |
| 140 | + dec=self['dec'].real(), | |
| 141 | + offset=self['offset'].real()) | |
| 146 | 142 | |
| 147 | 143 | # Create list of observations |
| 148 | 144 | obs = obsutils.set_obs_list(obsdeflist, |
| 149 | - tstart=self["tmin"].real(), | |
| 150 | - duration=self["tmax"].real()-self["tmin"].real(), | |
| 151 | - deadc=self["deadc"].real(), | |
| 152 | - emin=self["emin"].real(), | |
| 153 | - emax=self["emax"].real(), | |
| 154 | - rad=self["rad"].real(), | |
| 155 | - irf=self["irf"].string(), | |
| 156 | - caldb=self["caldb"].string()) | |
| 145 | + tstart=self['tmin'].real(), | |
| 146 | + duration=self['tmax'].real()-self['tmin'].real(), | |
| 147 | + deadc=self['deadc'].real(), | |
| 148 | + emin=self['emin'].real(), | |
| 149 | + emax=self['emax'].real(), | |
| 150 | + rad=self['rad'].real(), | |
| 151 | + irf=self['irf'].string(), | |
| 152 | + caldb=self['caldb'].string()) | |
| 157 | 153 | |
| 158 | 154 | # Return observation container |
| 159 | 155 | return obs |
| 160 | 156 | |
| 161 | 157 | def _set_stacked_irf(self): |
| 162 | 158 | """ |
| 163 | - For stacked analysis prepare stacked irfs | |
| 159 | + Prepare stacked IRFs for stacked analysis | |
| 164 | 160 | """ |
| 165 | 161 | # Write header into logger |
| 166 | 162 | if self._logTerse(): |
| 167 | - self._log("\n") | |
| 168 | - self._log.header1("Compute stacked response") | |
| 163 | + self._log('\n') | |
| 164 | + self._log.header1('Compute stacked response') | |
| 169 | 165 | |
| 170 | 166 | # Get stacked exposure |
| 171 | 167 | expcube = ctools.ctexpcube(self._obs) |
| 172 | - expcube["incube"] = "NONE" | |
| 173 | - expcube["usepnt"] = True | |
| 174 | - expcube["ebinalg"] = "LOG" | |
| 175 | - expcube["binsz"] = self._binsz | |
| 176 | - expcube["nxpix"] = self._npix | |
| 177 | - expcube["nypix"] = self._npix | |
| 178 | - expcube["enumbins"] = self._enumbins | |
| 179 | - expcube["emin"] = self["emin"].real() | |
| 180 | - expcube["emax"] = self["emax"].real() | |
| 181 | - expcube["coordsys"] = self._coordsys | |
| 182 | - expcube["proj"] = self._proj | |
| 168 | + expcube['incube'] = 'NONE' | |
| 169 | + expcube['usepnt'] = True | |
| 170 | + expcube['ebinalg'] = 'LOG' | |
| 171 | + expcube['binsz'] = self._binsz | |
| 172 | + expcube['nxpix'] = self._npix | |
| 173 | + expcube['nypix'] = self._npix | |
| 174 | + expcube['enumbins'] = self._enumbins | |
| 175 | + expcube['emin'] = self['emin'].real() | |
| 176 | + expcube['emax'] = self['emax'].real() | |
| 177 | + expcube['coordsys'] = self._coordsys | |
| 178 | + expcube['proj'] = self._proj | |
| 179 | + expcube['chatter'] = self._chatter | |
| 180 | + expcube['debug'] = self._logDebug() | |
| 183 | 181 | expcube.run() |
| 182 | + # JK: Debug | |
| 183 | + expcube['outcube'] = 'expcube.fits' | |
| 184 | + expcube.save() | |
| 184 | 185 | |
| 185 | 186 | # Notify exposure computation |
| 186 | 187 | if self._logTerse(): |
| 187 | - self._log("Computed exposure cube\n") | |
| 188 | + self._log('Computed exposure cube\n') | |
| 188 | 189 | |
| 189 | 190 | # Get stacked Psf |
| 190 | 191 | psfcube = ctools.ctpsfcube(self._obs) |
| 191 | - psfcube["incube"] = "NONE" | |
| 192 | - psfcube["usepnt"] = True | |
| 193 | - psfcube["ebinalg"] = "LOG" | |
| 194 | - psfcube["binsz"] = self._binsz*10.0 | |
| 195 | - psfcube["nxpix"] = self._npix/10 | |
| 196 | - psfcube["nypix"] = self._npix/10 | |
| 197 | - psfcube["enumbins"] = self._enumbins | |
| 198 | - psfcube["emin"] = self["emin"].real() | |
| 199 | - psfcube["emax"] = self["emax"].real() | |
| 200 | - psfcube["coordsys"] = self._coordsys | |
| 201 | - psfcube["proj"] = self._proj | |
| 192 | + psfcube['incube'] = 'NONE' | |
| 193 | + psfcube['usepnt'] = True | |
| 194 | + psfcube['ebinalg'] = 'LOG' | |
| 195 | + psfcube['binsz'] = self._binsz*10.0 | |
| 196 | + psfcube['nxpix'] = self._npix/10 | |
| 197 | + psfcube['nypix'] = self._npix/10 | |
| 198 | + psfcube['enumbins'] = self._enumbins | |
| 199 | + psfcube['emin'] = self['emin'].real() | |
| 200 | + psfcube['emax'] = self['emax'].real() | |
| 201 | + psfcube['coordsys'] = self._coordsys | |
| 202 | + psfcube['proj'] = self._proj | |
| 203 | + psfcube['chatter'] = self._chatter | |
| 204 | + psfcube['debug'] = self._logDebug() | |
| 202 | 205 | psfcube.run() |
| 206 | + # JK: Debug | |
| 207 | + psfcube['outcube'] = 'psfcube.fits' | |
| 208 | + psfcube.save() | |
| 203 | 209 | |
| 204 | 210 | # Notify Psf computation |
| 205 | 211 | if self._logTerse(): |
| 206 | - self._log("Computed point spread function cube\n") | |
| 212 | + self._log('Computed point spread function cube\n') | |
| 207 | 213 | |
| 208 | 214 | # Optionally get stacked Edisp |
| 209 | 215 | if self._edisp: |
| 210 | 216 | edispcube = ctools.ctedispcube(self._obs) |
| 211 | - edispcube["incube"] = "NONE" | |
| 212 | - edispcube["usepnt"] = True | |
| 213 | - edispcube["ebinalg"] = "LOG" | |
| 214 | - edispcube["binsz"] = self._binsz*10.0 | |
| 215 | - edispcube["nxpix"] = self._npix/10 | |
| 216 | - edispcube["nypix"] = self._npix/10 | |
| 217 | - edispcube["enumbins"] = self._enumbins | |
| 218 | - edispcube["emin"] = self["emin"].real() | |
| 219 | - edispcube["emax"] = self["emax"].real() | |
| 220 | - edispcube["coordsys"] = self._coordsys | |
| 221 | - edispcube["proj"] = self._proj | |
| 222 | - edispcube.run() | |
| 217 | + edispcube['incube'] = 'NONE' | |
| 218 | + edispcube['usepnt'] = True | |
| 219 | + edispcube['ebinalg'] = 'LOG' | |
| 220 | + edispcube['binsz'] = self._binsz*10.0 | |
| 221 | + edispcube['nxpix'] = self._npix/10 | |
| 222 | + edispcube['nypix'] = self._npix/10 | |
| 223 | + edispcube['enumbins'] = self._enumbins | |
| 224 | + edispcube['emin'] = self['emin'].real() | |
| 225 | + edispcube['emax'] = self['emax'].real() | |
| 226 | + edispcube['coordsys'] = self._coordsys | |
| 227 | + edispcube['proj'] = self._proj | |
| 228 | + edispcube['chatter'] = self._chatter | |
| 229 | + edispcube['debug'] = self._logDebug() | |
| 230 | + edispcube.run() | |
| 223 | 231 | |
| 224 | 232 | # Store result |
| 225 | 233 | self._edispcube = edispcube.edispcube().copy() |
| 226 | 234 | |
| 227 | 235 | # Logging |
| 228 | 236 | if self._logTerse(): |
| 229 | - self._log("Computed energy dispersion cube\n") | |
| 237 | + self._log('Computed energy dispersion cube\n') | |
| 230 | 238 | |
| 231 | 239 | # Get stacked background |
| 232 | 240 | bkgcube = ctools.ctbkgcube(self._obs) |
| 233 | - bkgcube["incube"] = "NONE" | |
| 234 | - bkgcube["usepnt"] = True | |
| 235 | - bkgcube["ebinalg"] = "LOG" | |
| 236 | - bkgcube["binsz"] = self._binsz | |
| 237 | - bkgcube["nxpix"] = self._npix | |
| 238 | - bkgcube["nypix"] = self._npix | |
| 239 | - bkgcube["enumbins"] = self._enumbins | |
| 240 | - bkgcube["emin"] = self["emin"].real() | |
| 241 | - bkgcube["emax"] = self["emax"].real() | |
| 242 | - bkgcube["coordsys"] = self._coordsys | |
| 243 | - bkgcube["proj"] = self._proj | |
| 241 | + bkgcube['incube'] = 'NONE' | |
| 242 | + bkgcube['usepnt'] = True | |
| 243 | + bkgcube['ebinalg'] = 'LOG' | |
| 244 | + bkgcube['binsz'] = self._binsz | |
| 245 | + bkgcube['nxpix'] = self._npix | |
| 246 | + bkgcube['nypix'] = self._npix | |
| 247 | + bkgcube['enumbins'] = self._enumbins | |
| 248 | + bkgcube['emin'] = self['emin'].real() | |
| 249 | + bkgcube['emax'] = self['emax'].real() | |
| 250 | + bkgcube['coordsys'] = self._coordsys | |
| 251 | + bkgcube['proj'] = self._proj | |
| 252 | + bkgcube['chatter'] = self._chatter | |
| 253 | + bkgcube['debug'] = self._logDebug() | |
| 244 | 254 | bkgcube.run() |
| 255 | + # JK: Debug | |
| 256 | + bkgcube['outcube'] = 'bkgcube.fits' | |
| 257 | + bkgcube['outmodel'] = 'cube_model.xml' | |
| 258 | + bkgcube.save() | |
| 245 | 259 | |
| 246 | 260 | # Notify background cube computation |
| 247 | 261 | if self._logTerse(): |
| 248 | - self._log("Computed background cube\n") | |
| 262 | + self._log('Computed background cube\n') | |
| 249 | 263 | |
| 250 | 264 | # Store results |
| 251 | 265 | self._exposure = expcube.expcube().copy() |
| ... | ... | @@ -256,19 +270,63 @@ class cspull(ctools.cscript): |
| 256 | 270 | # Return |
| 257 | 271 | return |
| 258 | 272 | |
| 259 | - def _trial(self, seed): | |
| 273 | + def _obs_string(self, obs): | |
| 260 | 274 | """ |
| 261 | - Compute the pull for a single trial. | |
| 275 | + Generate summary string for observation | |
| 276 | + | |
| 277 | + Parameters | |
| 278 | + ---------- | |
| 279 | + obs : `~gammalib.GCTAObservation` | |
| 280 | + Observation | |
| 262 | 281 | |
| 263 | - Args: | |
| 264 | - seed: Random number generator seed. | |
| 282 | + Returns | |
| 283 | + ------- | |
| 284 | + text : str | |
| 285 | + Summary string | |
| 286 | + """ | |
| 287 | + # Extract information from observation | |
| 288 | + emin = obs.events().ebounds().emin().TeV() | |
| 289 | + emax = obs.events().ebounds().emax().TeV() | |
| 290 | + events = obs.events().number() | |
| 291 | + binned = (obs.events().classname() == 'GCTAEventCube') | |
| 292 | + if binned: | |
| 293 | + mode = 'binned' | |
| 294 | + else: | |
| 295 | + mode = 'unbinned' | |
| 296 | + | |
| 297 | + # Compose summary string | |
| 298 | + if events > 0: | |
| 299 | + text = '%d events, %.3f-%.3f TeV, %s' % (events, emin, emax, mode) | |
| 300 | + else: | |
| 301 | + text = '%.3f-%.3f TeV, %s' % (emin, emax, mode) | |
| 302 | + | |
| 303 | + # Return summary string | |
| 304 | + return text | |
| 305 | + | |
| 306 | + def _trial(self, seed, stacked): | |
| 307 | + """ | |
| 308 | + Compute the pull for a single trial | |
| 309 | + | |
| 310 | + Parameters | |
| 311 | + ---------- | |
| 312 | + seed : int | |
| 313 | + Random number generator seed | |
| 314 | + stacked : bool | |
| 315 | + Use stacked analysis | |
| 316 | + | |
| 317 | + Returns | |
| 318 | + ------- | |
| 319 | + result : dict | |
| 320 | + Dictionary of results | |
| 265 | 321 | """ |
| 266 | 322 | # Write header |
| 267 | 323 | if self._logNormal(): |
| 268 | - self._log.header2("Trial "+str(seed+1)) | |
| 324 | + self._log.header2('Trial '+str(seed-self._seed+1)) | |
| 269 | 325 | |
| 270 | 326 | # Simulate events |
| 271 | 327 | obs = obsutils.sim(self._obs, |
| 328 | + emin=self['emin'].real(), | |
| 329 | + emax=self['emax'].real(), | |
| 272 | 330 | nbins=self._enumbins, |
| 273 | 331 | seed=seed, |
| 274 | 332 | binsz=self._binsz, |
| ... | ... | @@ -281,7 +339,7 @@ class cspull(ctools.cscript): |
| 281 | 339 | chatter=self._chatter) |
| 282 | 340 | |
| 283 | 341 | # Set response for a stacked observation |
| 284 | - if self._obs.size() > 1 and self._enumbins > 0: | |
| 342 | + if stacked: | |
| 285 | 343 | if self._edisp: |
| 286 | 344 | obs[0].response(self._exposure, self._psfcube, |
| 287 | 345 | self._edispcube, self._bckcube) |
| ... | ... | @@ -289,6 +347,8 @@ class cspull(ctools.cscript): |
| 289 | 347 | obs[0].response(self._exposure, self._psfcube, |
| 290 | 348 | self._bckcube) |
| 291 | 349 | obs.models(self._stackmodels) |
| 350 | + # JK: Test | |
| 351 | + obs[0].save('stacked_cube.fits', True) | |
| 292 | 352 | |
| 293 | 353 | # Determine number of events in simulation |
| 294 | 354 | nevents = 0.0 |
| ... | ... | @@ -297,13 +357,21 @@ class cspull(ctools.cscript): |
| 297 | 357 | |
| 298 | 358 | # Write simulation results |
| 299 | 359 | if self._logNormal(): |
| 300 | - self._log.header3("Simulation") | |
| 301 | - self._log.parformat("Number of simulated events") | |
| 360 | + self._log.header3('Simulation') | |
| 361 | + for run in self._obs: | |
| 362 | + self._log.parformat('Input observation %s' % (run.id())) | |
| 363 | + self._log(self._obs_string(run)) | |
| 364 | + self._log('\n') | |
| 365 | + for run in obs: | |
| 366 | + self._log.parformat('Output observation %s' % (run.id())) | |
| 367 | + self._log(self._obs_string(run)) | |
| 368 | + self._log('\n') | |
| 369 | + self._log.parformat('Number of simulated events') | |
| 302 | 370 | self._log(nevents) |
| 303 | - self._log("\n") | |
| 371 | + self._log('\n') | |
| 304 | 372 | |
| 305 | 373 | # Fit model |
| 306 | - if self["profile"].boolean(): | |
| 374 | + if self['profile'].boolean(): | |
| 307 | 375 | models = self._obs.models() |
| 308 | 376 | for i in range(models.size()): |
| 309 | 377 | model_name = models[i].name() |
| ... | ... | @@ -324,17 +392,17 @@ class cspull(ctools.cscript): |
| 324 | 392 | |
| 325 | 393 | # Write result header |
| 326 | 394 | if self._logNormal(): |
| 327 | - self._log.header3("Pulls") | |
| 395 | + self._log.header3('Pulls') | |
| 328 | 396 | |
| 329 | 397 | # Gather results |
| 330 | 398 | colnames = [] |
| 331 | 399 | values = {} |
| 332 | - colnames.append("LogL") | |
| 333 | - colnames.append("Sim_Events") | |
| 334 | - colnames.append("Npred_Events") | |
| 335 | - values["LogL"] = logL | |
| 336 | - values["Sim_Events"] = nevents | |
| 337 | - values["Npred_Events"] = npred | |
| 400 | + colnames.append('LogL') | |
| 401 | + colnames.append('Sim_Events') | |
| 402 | + colnames.append('Npred_Events') | |
| 403 | + values['LogL'] = logL | |
| 404 | + values['Sim_Events'] = nevents | |
| 405 | + values['Npred_Events'] = npred | |
| 338 | 406 | for i in range(models.size()): |
| 339 | 407 | model = models[i] |
| 340 | 408 | model_name = model.name() |
| ... | ... | @@ -343,12 +411,12 @@ class cspull(ctools.cscript): |
| 343 | 411 | if par.is_free(): |
| 344 | 412 | |
| 345 | 413 | # Set parameter name |
| 346 | - name = model_name+"_"+par.name() | |
| 414 | + name = model_name+'_'+par.name() | |
| 347 | 415 | |
| 348 | 416 | # Append parameter, Pull_parameter and Unc_parameter |
| 349 | 417 | colnames.append(name) |
| 350 | - colnames.append("Pull_"+name) | |
| 351 | - colnames.append("Unc_"+name) | |
| 418 | + colnames.append('Pull_'+name) | |
| 419 | + colnames.append('Unc_'+name) | |
| 352 | 420 | |
| 353 | 421 | # Compute pull |
| 354 | 422 | fitted_value = par.value() |
| ... | ... | @@ -361,18 +429,18 @@ class cspull(ctools.cscript): |
| 361 | 429 | |
| 362 | 430 | # Store results |
| 363 | 431 | values[name] = fitted_value |
| 364 | - values["Pull_"+name] = pull | |
| 365 | - values["Unc_"+name] = error | |
| 432 | + values['Pull_'+name] = pull | |
| 433 | + values['Unc_'+name] = error | |
| 366 | 434 | |
| 367 | 435 | # Write result |
| 368 | 436 | if self._logNormal(): |
| 369 | 437 | self._log.parformat(name) |
| 370 | 438 | self._log(pull) |
| 371 | - self._log(" (") | |
| 439 | + self._log(' (') | |
| 372 | 440 | self._log(fitted_value) |
| 373 | - self._log(" +/- ") | |
| 441 | + self._log(' +/- ') | |
| 374 | 442 | self._log(error) |
| 375 | - self._log(")\n") | |
| 443 | + self._log(')\n') | |
| 376 | 444 | |
| 377 | 445 | # Bundle together results |
| 378 | 446 | result = {'colnames': colnames, 'values': values} |
| ... | ... | @@ -384,7 +452,7 @@ class cspull(ctools.cscript): |
| 384 | 452 | # Public methods |
| 385 | 453 | def run(self): |
| 386 | 454 | """ |
| 387 | - Run the script. | |
| 455 | + Run the script | |
| 388 | 456 | """ |
| 389 | 457 | # Switch screen logging on in debug mode |
| 390 | 458 | if self._logDebug(): |
| ... | ... | @@ -395,25 +463,29 @@ class cspull(ctools.cscript): |
| 395 | 463 | |
| 396 | 464 | # Write observation into logger |
| 397 | 465 | if self._logTerse(): |
| 398 | - self._log("\n") | |
| 399 | - self._log.header1("Observation(s)") | |
| 466 | + self._log('\n') | |
| 467 | + self._log.header1(gammalib.number('Observation',len(self._obs))) | |
| 400 | 468 | self._log(str(self._obs)) |
| 401 | - self._log("\n") | |
| 469 | + self._log('\n') | |
| 470 | + | |
| 471 | + # Signal if stacked analysis is requested | |
| 472 | + #stacked = self._obs.size() > 1 and self._enumbins > 0 | |
| 473 | + stacked = self._enumbins > 0 | |
| 402 | 474 | |
| 403 | 475 | # If several observations and binned: prepare stacked irfs |
| 404 | - if self._obs.size() > 1 and self._enumbins > 0: | |
| 476 | + if stacked: | |
| 405 | 477 | self._set_stacked_irf() |
| 406 | 478 | |
| 407 | 479 | # Write header |
| 408 | 480 | if self._logTerse(): |
| 409 | - self._log("\n") | |
| 410 | - self._log.header1("Generate pull distribution") | |
| 481 | + self._log('\n') | |
| 482 | + self._log.header1('Generate pull distribution') | |
| 411 | 483 | |
| 412 | 484 | # Loop over trials |
| 413 | 485 | for seed in range(self._ntrials): |
| 414 | 486 | |
| 415 | 487 | # Make a trial and add initial seed |
| 416 | - result = self._trial(seed + self._seed) | |
| 488 | + result = self._trial(seed + self._seed, stacked) | |
| 417 | 489 | |
| 418 | 490 | # Write out result immediately |
| 419 | 491 | if seed == 0: |
| ... | ... | @@ -434,7 +506,7 @@ class cspull(ctools.cscript): |
| 434 | 506 | |
| 435 | 507 | def execute(self): |
| 436 | 508 | """ |
| 437 | - Execute the script. | |
| 509 | + Execute the script | |
| 438 | 510 | """ |
| 439 | 511 | # Open logfile |
| 440 | 512 | self.logFileOpen() |
| ... | ... | @@ -447,10 +519,15 @@ class cspull(ctools.cscript): |
| 447 | 519 | |
| 448 | 520 | def models(self, models): |
| 449 | 521 | """ |
| 450 | - Set model. | |
| 522 | + Set model | |
| 523 | + | |
| 524 | + Parameters | |
| 525 | + ---------- | |
| 526 | + models : `~gammalib.GModels` | |
| 527 | + Set model container | |
| 451 | 528 | """ |
| 452 | - # Copy models | |
| 453 | - self.obs.models(models.copy()) | |
| 529 | + # Set model container | |
| 530 | + self._obs.models(models) | |
| 454 | 531 | |
| 455 | 532 | # Return |
| 456 | 533 | return | ... | ... |
cscripts/obsutils.py
| ... | ... | @@ -24,46 +24,58 @@ import ctools |
| 24 | 24 | # ===================== # |
| 25 | 25 | # Simulate observations # |
| 26 | 26 | # ===================== # |
| 27 | -def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, nbins=0, | |
| 28 | - binsz=0.05, npix=200, proj="TAN", coord="GAL"): | |
| 27 | +def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, | |
| 28 | + emin=None, emax=None, nbins=0, | |
| 29 | + binsz=0.05, npix=200, proj='TAN', coord='GAL'): | |
| 29 | 30 | """ |
| 30 | - Simulate events for all observations in the container. | |
| 31 | - | |
| 32 | - Args: | |
| 33 | - obs: Observation container without events | |
| 34 | - | |
| 35 | - Kwargs: | |
| 36 | - log: Create log file(s) | |
| 37 | - debug: Create console dump? | |
| 38 | - chatter: Chatter level | |
| 39 | - edisp: Apply energy dispersion? | |
| 40 | - seed: Seed value for simulations (default: 0) | |
| 41 | - nbins: Number of energy bins (default: 0=unbinned) | |
| 42 | - binsz: Pixel size for binned simulation (deg/pixel) | |
| 43 | - npix: Number of pixels in X and Y for binned simulation | |
| 44 | - proj: Projection for binned simulation | |
| 45 | - coord: Coordinate system for binned simulation | |
| 46 | - | |
| 47 | - Returns: | |
| 48 | - Observation container, filled with simulated events. | |
| 31 | + Simulate events for all observations in the container | |
| 32 | + | |
| 33 | + Parameters | |
| 34 | + ---------- | |
| 35 | + obs : `~gammalib.GObservations` | |
| 36 | + Observation container without events | |
| 37 | + log : bool, optional | |
| 38 | + Create log file(s) | |
| 39 | + debug : bool, optional | |
| 40 | + Create console dump? | |
| 41 | + chatter : int, optional | |
| 42 | + Chatter level | |
| 43 | + edisp : bool, optional | |
| 44 | + Apply energy dispersion? | |
| 45 | + seed : int, integer | |
| 46 | + Seed value for simulations | |
| 47 | + emin : float, optional | |
| 48 | + Minimum energy of counts cube for binned (TeV) | |
| 49 | + emax : float, optional | |
| 50 | + Maximum energy of counts cube for binned (TeV) | |
| 51 | + nbins : int, optional | |
| 52 | + Number of energy bins (0=unbinned) | |
| 53 | + binsz : float, optional | |
| 54 | + Pixel size for binned simulation (deg/pixel) | |
| 55 | + npix : int, optional | |
| 56 | + Number of pixels in X and Y for binned simulation | |
| 57 | + proj : str, optional | |
| 58 | + Projection for binned simulation | |
| 59 | + coord : str, optional | |
| 60 | + Coordinate system for binned simulation | |
| 61 | + | |
| 62 | + Returns | |
| 63 | + ------- | |
| 64 | + obs : `~gammalib.GObservations` | |
| 65 | + Observation container filled with simulated events | |
| 49 | 66 | """ |
| 50 | 67 | |
| 51 | 68 | # Allocate ctobssim application and set parameters |
| 52 | 69 | sim = ctools.ctobssim(obs) |
| 53 | - sim["seed"] = seed | |
| 54 | - sim["edisp"] = edisp | |
| 70 | + sim['seed'] = seed | |
| 71 | + sim['edisp'] = edisp | |
| 72 | + sim['chatter'] = chatter | |
| 73 | + sim['debug'] = debug | |
| 55 | 74 | |
| 56 | 75 | # Optionally open the log file |
| 57 | 76 | if log: |
| 58 | 77 | sim.logFileOpen() |
| 59 | 78 | |
| 60 | - # Optionally switch-on debugging model | |
| 61 | - if debug: | |
| 62 | - sim["debug"] = True | |
| 63 | - | |
| 64 | - # Set chatter level | |
| 65 | - sim["chatter"] = chatter | |
| 66 | - | |
| 67 | 79 | # Run ctobssim application. This will loop over all observations in the |
| 68 | 80 | # container and simulation the events for each observation. Note that |
| 69 | 81 | # events are not added together, they still apply to each observation |
| ... | ... | @@ -73,45 +85,42 @@ def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, nbins=0, |
| 73 | 85 | # Binned option? |
| 74 | 86 | if nbins > 0: |
| 75 | 87 | |
| 76 | - # Determine common energy boundaries for observations | |
| 77 | - emin = None | |
| 78 | - emax = None | |
| 79 | - for run in sim.obs(): | |
| 80 | - run_emin = run.events().ebounds().emin().TeV() | |
| 81 | - run_emax = run.events().ebounds().emax().TeV() | |
| 82 | - if emin == None: | |
| 83 | - emin = run_emin | |
| 84 | - elif run_emin > emin: | |
| 85 | - emin = run_emin | |
| 86 | - if emax == None: | |
| 87 | - emax = run_emax | |
| 88 | - elif run_emax > emax: | |
| 89 | - emax = run_emax | |
| 88 | + # If energy boundaries are not given then determine common energy | |
| 89 | + # boundaries for all observations | |
| 90 | + if emin == None or emax == None: | |
| 91 | + emin = None | |
| 92 | + emax = None | |
| 93 | + for run in sim.obs(): | |
| 94 | + run_emin = run.events().ebounds().emin().TeV() | |
| 95 | + run_emax = run.events().ebounds().emax().TeV() | |
| 96 | + if emin == None: | |
| 97 | + emin = run_emin | |
| 98 | + elif run_emin > emin: | |
| 99 | + emin = run_emin | |
| 100 | + if emax == None: | |
| 101 | + emax = run_emax | |
| 102 | + elif run_emax > emax: | |
| 103 | + emax = run_emax | |
| 90 | 104 | |
| 91 | 105 | # Allocate ctbin application and set parameters |
| 92 | 106 | bin = ctools.ctbin(sim.obs()) |
| 93 | - bin["ebinalg"] = "LOG" | |
| 94 | - bin["emin"] = emin | |
| 95 | - bin["emax"] = emax | |
| 96 | - bin["enumbins"] = nbins | |
| 97 | - bin["usepnt"] = True # Use pointing for map centre | |
| 98 | - bin["nxpix"] = npix | |
| 99 | - bin["nypix"] = npix | |
| 100 | - bin["binsz"] = binsz | |
| 101 | - bin["coordsys"] = coord | |
| 102 | - bin["proj"] = proj | |
| 107 | + bin['ebinalg'] = 'LOG' | |
| 108 | + bin['emin'] = emin | |
| 109 | + bin['emax'] = emax | |
| 110 | + bin['enumbins'] = nbins | |
| 111 | + bin['usepnt'] = True # Use pointing for map centre | |
| 112 | + bin['nxpix'] = npix | |
| 113 | + bin['nypix'] = npix | |
| 114 | + bin['binsz'] = binsz | |
| 115 | + bin['coordsys'] = coord | |
| 116 | + bin['proj'] = proj | |
| 117 | + bin['chatter'] = chatter | |
| 118 | + bin['debug'] = debug | |
| 103 | 119 | |
| 104 | 120 | # Optionally open the log file |
| 105 | 121 | if log: |
| 106 | 122 | bin.logFileOpen() |
| 107 | 123 | |
| 108 | - # Optionally switch-on debugging model | |
| 109 | - if debug: | |
| 110 | - bin["debug"] = True | |
| 111 | - | |
| 112 | - # Set chatter level | |
| 113 | - bin["chatter"] = chatter | |
| 114 | - | |
| 115 | 124 | # Run ctbin application. This will loop over all observations in |
| 116 | 125 | # the container and bin the events in counts maps |
| 117 | 126 | bin.run() | ... | ... |
src/ctexpcube/ctexpcube.cpp
| ... | ... | @@ -220,12 +220,7 @@ void ctexpcube::run(void) |
| 220 | 220 | // Write observation(s) into logger |
| 221 | 221 | if (logTerse()) { |
| 222 | 222 | log << std::endl; |
| 223 | - if (m_obs.size() > 1) { | |
| 224 | - log.header1("Observations"); | |
| 225 | - } | |
| 226 | - else { | |
| 227 | - log.header1("Observation"); | |
| 228 | - } | |
| 223 | + log.header1(gammalib::number("Observation",m_obs.size())); | |
| 229 | 224 | log << m_obs << std::endl; |
| 230 | 225 | } |
| 231 | 226 | ... | ... |
src/ctlike/ctlike.cpp
| ... | ... | @@ -230,13 +230,8 @@ void ctlike::run(void) |
| 230 | 230 | // Write observation(s) into logger |
| 231 | 231 | if (logTerse()) { |
| 232 | 232 | log << std::endl; |
| 233 | - if (m_obs.size() > 1) { | |
| 234 | - log.header1("Observations"); | |
| 235 | - } | |
| 236 | - else { | |
| 237 | - log.header1("Observation"); | |
| 238 | - } | |
| 239 | - log << m_obs << std::endl; | |
| 233 | + log.header1(gammalib::number("Observation",m_obs.size())); | |
| 234 | + log << m_obs.print(m_chatter) << std::endl; | |
| 240 | 235 | } |
| 241 | 236 | |
| 242 | 237 | // Optimize model parameters using LM optimizer |
| ... | ... | @@ -311,7 +306,7 @@ void ctlike::run(void) |
| 311 | 306 | if (logTerse()) { |
| 312 | 307 | log << std::endl; |
| 313 | 308 | log.header1("Maximum likelihood optimisation results"); |
| 314 | - log << *m_opt << std::endl; | |
| 309 | + log << m_opt->print(m_chatter) << std::endl; | |
| 315 | 310 | log << gammalib::parformat("Maximum log likelihood"); |
| 316 | 311 | log << gammalib::str(m_logL,3) << std::endl; |
| 317 | 312 | log << gammalib::parformat("Observed events (Nobs)"); |
| ... | ... | @@ -321,7 +316,7 @@ void ctlike::run(void) |
| 321 | 316 | log << " (Nobs - Npred = "; |
| 322 | 317 | log << gammalib::str(num_events-npred); |
| 323 | 318 | log << ")" << std::endl; |
| 324 | - log << m_obs.models() << std::endl; | |
| 319 | + log << m_obs.models().print(m_chatter) << std::endl; | |
| 325 | 320 | } |
| 326 | 321 | |
| 327 | 322 | // Restore energy dispersion flag for all CTA observations |
| ... | ... | @@ -430,6 +425,7 @@ void ctlike::get_parameters(void) |
| 430 | 425 | m_refit = (*this)["refit"].boolean(); |
| 431 | 426 | m_apply_edisp = (*this)["edisp"].boolean(); |
| 432 | 427 | m_fix_spat_for_ts = (*this)["fix_spat_for_ts"].boolean(); |
| 428 | + m_chatter = static_cast<GChatter>((*this)["chatter"].integer()); | |
| 433 | 429 | |
| 434 | 430 | // Optionally read ahead parameters so that they get correctly |
| 435 | 431 | // dumped into the log file |
| ... | ... | @@ -592,6 +588,7 @@ void ctlike::init_members(void) |
| 592 | 588 | m_opt = NULL; |
| 593 | 589 | m_apply_edisp = false; |
| 594 | 590 | m_fix_spat_for_ts = false; |
| 591 | + m_chatter = static_cast<GChatter>(2); | |
| 595 | 592 | |
| 596 | 593 | // Set logger properties |
| 597 | 594 | log.date(true); |
| ... | ... | @@ -628,6 +625,7 @@ void ctlike::copy_members(const ctlike& app) |
| 628 | 625 | m_opt = app.m_opt->clone(); |
| 629 | 626 | m_apply_edisp = app.m_apply_edisp; |
| 630 | 627 | m_fix_spat_for_ts = app.m_fix_spat_for_ts; |
| 628 | + m_chatter = app.m_chatter; | |
| 631 | 629 | |
| 632 | 630 | // Return |
| 633 | 631 | return; | ... | ... |
src/ctlike/ctlike.hpp
| ... | ... | @@ -77,6 +77,7 @@ protected: |
| 77 | 77 | GFilename m_outmodel; //!< Source model output XML file name |
| 78 | 78 | bool m_apply_edisp; //!< Apply energy dispersion? |
| 79 | 79 | bool m_fix_spat_for_ts; //!< Fix spatial parameters for TS computation? |
| 80 | + GChatter m_chatter; //!< Chattiness | |
| 80 | 81 | |
| 81 | 82 | // Members |
| 82 | 83 | GObservations m_obs; //!< Observations | ... | ... |