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,22 +30,16 @@ from cscripts import obsutils | ||
| 30 | # ============ # | 30 | # ============ # |
| 31 | class cspull(ctools.cscript): | 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 | # Constructor | 35 | # Constructor |
| 42 | def __init__(self, *argv): | 36 | def __init__(self, *argv): |
| 43 | """ | 37 | """ |
| 44 | Constructor. | 38 | Constructor. |
| 45 | """ | 39 | """ |
| 46 | # Set name | 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 | # Initialise some members | 44 | # Initialise some members |
| 51 | self._edisp = False | 45 | self._edisp = False |
| @@ -54,15 +48,15 @@ class cspull(ctools.cscript): | @@ -54,15 +48,15 @@ class cspull(ctools.cscript): | ||
| 54 | self._bckcube = None | 48 | self._bckcube = None |
| 55 | self._edispcube = None | 49 | self._edispcube = None |
| 56 | self._stackmodels = None | 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 | self._offset = 0.0 | 54 | self._offset = 0.0 |
| 61 | self._ntrials = 0 | 55 | self._ntrials = 0 |
| 62 | self._outfile = gammalib.GFilename() | 56 | self._outfile = gammalib.GFilename() |
| 63 | self._npix = 0 | 57 | self._npix = 0 |
| 64 | self._binsz = 0.0 | 58 | self._binsz = 0.0 |
| 65 | - self._pattern = "single" | 59 | + self._pattern = 'single' |
| 66 | self._enumbins = 0 | 60 | self._enumbins = 0 |
| 67 | self._seed = 1 | 61 | self._seed = 1 |
| 68 | self._chatter = 2 | 62 | self._chatter = 2 |
| @@ -81,7 +75,7 @@ class cspull(ctools.cscript): | @@ -81,7 +75,7 @@ class cspull(ctools.cscript): | ||
| 81 | # Private methods | 75 | # Private methods |
| 82 | def _get_parameters(self): | 76 | def _get_parameters(self): |
| 83 | """ | 77 | """ |
| 84 | - Get parameters from parfile. | 78 | + Get parameters from parfile |
| 85 | """ | 79 | """ |
| 86 | # If there are no observations in container then get some ... | 80 | # If there are no observations in container then get some ... |
| 87 | if self._obs.size() == 0: | 81 | if self._obs.size() == 0: |
| @@ -89,8 +83,8 @@ class cspull(ctools.cscript): | @@ -89,8 +83,8 @@ class cspull(ctools.cscript): | ||
| 89 | 83 | ||
| 90 | # Check for requested pattern and use above | 84 | # Check for requested pattern and use above |
| 91 | # observation parameters to set wobble pattern | 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 | self._obs = self._set_obs() | 88 | self._obs = self._set_obs() |
| 95 | 89 | ||
| 96 | # ... otherwise add response information and energy boundaries | 90 | # ... otherwise add response information and energy boundaries |
| @@ -99,153 +93,173 @@ class cspull(ctools.cscript): | @@ -99,153 +93,173 @@ class cspull(ctools.cscript): | ||
| 99 | self._setup_observations(self._obs) | 93 | self._setup_observations(self._obs) |
| 100 | 94 | ||
| 101 | # Get number of energy bins | 95 | # Get number of energy bins |
| 102 | - self._enumbins = self["enumbins"].integer() | 96 | + self._enumbins = self['enumbins'].integer() |
| 103 | 97 | ||
| 104 | # Read parameters for binned if requested | 98 | # Read parameters for binned if requested |
| 105 | if self._enumbins != 0: | 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 | # Set models if we have none | 105 | # Set models if we have none |
| 112 | if self._obs.models().size() == 0: | 106 | if self._obs.models().size() == 0: |
| 113 | - self._obs.models(self["inmodel"].filename()) | 107 | + self._obs.models(self['inmodel'].filename()) |
| 114 | 108 | ||
| 115 | # Read other parameters | 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 | # Query some parameters | 117 | # Query some parameters |
| 124 | - self["profile"].boolean() | 118 | + self['profile'].boolean() |
| 125 | 119 | ||
| 126 | # Write input parameters into logger | 120 | # Write input parameters into logger |
| 127 | if self._logTerse(): | 121 | if self._logTerse(): |
| 128 | self._log_parameters() | 122 | self._log_parameters() |
| 129 | - self._log("\n") | 123 | + self._log('\n') |
| 130 | 124 | ||
| 131 | # Return | 125 | # Return |
| 132 | return | 126 | return |
| 133 | 127 | ||
| 134 | def _set_obs(self): | 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 | # Setup observation definition list | 137 | # Setup observation definition list |
| 142 | obsdeflist = obsutils.set_obs_patterns(self._pattern, | 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 | # Create list of observations | 143 | # Create list of observations |
| 148 | obs = obsutils.set_obs_list(obsdeflist, | 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 | # Return observation container | 154 | # Return observation container |
| 159 | return obs | 155 | return obs |
| 160 | 156 | ||
| 161 | def _set_stacked_irf(self): | 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 | # Write header into logger | 161 | # Write header into logger |
| 166 | if self._logTerse(): | 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 | # Get stacked exposure | 166 | # Get stacked exposure |
| 171 | expcube = ctools.ctexpcube(self._obs) | 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 | expcube.run() | 181 | expcube.run() |
| 182 | + # JK: Debug | ||
| 183 | + expcube['outcube'] = 'expcube.fits' | ||
| 184 | + expcube.save() | ||
| 184 | 185 | ||
| 185 | # Notify exposure computation | 186 | # Notify exposure computation |
| 186 | if self._logTerse(): | 187 | if self._logTerse(): |
| 187 | - self._log("Computed exposure cube\n") | 188 | + self._log('Computed exposure cube\n') |
| 188 | 189 | ||
| 189 | # Get stacked Psf | 190 | # Get stacked Psf |
| 190 | psfcube = ctools.ctpsfcube(self._obs) | 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 | psfcube.run() | 205 | psfcube.run() |
| 206 | + # JK: Debug | ||
| 207 | + psfcube['outcube'] = 'psfcube.fits' | ||
| 208 | + psfcube.save() | ||
| 203 | 209 | ||
| 204 | # Notify Psf computation | 210 | # Notify Psf computation |
| 205 | if self._logTerse(): | 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 | # Optionally get stacked Edisp | 214 | # Optionally get stacked Edisp |
| 209 | if self._edisp: | 215 | if self._edisp: |
| 210 | edispcube = ctools.ctedispcube(self._obs) | 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 | # Store result | 232 | # Store result |
| 225 | self._edispcube = edispcube.edispcube().copy() | 233 | self._edispcube = edispcube.edispcube().copy() |
| 226 | 234 | ||
| 227 | # Logging | 235 | # Logging |
| 228 | if self._logTerse(): | 236 | if self._logTerse(): |
| 229 | - self._log("Computed energy dispersion cube\n") | 237 | + self._log('Computed energy dispersion cube\n') |
| 230 | 238 | ||
| 231 | # Get stacked background | 239 | # Get stacked background |
| 232 | bkgcube = ctools.ctbkgcube(self._obs) | 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 | bkgcube.run() | 254 | bkgcube.run() |
| 255 | + # JK: Debug | ||
| 256 | + bkgcube['outcube'] = 'bkgcube.fits' | ||
| 257 | + bkgcube['outmodel'] = 'cube_model.xml' | ||
| 258 | + bkgcube.save() | ||
| 245 | 259 | ||
| 246 | # Notify background cube computation | 260 | # Notify background cube computation |
| 247 | if self._logTerse(): | 261 | if self._logTerse(): |
| 248 | - self._log("Computed background cube\n") | 262 | + self._log('Computed background cube\n') |
| 249 | 263 | ||
| 250 | # Store results | 264 | # Store results |
| 251 | self._exposure = expcube.expcube().copy() | 265 | self._exposure = expcube.expcube().copy() |
| @@ -256,19 +270,63 @@ class cspull(ctools.cscript): | @@ -256,19 +270,63 @@ class cspull(ctools.cscript): | ||
| 256 | # Return | 270 | # Return |
| 257 | return | 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 | # Write header | 322 | # Write header |
| 267 | if self._logNormal(): | 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 | # Simulate events | 326 | # Simulate events |
| 271 | obs = obsutils.sim(self._obs, | 327 | obs = obsutils.sim(self._obs, |
| 328 | + emin=self['emin'].real(), | ||
| 329 | + emax=self['emax'].real(), | ||
| 272 | nbins=self._enumbins, | 330 | nbins=self._enumbins, |
| 273 | seed=seed, | 331 | seed=seed, |
| 274 | binsz=self._binsz, | 332 | binsz=self._binsz, |
| @@ -281,7 +339,7 @@ class cspull(ctools.cscript): | @@ -281,7 +339,7 @@ class cspull(ctools.cscript): | ||
| 281 | chatter=self._chatter) | 339 | chatter=self._chatter) |
| 282 | 340 | ||
| 283 | # Set response for a stacked observation | 341 | # Set response for a stacked observation |
| 284 | - if self._obs.size() > 1 and self._enumbins > 0: | 342 | + if stacked: |
| 285 | if self._edisp: | 343 | if self._edisp: |
| 286 | obs[0].response(self._exposure, self._psfcube, | 344 | obs[0].response(self._exposure, self._psfcube, |
| 287 | self._edispcube, self._bckcube) | 345 | self._edispcube, self._bckcube) |
| @@ -289,6 +347,8 @@ class cspull(ctools.cscript): | @@ -289,6 +347,8 @@ class cspull(ctools.cscript): | ||
| 289 | obs[0].response(self._exposure, self._psfcube, | 347 | obs[0].response(self._exposure, self._psfcube, |
| 290 | self._bckcube) | 348 | self._bckcube) |
| 291 | obs.models(self._stackmodels) | 349 | obs.models(self._stackmodels) |
| 350 | + # JK: Test | ||
| 351 | + obs[0].save('stacked_cube.fits', True) | ||
| 292 | 352 | ||
| 293 | # Determine number of events in simulation | 353 | # Determine number of events in simulation |
| 294 | nevents = 0.0 | 354 | nevents = 0.0 |
| @@ -297,13 +357,21 @@ class cspull(ctools.cscript): | @@ -297,13 +357,21 @@ class cspull(ctools.cscript): | ||
| 297 | 357 | ||
| 298 | # Write simulation results | 358 | # Write simulation results |
| 299 | if self._logNormal(): | 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 | self._log(nevents) | 370 | self._log(nevents) |
| 303 | - self._log("\n") | 371 | + self._log('\n') |
| 304 | 372 | ||
| 305 | # Fit model | 373 | # Fit model |
| 306 | - if self["profile"].boolean(): | 374 | + if self['profile'].boolean(): |
| 307 | models = self._obs.models() | 375 | models = self._obs.models() |
| 308 | for i in range(models.size()): | 376 | for i in range(models.size()): |
| 309 | model_name = models[i].name() | 377 | model_name = models[i].name() |
| @@ -324,17 +392,17 @@ class cspull(ctools.cscript): | @@ -324,17 +392,17 @@ class cspull(ctools.cscript): | ||
| 324 | 392 | ||
| 325 | # Write result header | 393 | # Write result header |
| 326 | if self._logNormal(): | 394 | if self._logNormal(): |
| 327 | - self._log.header3("Pulls") | 395 | + self._log.header3('Pulls') |
| 328 | 396 | ||
| 329 | # Gather results | 397 | # Gather results |
| 330 | colnames = [] | 398 | colnames = [] |
| 331 | values = {} | 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 | for i in range(models.size()): | 406 | for i in range(models.size()): |
| 339 | model = models[i] | 407 | model = models[i] |
| 340 | model_name = model.name() | 408 | model_name = model.name() |
| @@ -343,12 +411,12 @@ class cspull(ctools.cscript): | @@ -343,12 +411,12 @@ class cspull(ctools.cscript): | ||
| 343 | if par.is_free(): | 411 | if par.is_free(): |
| 344 | 412 | ||
| 345 | # Set parameter name | 413 | # Set parameter name |
| 346 | - name = model_name+"_"+par.name() | 414 | + name = model_name+'_'+par.name() |
| 347 | 415 | ||
| 348 | # Append parameter, Pull_parameter and Unc_parameter | 416 | # Append parameter, Pull_parameter and Unc_parameter |
| 349 | colnames.append(name) | 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 | # Compute pull | 421 | # Compute pull |
| 354 | fitted_value = par.value() | 422 | fitted_value = par.value() |
| @@ -361,18 +429,18 @@ class cspull(ctools.cscript): | @@ -361,18 +429,18 @@ class cspull(ctools.cscript): | ||
| 361 | 429 | ||
| 362 | # Store results | 430 | # Store results |
| 363 | values[name] = fitted_value | 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 | # Write result | 435 | # Write result |
| 368 | if self._logNormal(): | 436 | if self._logNormal(): |
| 369 | self._log.parformat(name) | 437 | self._log.parformat(name) |
| 370 | self._log(pull) | 438 | self._log(pull) |
| 371 | - self._log(" (") | 439 | + self._log(' (') |
| 372 | self._log(fitted_value) | 440 | self._log(fitted_value) |
| 373 | - self._log(" +/- ") | 441 | + self._log(' +/- ') |
| 374 | self._log(error) | 442 | self._log(error) |
| 375 | - self._log(")\n") | 443 | + self._log(')\n') |
| 376 | 444 | ||
| 377 | # Bundle together results | 445 | # Bundle together results |
| 378 | result = {'colnames': colnames, 'values': values} | 446 | result = {'colnames': colnames, 'values': values} |
| @@ -384,7 +452,7 @@ class cspull(ctools.cscript): | @@ -384,7 +452,7 @@ class cspull(ctools.cscript): | ||
| 384 | # Public methods | 452 | # Public methods |
| 385 | def run(self): | 453 | def run(self): |
| 386 | """ | 454 | """ |
| 387 | - Run the script. | 455 | + Run the script |
| 388 | """ | 456 | """ |
| 389 | # Switch screen logging on in debug mode | 457 | # Switch screen logging on in debug mode |
| 390 | if self._logDebug(): | 458 | if self._logDebug(): |
| @@ -395,25 +463,29 @@ class cspull(ctools.cscript): | @@ -395,25 +463,29 @@ class cspull(ctools.cscript): | ||
| 395 | 463 | ||
| 396 | # Write observation into logger | 464 | # Write observation into logger |
| 397 | if self._logTerse(): | 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 | self._log(str(self._obs)) | 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 | # If several observations and binned: prepare stacked irfs | 475 | # If several observations and binned: prepare stacked irfs |
| 404 | - if self._obs.size() > 1 and self._enumbins > 0: | 476 | + if stacked: |
| 405 | self._set_stacked_irf() | 477 | self._set_stacked_irf() |
| 406 | 478 | ||
| 407 | # Write header | 479 | # Write header |
| 408 | if self._logTerse(): | 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 | # Loop over trials | 484 | # Loop over trials |
| 413 | for seed in range(self._ntrials): | 485 | for seed in range(self._ntrials): |
| 414 | 486 | ||
| 415 | # Make a trial and add initial seed | 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 | # Write out result immediately | 490 | # Write out result immediately |
| 419 | if seed == 0: | 491 | if seed == 0: |
| @@ -434,7 +506,7 @@ class cspull(ctools.cscript): | @@ -434,7 +506,7 @@ class cspull(ctools.cscript): | ||
| 434 | 506 | ||
| 435 | def execute(self): | 507 | def execute(self): |
| 436 | """ | 508 | """ |
| 437 | - Execute the script. | 509 | + Execute the script |
| 438 | """ | 510 | """ |
| 439 | # Open logfile | 511 | # Open logfile |
| 440 | self.logFileOpen() | 512 | self.logFileOpen() |
| @@ -447,10 +519,15 @@ class cspull(ctools.cscript): | @@ -447,10 +519,15 @@ class cspull(ctools.cscript): | ||
| 447 | 519 | ||
| 448 | def models(self, models): | 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 | # Return | 532 | # Return |
| 456 | return | 533 | return |
cscripts/obsutils.py
| @@ -24,46 +24,58 @@ import ctools | @@ -24,46 +24,58 @@ import ctools | ||
| 24 | # ===================== # | 24 | # ===================== # |
| 25 | # Simulate observations # | 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 | # Allocate ctobssim application and set parameters | 68 | # Allocate ctobssim application and set parameters |
| 52 | sim = ctools.ctobssim(obs) | 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 | # Optionally open the log file | 75 | # Optionally open the log file |
| 57 | if log: | 76 | if log: |
| 58 | sim.logFileOpen() | 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 | # Run ctobssim application. This will loop over all observations in the | 79 | # Run ctobssim application. This will loop over all observations in the |
| 68 | # container and simulation the events for each observation. Note that | 80 | # container and simulation the events for each observation. Note that |
| 69 | # events are not added together, they still apply to each observation | 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,45 +85,42 @@ def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, nbins=0, | ||
| 73 | # Binned option? | 85 | # Binned option? |
| 74 | if nbins > 0: | 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 | # Allocate ctbin application and set parameters | 105 | # Allocate ctbin application and set parameters |
| 92 | bin = ctools.ctbin(sim.obs()) | 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 | # Optionally open the log file | 120 | # Optionally open the log file |
| 105 | if log: | 121 | if log: |
| 106 | bin.logFileOpen() | 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 | # Run ctbin application. This will loop over all observations in | 124 | # Run ctbin application. This will loop over all observations in |
| 116 | # the container and bin the events in counts maps | 125 | # the container and bin the events in counts maps |
| 117 | bin.run() | 126 | bin.run() |
src/ctexpcube/ctexpcube.cpp
| @@ -220,12 +220,7 @@ void ctexpcube::run(void) | @@ -220,12 +220,7 @@ void ctexpcube::run(void) | ||
| 220 | // Write observation(s) into logger | 220 | // Write observation(s) into logger |
| 221 | if (logTerse()) { | 221 | if (logTerse()) { |
| 222 | log << std::endl; | 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 | log << m_obs << std::endl; | 224 | log << m_obs << std::endl; |
| 230 | } | 225 | } |
| 231 | 226 |
src/ctlike/ctlike.cpp
| @@ -230,13 +230,8 @@ void ctlike::run(void) | @@ -230,13 +230,8 @@ void ctlike::run(void) | ||
| 230 | // Write observation(s) into logger | 230 | // Write observation(s) into logger |
| 231 | if (logTerse()) { | 231 | if (logTerse()) { |
| 232 | log << std::endl; | 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 | // Optimize model parameters using LM optimizer | 237 | // Optimize model parameters using LM optimizer |
| @@ -311,7 +306,7 @@ void ctlike::run(void) | @@ -311,7 +306,7 @@ void ctlike::run(void) | ||
| 311 | if (logTerse()) { | 306 | if (logTerse()) { |
| 312 | log << std::endl; | 307 | log << std::endl; |
| 313 | log.header1("Maximum likelihood optimisation results"); | 308 | log.header1("Maximum likelihood optimisation results"); |
| 314 | - log << *m_opt << std::endl; | 309 | + log << m_opt->print(m_chatter) << std::endl; |
| 315 | log << gammalib::parformat("Maximum log likelihood"); | 310 | log << gammalib::parformat("Maximum log likelihood"); |
| 316 | log << gammalib::str(m_logL,3) << std::endl; | 311 | log << gammalib::str(m_logL,3) << std::endl; |
| 317 | log << gammalib::parformat("Observed events (Nobs)"); | 312 | log << gammalib::parformat("Observed events (Nobs)"); |
| @@ -321,7 +316,7 @@ void ctlike::run(void) | @@ -321,7 +316,7 @@ void ctlike::run(void) | ||
| 321 | log << " (Nobs - Npred = "; | 316 | log << " (Nobs - Npred = "; |
| 322 | log << gammalib::str(num_events-npred); | 317 | log << gammalib::str(num_events-npred); |
| 323 | log << ")" << std::endl; | 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 | // Restore energy dispersion flag for all CTA observations | 322 | // Restore energy dispersion flag for all CTA observations |
| @@ -430,6 +425,7 @@ void ctlike::get_parameters(void) | @@ -430,6 +425,7 @@ void ctlike::get_parameters(void) | ||
| 430 | m_refit = (*this)["refit"].boolean(); | 425 | m_refit = (*this)["refit"].boolean(); |
| 431 | m_apply_edisp = (*this)["edisp"].boolean(); | 426 | m_apply_edisp = (*this)["edisp"].boolean(); |
| 432 | m_fix_spat_for_ts = (*this)["fix_spat_for_ts"].boolean(); | 427 | m_fix_spat_for_ts = (*this)["fix_spat_for_ts"].boolean(); |
| 428 | + m_chatter = static_cast<GChatter>((*this)["chatter"].integer()); | ||
| 433 | 429 | ||
| 434 | // Optionally read ahead parameters so that they get correctly | 430 | // Optionally read ahead parameters so that they get correctly |
| 435 | // dumped into the log file | 431 | // dumped into the log file |
| @@ -592,6 +588,7 @@ void ctlike::init_members(void) | @@ -592,6 +588,7 @@ void ctlike::init_members(void) | ||
| 592 | m_opt = NULL; | 588 | m_opt = NULL; |
| 593 | m_apply_edisp = false; | 589 | m_apply_edisp = false; |
| 594 | m_fix_spat_for_ts = false; | 590 | m_fix_spat_for_ts = false; |
| 591 | + m_chatter = static_cast<GChatter>(2); | ||
| 595 | 592 | ||
| 596 | // Set logger properties | 593 | // Set logger properties |
| 597 | log.date(true); | 594 | log.date(true); |
| @@ -628,6 +625,7 @@ void ctlike::copy_members(const ctlike& app) | @@ -628,6 +625,7 @@ void ctlike::copy_members(const ctlike& app) | ||
| 628 | m_opt = app.m_opt->clone(); | 625 | m_opt = app.m_opt->clone(); |
| 629 | m_apply_edisp = app.m_apply_edisp; | 626 | m_apply_edisp = app.m_apply_edisp; |
| 630 | m_fix_spat_for_ts = app.m_fix_spat_for_ts; | 627 | m_fix_spat_for_ts = app.m_fix_spat_for_ts; |
| 628 | + m_chatter = app.m_chatter; | ||
| 631 | 629 | ||
| 632 | // Return | 630 | // Return |
| 633 | return; | 631 | return; |
src/ctlike/ctlike.hpp
| @@ -77,6 +77,7 @@ protected: | @@ -77,6 +77,7 @@ protected: | ||
| 77 | GFilename m_outmodel; //!< Source model output XML file name | 77 | GFilename m_outmodel; //!< Source model output XML file name |
| 78 | bool m_apply_edisp; //!< Apply energy dispersion? | 78 | bool m_apply_edisp; //!< Apply energy dispersion? |
| 79 | bool m_fix_spat_for_ts; //!< Fix spatial parameters for TS computation? | 79 | bool m_fix_spat_for_ts; //!< Fix spatial parameters for TS computation? |
| 80 | + GChatter m_chatter; //!< Chattiness | ||
| 80 | 81 | ||
| 81 | // Members | 82 | // Members |
| 82 | GObservations m_obs; //!< Observations | 83 | GObservations m_obs; //!< Observations |