Commit 57e2fed7b3d343f2ff9b20abc14a8be956236535
Merge branch '2313-csobsinfo-access-pointing-ra-dec' into integration
# Conflicts: # ChangeLog # NEWS # doc/source/admin/release_history/1.6.rst
Showing
5 changed files
with
78 additions
and
65 deletions
ChangeLog
NEWS
| 1 | 1 | New Features and Important Changes in ctools 1.6.0 |
| 2 | 2 | |
| 3 | -13 February 2018 | |
| 3 | +14 February 2018 | |
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | Introduction |
| ... | ... | @@ -206,7 +206,7 @@ None |
| 206 | 206 | |
| 207 | 207 | csobsinfo - Return observation definition information |
| 208 | 208 | ----------------------------------------------------- |
| 209 | -None | |
| 209 | +Add ras() and decs() methods (#2313) | |
| 210 | 210 | |
| 211 | 211 | |
| 212 | 212 | csobsselect - Select observations | ... | ... |
cscripts/csobsinfo.py
| ... | ... | @@ -59,11 +59,11 @@ class csobsinfo(ctools.csobservation): |
| 59 | 59 | """ |
| 60 | 60 | Get parameters from parfile and setup the observation |
| 61 | 61 | """ |
| 62 | - # Get parameters | |
| 62 | + # Get parameters | |
| 63 | 63 | if self.obs().size() == 0: |
| 64 | 64 | self._require_inobs('csobsinfo::get_parameters') |
| 65 | 65 | self.obs(self._get_observations(False)) |
| 66 | - | |
| 66 | + | |
| 67 | 67 | # Initialise object position |
| 68 | 68 | self._obj_dir = gammalib.GSkyDir() |
| 69 | 69 | |
| ... | ... | @@ -83,7 +83,7 @@ class csobsinfo(ctools.csobservation): |
| 83 | 83 | |
| 84 | 84 | # Return |
| 85 | 85 | return |
| 86 | - | |
| 86 | + | |
| 87 | 87 | |
| 88 | 88 | # Public methods |
| 89 | 89 | def run(self): |
| ... | ... | @@ -96,7 +96,7 @@ class csobsinfo(ctools.csobservation): |
| 96 | 96 | |
| 97 | 97 | # Get parameters |
| 98 | 98 | self._get_parameters() |
| 99 | - | |
| 99 | + | |
| 100 | 100 | # Initialise arrays to store certain values for reuse |
| 101 | 101 | # Todo, think about using a python dictionary |
| 102 | 102 | self._offsets = [] |
| ... | ... | @@ -107,7 +107,7 @@ class csobsinfo(ctools.csobservation): |
| 107 | 107 | self._ebounds = gammalib.GEbounds() |
| 108 | 108 | self._gti = gammalib.GGti() |
| 109 | 109 | obs_names = [] |
| 110 | - | |
| 110 | + | |
| 111 | 111 | # Initialise output to be filled |
| 112 | 112 | ontime = 0.0 |
| 113 | 113 | livetime = 0.0 |
| ... | ... | @@ -115,12 +115,12 @@ class csobsinfo(ctools.csobservation): |
| 115 | 115 | n_eventbins = 0 |
| 116 | 116 | n_obs_binned = 0 |
| 117 | 117 | n_obs_unbinned = 0 |
| 118 | - | |
| 118 | + | |
| 119 | 119 | # Write header |
| 120 | 120 | if self._logTerse(): |
| 121 | 121 | self._log('\n') |
| 122 | 122 | self._log.header1(gammalib.number('Observation', self.obs().size())) |
| 123 | - | |
| 123 | + | |
| 124 | 124 | # Loop over observations |
| 125 | 125 | for obs in self.obs(): |
| 126 | 126 | |
| ... | ... | @@ -128,44 +128,44 @@ class csobsinfo(ctools.csobservation): |
| 128 | 128 | if not obs.classname() == 'GCTAObservation': |
| 129 | 129 | self._log('Skipping '+obs.instrument()+' observation\n') |
| 130 | 130 | continue |
| 131 | - | |
| 131 | + | |
| 132 | 132 | # Use observed object as observation name if name is not given |
| 133 | 133 | obs_name = obs.name() |
| 134 | 134 | if obs_name == '': |
| 135 | 135 | obs_name = obs.object() |
| 136 | - | |
| 136 | + | |
| 137 | 137 | # Logging |
| 138 | 138 | if self._logExplicit(): |
| 139 | 139 | self._log.header2(obs_name) |
| 140 | - | |
| 140 | + | |
| 141 | 141 | # Retrieve observation name |
| 142 | 142 | obs_names.append(obs_name) |
| 143 | - | |
| 143 | + | |
| 144 | 144 | # Retrieve energy boundaries |
| 145 | 145 | obs_bounds = obs.events().ebounds() |
| 146 | - | |
| 146 | + | |
| 147 | 147 | # Retrieve time interval |
| 148 | 148 | obs_gti = obs.events().gti() |
| 149 | - | |
| 149 | + | |
| 150 | 150 | # Compute mean time and dead time fraction in percent |
| 151 | 151 | deadfrac = (1.0-obs.deadc())*100.0 |
| 152 | - | |
| 152 | + | |
| 153 | 153 | # Retrieve pointing and store Ra,Dec |
| 154 | - pnt_dir = obs.pointing().dir() | |
| 154 | + pnt_dir = obs.pointing().dir() | |
| 155 | 155 | self._pnt_ra.append(pnt_dir.ra_deg()) |
| 156 | - self._pnt_dec.append(pnt_dir.dec_deg()) | |
| 157 | - | |
| 156 | + self._pnt_dec.append(pnt_dir.dec_deg()) | |
| 157 | + | |
| 158 | 158 | # If avaliable append energy boundaries |
| 159 | 159 | if obs_bounds.size() > 0 : |
| 160 | 160 | self._ebounds.append(obs_bounds.emin(),obs_bounds.emax()) |
| 161 | - | |
| 161 | + | |
| 162 | 162 | # Append time interval |
| 163 | 163 | self._gti.append(obs_gti.tstart(), obs_gti.tstop()) |
| 164 | - | |
| 164 | + | |
| 165 | 165 | # Increment global livetime and ontime |
| 166 | 166 | ontime += obs.ontime() |
| 167 | 167 | livetime += obs.livetime() |
| 168 | - | |
| 168 | + | |
| 169 | 169 | # Bookkeeping |
| 170 | 170 | if obs.eventtype() == 'CountsCube': |
| 171 | 171 | n_eventbins += obs.events().size() |
| ... | ... | @@ -190,10 +190,10 @@ class csobsinfo(ctools.csobservation): |
| 190 | 190 | if self._compute_offset: |
| 191 | 191 | offset = pnt_dir.dist_deg(self._obj_dir) |
| 192 | 192 | self._offsets.append(offset) |
| 193 | - | |
| 193 | + | |
| 194 | 194 | # Optionally log details |
| 195 | 195 | if self._logExplicit(): |
| 196 | - | |
| 196 | + | |
| 197 | 197 | # Log the observation energy range (if available) |
| 198 | 198 | self._log.parformat('Energy range') |
| 199 | 199 | if obs_bounds.size() == 0: |
| ... | ... | @@ -203,7 +203,7 @@ class csobsinfo(ctools.csobservation): |
| 203 | 203 | self._log(' - ') |
| 204 | 204 | self._log(str(obs_bounds.emax())) |
| 205 | 205 | self._log('\n') |
| 206 | - | |
| 206 | + | |
| 207 | 207 | # Log observation time interval |
| 208 | 208 | self._log.parformat('Time range (MJD)') |
| 209 | 209 | if obs_gti.size() == 0: |
| ... | ... | @@ -213,7 +213,7 @@ class csobsinfo(ctools.csobservation): |
| 213 | 213 | self._log(' - ') |
| 214 | 214 | self._log(str(obs_gti.tstop().mjd())) |
| 215 | 215 | self._log('\n') |
| 216 | - | |
| 216 | + | |
| 217 | 217 | # Log observation information |
| 218 | 218 | self._log_value(gammalib.EXPLICIT, 'Ontime', '%.3f s' % |
| 219 | 219 | obs.ontime()) |
| ... | ... | @@ -233,7 +233,7 @@ class csobsinfo(ctools.csobservation): |
| 233 | 233 | zenith) |
| 234 | 234 | self._log_value(gammalib.EXPLICIT, 'Azimuth angle', '%.2f deg' % |
| 235 | 235 | azimuth) |
| 236 | - | |
| 236 | + | |
| 237 | 237 | # Write summary header |
| 238 | 238 | self._log_header1(gammalib.NORMAL, 'Summary') |
| 239 | 239 | |
| ... | ... | @@ -258,7 +258,7 @@ class csobsinfo(ctools.csobservation): |
| 258 | 258 | mean_azimuth = '%.2f deg' % (sum(self._azimuths) / len(self._azimuths)) |
| 259 | 259 | else: |
| 260 | 260 | mean_azimuth = 'Unknown' |
| 261 | - | |
| 261 | + | |
| 262 | 262 | # Log mean offset, azimuth and zenith angle |
| 263 | 263 | self._log_header3(gammalib.NORMAL, 'Pointings') |
| 264 | 264 | self._log_value(gammalib.NORMAL, 'Mean offset angle', mean_offset) |
| ... | ... | @@ -323,48 +323,60 @@ class csobsinfo(ctools.csobservation): |
| 323 | 323 | |
| 324 | 324 | # Check if DS9 file is valid |
| 325 | 325 | if ds9file.url() != 'NONE': |
| 326 | - | |
| 326 | + | |
| 327 | 327 | # Write header |
| 328 | 328 | self._log_header1(gammalib.TERSE, 'Save pointings in DS9 file') |
| 329 | 329 | |
| 330 | 330 | # Log filename |
| 331 | 331 | self._log_value(gammalib.NORMAL, 'DS9 filename', ds9file.url()) |
| 332 | - | |
| 333 | - # Open file | |
| 332 | + | |
| 333 | + # Open file | |
| 334 | 334 | f = open(ds9file.url(),'w') |
| 335 | - | |
| 335 | + | |
| 336 | 336 | # Write coordinate system |
| 337 | 337 | f.write('fk5\n') |
| 338 | - | |
| 338 | + | |
| 339 | 339 | # Loop over pointings |
| 340 | 340 | for i in range(len(self._pnt_ra)): |
| 341 | - | |
| 341 | + | |
| 342 | 342 | # Create string |
| 343 | 343 | line = 'point(' |
| 344 | 344 | line += str(self._pnt_ra[i])+','+str(self._pnt_dec[i])+')' |
| 345 | 345 | line += ' # point=cross 20 width=3\n' |
| 346 | - | |
| 346 | + | |
| 347 | 347 | # Write to file |
| 348 | 348 | f.write(line) |
| 349 | - | |
| 349 | + | |
| 350 | 350 | # Close file |
| 351 | 351 | f.close() |
| 352 | - | |
| 352 | + | |
| 353 | 353 | # Return |
| 354 | - return | |
| 355 | - | |
| 354 | + return | |
| 355 | + | |
| 356 | 356 | def zeniths(self): |
| 357 | 357 | """ |
| 358 | 358 | Return zenith angles |
| 359 | 359 | """ |
| 360 | 360 | return self._zeniths |
| 361 | - | |
| 361 | + | |
| 362 | 362 | def azimuths(self): |
| 363 | 363 | """ |
| 364 | 364 | Return azimuth angles |
| 365 | 365 | """ |
| 366 | 366 | return self._azimuths |
| 367 | - | |
| 367 | + | |
| 368 | + def ras(self): | |
| 369 | + """ | |
| 370 | + Return pointings right ascension | |
| 371 | + """ | |
| 372 | + return self._pnt_ra | |
| 373 | + | |
| 374 | + def decs(self): | |
| 375 | + """ | |
| 376 | + Return pointings declination | |
| 377 | + """ | |
| 378 | + return self._pnt_dec | |
| 379 | + | |
| 368 | 380 | def offsets(self): |
| 369 | 381 | """ |
| 370 | 382 | Return offset angles |
| ... | ... | @@ -376,13 +388,13 @@ class csobsinfo(ctools.csobservation): |
| 376 | 388 | Return energy boundaries |
| 377 | 389 | """ |
| 378 | 390 | return self._ebounds |
| 379 | - | |
| 391 | + | |
| 380 | 392 | def gti(self): |
| 381 | 393 | """ |
| 382 | 394 | Return good time intervals |
| 383 | 395 | """ |
| 384 | 396 | return self._gti |
| 385 | - | |
| 397 | + | |
| 386 | 398 | |
| 387 | 399 | # ======================== # |
| 388 | 400 | # Main routine entry point # |
| ... | ... | @@ -391,6 +403,6 @@ if __name__ == '__main__': |
| 391 | 403 | |
| 392 | 404 | # Create instance of application |
| 393 | 405 | app = csobsinfo(sys.argv) |
| 394 | - | |
| 406 | + | |
| 395 | 407 | # Execute application |
| 396 | 408 | app.execute() | ... | ... |
doc/source/admin/release_history/1.6.rst
| ... | ... | @@ -22,6 +22,8 @@ Bug fixes |
| 22 | 22 | Improvements |
| 23 | 23 | ------------ |
| 24 | 24 | |
| 25 | +* [`2313 <https://cta-redmine.irap.omp.eu/issues/2313>`_] - | |
| 26 | + Add `ras()` and `decs()` methods to :ref:`csobsinfo` | |
| 25 | 27 | * [`2311 <https://cta-redmine.irap.omp.eu/issues/2311>`_] - |
| 26 | 28 | Allow specifying of input skymap to :ref:`ctskymap` tool |
| 27 | 29 | * [`2309 <https://cta-redmine.irap.omp.eu/issues/2309>`_] - | ... | ... |
test/test_csobsinfo.py
| ... | ... | @@ -112,7 +112,7 @@ class Test(test): |
| 112 | 112 | obsinfo['ra'] = 83.63 |
| 113 | 113 | obsinfo['dec'] = 22.01 |
| 114 | 114 | obsinfo['logfile'] = 'csobsinfo_py1.log' |
| 115 | - obsinfo['chatter'] = 2 | |
| 115 | + obsinfo['chatter'] = 3 | |
| 116 | 116 | |
| 117 | 117 | # Run csobsinfo script and save XML file |
| 118 | 118 | obsinfo.logFileOpen() # Make sure we get a log file |
| ... | ... | @@ -122,21 +122,20 @@ class Test(test): |
| 122 | 122 | # Check DS9 file |
| 123 | 123 | self._check_ds9_file('csobsinfo_py1.reg') |
| 124 | 124 | |
| 125 | - # Set-up csobsinfo | |
| 126 | - obsinfo = cscripts.csobsinfo() | |
| 127 | - obsinfo['inobs'] = self._inobs | |
| 128 | - obsinfo['outds9file'] = 'csobsinfo_py2.reg' | |
| 129 | - obsinfo['offset'] = True | |
| 130 | - obsinfo['ra'] = 83.63 | |
| 131 | - obsinfo['dec'] = 22.01 | |
| 132 | - obsinfo['logfile'] = 'csobsinfo_py2.log' | |
| 133 | - obsinfo['chatter'] = 3 | |
| 134 | - | |
| 135 | - # Execute csobsinfo script | |
| 136 | - obsinfo.execute() | |
| 137 | - | |
| 138 | - # Check DS9 file | |
| 139 | - self._check_ds9_file('csobsinfo_py2.reg') | |
| 125 | + # Check result access methods | |
| 126 | + self.test_value(len(obsinfo.zeniths()), 1, 'Test number of zenith angles') | |
| 127 | + self.test_value(obsinfo.zeniths()[0], 0.0, 'Test zenith angle') | |
| 128 | + self.test_value(len(obsinfo.azimuths()), 1, 'Test number of azimuth angles') | |
| 129 | + self.test_value(obsinfo.azimuths()[0], 0.0, 'Test azimuth angle') | |
| 130 | + self.test_value(len(obsinfo.ras()), 1, 'Test number of Right Ascensions') | |
| 131 | + self.test_value(obsinfo.ras()[0], 83.63, 'Test Right Ascension') | |
| 132 | + self.test_value(len(obsinfo.decs()), 1, 'Test number of Declinations') | |
| 133 | + self.test_value(obsinfo.decs()[0], 22.51, 'Test Declination') | |
| 134 | + self.test_value(len(obsinfo.offsets()), 1, 'Test number of offsets') | |
| 135 | + self.test_value(obsinfo.offsets()[0], 0.5, 'Test offset angle') | |
| 136 | + self.test_value(obsinfo.ebounds().size(), 1, 'Test number of energy boundaries') | |
| 137 | + self.test_value(obsinfo.ebounds().emin().GeV(), 100.0, 'Test minimum energy') | |
| 138 | + self.test_value(obsinfo.ebounds().emax().TeV(), 100.0, 'Test maximum energy') | |
| 140 | 139 | |
| 141 | 140 | # Return |
| 142 | 141 | return |
| ... | ... | @@ -151,13 +150,12 @@ class Test(test): |
| 151 | 150 | |
| 152 | 151 | # Expect "fk5" in first line |
| 153 | 152 | line = f.readline().strip('\n') |
| 154 | - self.test_assert(line == 'fk5', | |
| 155 | - 'Check for "fk5" in first line') | |
| 153 | + self.test_value(line, 'fk5', | |
| 154 | + 'Test for "fk5" in first line of DS9 file') | |
| 156 | 155 | |
| 157 | 156 | # Expect "fk5" in first line |
| 158 | 157 | line = f.readline().strip('\n') |
| 159 | - self.test_assert(line[0:6] == 'point(', | |
| 160 | - 'Check for "point(" in second line') | |
| 158 | + self.test_value(line[0:6], 'point(', 'Test for "point(" in second line of DS9 file') | |
| 161 | 159 | |
| 162 | 160 | # Close file |
| 163 | 161 | f.close() | ... | ... |