Commit 0838e2611f7cca4896c3c6062c06eeca2cd1d812

Authored by Jürgen Knödlseder
1 parent 4c6494dd

Add unit test for csinfo (#1828)

cscripts/csinfo.py
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 # ========================================================================== 2 # ==========================================================================
3 # Print info about Gammalib / ctools to the console. 3 # Print info about Gammalib / ctools to the console.
4 # 4 #
5 -# Copyright (C) 2015 Christoph Deil 5 +# Copyright (C) 2015-2016 Christoph Deil
6 # 6 #
7 # This program is free software: you can redistribute it and/or modify 7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by 8 # it under the terms of the GNU General Public License as published by
@@ -21,27 +21,18 @@ @@ -21,27 +21,18 @@
21 import sys 21 import sys
22 import os 22 import os
23 23
24 -  
25 -def get_command_output(cmd):  
26 - """Utility function to get command output on old and new Python versions.  
27 - """  
28 - try:  
29 - from subprocess import getoutput  
30 - except ImportError:  
31 - from commands import getoutput  
32 -  
33 - return getoutput(cmd)  
34 -  
35 -  
36 -# Copied and edited a bit from the `doc/source/reference_manual/index.rst` file  
37 -# The list there and here needs to be manually updated and kept in sync. 24 +# Copied and edited a bit from the `doc/source/users/reference_manual/index.rst`
  25 +# file. The list there and here needs to be manually updated and kept in sync.
38 CTOOL_LIST = """ 26 CTOOL_LIST = """
39 ctbin Generates counts cube 27 ctbin Generates counts cube
40 ctbkgcube Generates background cube 28 ctbkgcube Generates background cube
41 ctbutterfly Compute butterfly 29 ctbutterfly Compute butterfly
42 ctcubemask Filter counts cube 30 ctcubemask Filter counts cube
  31 + ctedispcube Generates energy dispersion cube
  32 + cterror Calculates likelihood profile errors
43 ctexpcube Generates exposure cube 33 ctexpcube Generates exposure cube
44 ctlike Performs maximum likelihood fitting 34 ctlike Performs maximum likelihood fitting
  35 + ctmapcube Generates a map cube
45 ctmodel Computes model counts cube 36 ctmodel Computes model counts cube
46 ctobssim Simulate CTA observations 37 ctobssim Simulate CTA observations
47 ctpsfcube Generates point spread function cube 38 ctpsfcube Generates point spread function cube
@@ -49,47 +40,112 @@ CTOOL_LIST = """ @@ -49,47 +40,112 @@ CTOOL_LIST = """
49 ctskymap Generates sky map 40 ctskymap Generates sky map
50 cttsmap Generates Test Statistics map 41 cttsmap Generates Test Statistics map
51 ctulimit Calculates upper limit 42 ctulimit Calculates upper limit
52 - cterror Calculates likelihood profile errors  
53 """ 43 """
54 CSCRIPT_LIST = """ 44 CSCRIPT_LIST = """
55 cscaldb Lists available instrument response functions 45 cscaldb Lists available instrument response functions
  46 + cslightcrv Computes lightcurve
56 csinfo Checks ctools and GammaLib installations 47 csinfo Checks ctools and GammaLib installations
  48 + csmodelinfo Shows model container content
  49 + csmodelmerge Merges several model containers into one file
57 csobsdef Generates observation definition file 50 csobsdef Generates observation definition file
58 - cslightcrv Computes lightcurve 51 + csobsinfo Shows observation container content
59 cspull Generates pull distribution 52 cspull Generates pull distribution
  53 + csresmap Generates residual map
60 cssens Computes CTA sensitivity 54 cssens Computes CTA sensitivity
61 csspec Computes spectral points 55 csspec Computes spectral points
62 - csresmap Generates residual map  
63 cstsdist Generates TS distribution 56 cstsdist Generates TS distribution
  57 + cstsmapsplit Creates commands to split the Test Statistic map computations
  58 + cstsmapmerge Merges slices from Test Statistic map computations\n
  59 + csobs2caldb Creates a caldb entry from an input observation
  60 + csiactdata Shows information about IACT data available on the user machine
  61 + csiactobs Generates observation definition file for IACT data from observation IDs
  62 + csfindobs Generates a list of IACT observation IDs
  63 + csiactcopy Copies IACT data from one location to another
64 """ 64 """
65 65
  66 +
  67 +# ============================================================ #
  68 +# Workaround for command output on old and new Python versions #
  69 +# ============================================================ #
  70 +def get_command_output(cmd):
  71 + """
  72 + Utility function to get command output on old and new Python versions
  73 +
  74 + Parameters
  75 + ----------
  76 + cmd : str
  77 + Command string
  78 +
  79 + Returns
  80 + -------
  81 + output : str
  82 + Command output
  83 + """
  84 + # Try to import getoutput from subprocess, alternatively get it from
  85 + # commands
  86 + try:
  87 + from subprocess import getoutput
  88 + except ImportError:
  89 + from commands import getoutput
  90 +
  91 + # Return command output
  92 + return getoutput(cmd)
  93 +
  94 +
  95 +# ===================================== #
  96 +# Workaround for print without linefeed #
  97 +# ===================================== #
66 def log(text, end='\n'): 98 def log(text, end='\n'):
67 - """Print text to console. 99 + """
  100 + Print text to console
68 101
69 Workaround to have an `end=''` option on old Pythons: 102 Workaround to have an `end=''` option on old Pythons:
70 http://stackoverflow.com/a/493399/498873 103 http://stackoverflow.com/a/493399/498873
71 """ 104 """
  105 + # Print without linefeed
72 sys.stdout.write(text + end) 106 sys.stdout.write(text + end)
73 107
  108 + # Return
  109 + return
74 110
  111 +
  112 +# ====================== #
  113 +# Print list information #
  114 +# ====================== #
75 def csinfo_list_tools(): 115 def csinfo_list_tools():
76 - """Print available ctools with one-line description to the console.  
77 """ 116 """
  117 + Print available ctools with one-line description to the console
  118 + """
  119 + # Print list of available ctools
78 print('\nAvailable ctools:') 120 print('\nAvailable ctools:')
79 print(CTOOL_LIST) 121 print(CTOOL_LIST)
  122 +
  123 + # Print list of available cscripts
80 print('Available cscripts:') 124 print('Available cscripts:')
81 print(CSCRIPT_LIST) 125 print(CSCRIPT_LIST)
82 126
  127 + # Return
  128 + return
83 129
84 -def csinfo_setup_check():  
85 - print('\nGammalib / ctools setup check:\n')  
86 130
  131 +# ======================= #
  132 +# Print check information #
  133 +# ======================= #
  134 +def csinfo_setup_check():
  135 + """
  136 + Print check information
  137 + """
  138 + # Initialise success flags
87 all_ok = True 139 all_ok = True
88 gammalib_environ = False 140 gammalib_environ = False
89 ctools_environ = False 141 ctools_environ = False
90 gammalib_python = False 142 gammalib_python = False
91 ctools_python = False 143 ctools_python = False
92 144
  145 + # Print header
  146 + print('\nGammalib / ctools setup check:\n')
  147 +
  148 + # Check if GAMMALIB is set
93 log(' GAMMALIB environment variable ... ', end='') 149 log(' GAMMALIB environment variable ... ', end='')
94 try: 150 try:
95 gammalib_env = os.environ['GAMMALIB'] 151 gammalib_env = os.environ['GAMMALIB']
@@ -99,6 +155,7 @@ def csinfo_setup_check(): @@ -99,6 +155,7 @@ def csinfo_setup_check():
99 all_ok = False 155 all_ok = False
100 gammalib_environ = True 156 gammalib_environ = True
101 157
  158 + # Check if CTOOLS is set
102 log(' CTOOLS environment variable ... ', end='') 159 log(' CTOOLS environment variable ... ', end='')
103 try: 160 try:
104 ctools_env = os.environ['CTOOLS'] 161 ctools_env = os.environ['CTOOLS']
@@ -108,6 +165,7 @@ def csinfo_setup_check(): @@ -108,6 +165,7 @@ def csinfo_setup_check():
108 all_ok = False 165 all_ok = False
109 ctools_environ = True 166 ctools_environ = True
110 167
  168 + # Check if gammalib Python module import works
111 log(' gammalib Python import .......... ', end='') 169 log(' gammalib Python import .......... ', end='')
112 try: 170 try:
113 import gammalib 171 import gammalib
@@ -117,6 +175,7 @@ def csinfo_setup_check(): @@ -117,6 +175,7 @@ def csinfo_setup_check():
117 all_ok = False 175 all_ok = False
118 gammalib_python = True 176 gammalib_python = True
119 177
  178 + # Check if ctools Python module import works
120 log(' ctools Python import .......... ', end='') 179 log(' ctools Python import .......... ', end='')
121 try: 180 try:
122 import ctools 181 import ctools
@@ -126,6 +185,8 @@ def csinfo_setup_check(): @@ -126,6 +185,8 @@ def csinfo_setup_check():
126 all_ok = False 185 all_ok = False
127 ctools_python = True 186 ctools_python = True
128 187
  188 + # Signal if everything is okay, or notify about the problems that have
  189 + # been encountered
129 if all_ok: 190 if all_ok:
130 print('\n ===> Your Gammalib / ctools setup is OK.') 191 print('\n ===> Your Gammalib / ctools setup is OK.')
131 else: 192 else:
@@ -138,64 +199,107 @@ def csinfo_setup_check(): @@ -138,64 +199,107 @@ def csinfo_setup_check():
138 print(' - Did you source gammalib-init.sh?') 199 print(' - Did you source gammalib-init.sh?')
139 print(' - Did you source ctools-init.sh ?') 200 print(' - Did you source ctools-init.sh ?')
140 print(' - Are you using the correct Python ?') 201 print(' - Are you using the correct Python ?')
141 -  
142 print('') 202 print('')
143 - print(' Gammalib: http://cta.irap.omp.eu/gammalib-devel/')  
144 - print(' ctools: http://cta.irap.omp.eu/ctools-devel/')  
145 - 203 + print(' Gammalib: http://cta.irap.omp.eu/gammalib/')
  204 + print(' ctools: http://cta.irap.omp.eu/ctools/')
146 print('') 205 print('')
147 206
  207 + # Return
  208 + return
148 209
149 -def csinfo_setup_info():  
150 - print('\nGammalib / ctools setup info:\n')  
151 -  
152 - gammalib_version = 'TODO' # a function needs to be added to the library to get the version  
153 - print(' Gammalib version ................. {0}'.format(gammalib_version))  
154 -  
155 - ctools_version = 'TODO' # a function needs to be added to the library to get the version  
156 - print(' ctools version ................. {0}'.format(ctools_version))  
157 -  
158 - gammalib_env = os.environ.get('GAMMALIB', 'Not found')  
159 - print(' $GAMMALIB environment variable ... {0}'.format(gammalib_env))  
160 210
161 - ctools_env = os.environ.get('CTOOLS', 'Not found')  
162 - print(' $CTOOLS environment variable ... {0}'.format(ctools_env))  
163 -  
164 - print(' Python executable ................ {0}'.format(sys.executable))  
165 -  
166 - log(' gammalib Python package ......... ', end='') 211 +# ======================= #
  212 +# Print setup information #
  213 +# ======================= #
  214 +def csinfo_setup_info():
  215 + """
  216 + Print setup information
  217 + """
  218 + # Try importing GammaLib, and flag if this was unsuccessful
167 try: 219 try:
168 import gammalib 220 import gammalib
169 - print(gammalib.__path__[0]) 221 + gammalib_path = gammalib.__path__[0]
  222 + gammalib_version = gammalib.__version__
170 except ImportError: 223 except ImportError:
171 - print('Not found') 224 + gammalib_path = 'Not found'
  225 + gammalib_version = 'Unknown'
172 226
173 - log(' ctools Python package ........ ', end='') 227 + # Try importing ctools, and flag if this was unsuccessful
174 try: 228 try:
175 import ctools 229 import ctools
176 - print(ctools.__path__[0]) 230 + ctools_path = ctools.__path__[0]
  231 + ctools_version = ctools.__version__
177 except ImportError: 232 except ImportError:
178 - print('Not found') 233 + ctools_path = 'Not found'
  234 + ctools_version = 'Unknown'
  235 +
  236 + # Get GAMMALIB and CTOOLS environment variables
  237 + gammalib_env = os.environ.get('GAMMALIB', 'Not found')
  238 + ctools_env = os.environ.get('CTOOLS', 'Not found')
  239 +
  240 + # Print header
  241 + print('\nGammalib / ctools setup info:\n')
179 242
  243 + # Print package versions
  244 + print(' Gammalib version ................. {0}'.format(gammalib_version))
  245 + print(' ctools version ................. {0}'.format(ctools_version))
  246 + print(' $GAMMALIB environment variable ... {0}'.format(gammalib_env))
  247 + print(' $CTOOLS environment variable ... {0}'.format(ctools_env))
  248 + print(' Python executable ................ {0}'.format(sys.executable))
  249 + print(' gammalib Python package ......... {0}'.format(gammalib_path))
  250 + print(' ctools Python package ........ {0}'.format(ctools_path))
180 print(' GAMMALIB CFLAGS ................. {0}'.format(get_pkg_config_info('cflags', 'gammalib'))) 251 print(' GAMMALIB CFLAGS ................. {0}'.format(get_pkg_config_info('cflags', 'gammalib')))
181 print(' CTOOLS CFLAGS ................. {0}'.format(get_pkg_config_info('cflags', 'ctools'))) 252 print(' CTOOLS CFLAGS ................. {0}'.format(get_pkg_config_info('cflags', 'ctools')))
182 -  
183 print(' GAMMALIB LIBS ................. {0}'.format(get_pkg_config_info('libs', 'gammalib'))) 253 print(' GAMMALIB LIBS ................. {0}'.format(get_pkg_config_info('libs', 'gammalib')))
184 print(' CTOOLS LIBS ................. {0}'.format(get_pkg_config_info('libs', 'ctools'))) 254 print(' CTOOLS LIBS ................. {0}'.format(get_pkg_config_info('libs', 'ctools')))
185 -  
186 print('') 255 print('')
187 256
  257 + # Return
  258 + return
  259 +
188 260
  261 +# =============================== #
  262 +# Get information from pkg-config #
  263 +# =============================== #
189 def get_pkg_config_info(info, library): 264 def get_pkg_config_info(info, library):
  265 + """
  266 + Get information from pkg-config
  267 +
  268 + Parameters
  269 + ----------
  270 + info : str
  271 + Information to extract
  272 + library : str
  273 + Library name for which information is to be extracted
  274 +
  275 + Returns
  276 + -------
  277 + out : str
  278 + Information string, 'Not available' if pkg-config is not installed
  279 + """
  280 + # Set pkg-config command
190 cmd = 'pkg-config --{0} {1}'.format(info, library) 281 cmd = 'pkg-config --{0} {1}'.format(info, library)
  282 +
  283 + # Execute command
191 out = get_command_output(cmd) 284 out = get_command_output(cmd)
192 - if 'was not found' in out:  
193 - return 'Not available'  
194 - else:  
195 - return out  
196 285
  286 + # If the command returns 'was not found' then pkg-config is not
  287 + # avaailable
  288 + if 'not found' in out:
  289 + out = 'Not available'
  290 +
  291 + # Return output
  292 + return out
197 293
  294 +
  295 +# ============================ #
  296 +# Print help text into console #
  297 +# ============================ #
198 def csinfo_print_help(): 298 def csinfo_print_help():
  299 + """
  300 + Print help text into console
  301 + """
  302 + # Print help text
199 print('\nPrint info about Gammalib and ctools to the console.\n') 303 print('\nPrint info about Gammalib and ctools to the console.\n')
200 print('Available commands:') 304 print('Available commands:')
201 print(' csinfo list List available ctools and cscripts') 305 print(' csinfo list List available ctools and cscripts')
@@ -203,14 +307,24 @@ def csinfo_print_help(): @@ -203,14 +307,24 @@ def csinfo_print_help():
203 print(' csinfo info Print Gammalib / ctools setup info') 307 print(' csinfo info Print Gammalib / ctools setup info')
204 print('') 308 print('')
205 309
  310 + # Return
  311 + return
  312 +
206 313
  314 +# ============================ #
  315 +# Print information to console #
  316 +# ============================ #
207 def csinfo(argv): 317 def csinfo(argv):
208 - """Print info about Gammalib / ctools to the console.  
209 """ 318 """
  319 + Print information about Gammalib and ctools to the console
  320 + """
  321 + # If there are no command line arguments then print help and exit
  322 + # with success
210 if len(argv) <= 1: 323 if len(argv) <= 1:
211 csinfo_print_help() 324 csinfo_print_help()
212 sys.exit(0) 325 sys.exit(0)
213 326
  327 + # Dispatch according to the command line argument
214 cmd = argv[1] 328 cmd = argv[1]
215 if cmd == 'list': 329 if cmd == 'list':
216 csinfo_list_tools() 330 csinfo_list_tools()
@@ -223,6 +337,14 @@ def csinfo(argv): @@ -223,6 +337,14 @@ def csinfo(argv):
223 csinfo_print_help() 337 csinfo_print_help()
224 sys.exit(-1) 338 sys.exit(-1)
225 339
  340 + # Return
  341 + return
226 342
  343 +
  344 +# ======================== #
  345 +# Main routine entry point #
  346 +# ======================== #
227 if __name__ == '__main__': 347 if __name__ == '__main__':
  348 +
  349 + # Run the script
228 csinfo(sys.argv) 350 csinfo(sys.argv)
test/test_cscaldb.py
@@ -29,9 +29,6 @@ from testing import test @@ -29,9 +29,6 @@ from testing import test
29 class Test(test): 29 class Test(test):
30 """ 30 """
31 Test class for cscaldb script 31 Test class for cscaldb script
32 -  
33 - This test class makes unit tests for the cslightcrv script by using it  
34 - from the command line and from Python.  
35 """ 32 """
36 33
37 # Constructor 34 # Constructor
test/test_csinfo.py 0 → 100755
  1 +#! /usr/bin/env python
  2 +# ==========================================================================
  3 +# This scripts performs unit tests for the csinfo script.
  4 +#
  5 +# Copyright (C) 2016 Juergen Knoedlseder
  6 +#
  7 +# This program is free software: you can redistribute it and/or modify
  8 +# it under the terms of the GNU General Public License as published by
  9 +# the Free Software Foundation, either version 3 of the License, or
  10 +# (at your option) any later version.
  11 +#
  12 +# This program is distributed in the hope that it will be useful,
  13 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 +# GNU General Public License for more details.
  16 +#
  17 +# You should have received a copy of the GNU General Public License
  18 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
  19 +#
  20 +# ==========================================================================
  21 +import gammalib
  22 +import cscripts
  23 +from testing import test
  24 +
  25 +
  26 +# ============================ #
  27 +# Test class for csinfo script #
  28 +# ============================ #
  29 +class Test(test):
  30 + """
  31 + Test class for csinfo script
  32 + """
  33 +
  34 + # Constructor
  35 + def __init__(self):
  36 + """
  37 + Constructor.
  38 + """
  39 + # Call base class constructor
  40 + test.__init__(self)
  41 +
  42 + # Return
  43 + return
  44 +
  45 + # Set test functions
  46 + def set(self):
  47 + """
  48 + Set all test functions.
  49 + """
  50 + # Set test name
  51 + self.name('csinfo')
  52 +
  53 + # Append tests
  54 + self.append(self._test_cmd, 'Test csinfo on command line')
  55 +
  56 + # Return
  57 + return
  58 +
  59 + # Test csinfo on command line
  60 + def _test_cmd(self):
  61 + """
  62 + Test csinfo on the command line.
  63 + """
  64 + # Set script name
  65 + csinfo = self._script('csinfo')
  66 +
  67 + # Setup csinfo command
  68 + cmd = csinfo
  69 +
  70 + # Check if execution of wrong command fails
  71 + self.test_assert(self._execute('command_that_does_not_exist') != 0,
  72 + 'Self test of test script')
  73 +
  74 + # Execute script without arguments
  75 + self.test_assert(self._execute(cmd) == 0,
  76 + 'Check successful execution from command line')
  77 +
  78 + # Execute script with "list" argument
  79 + self.test_assert(self._execute(cmd+' list') == 0,
  80 + 'Check successful execution with "list" argument from command line')
  81 +
  82 + # Execute script with "check" argument
  83 + self.test_assert(self._execute(cmd+' check') == 0,
  84 + 'Check successful execution with "check" argument from command line')
  85 +
  86 + # Execute script with "info" argument
  87 + self.test_assert(self._execute(cmd+' info') == 0,
  88 + 'Check successful execution with "info" argument from command line')
  89 +
  90 + # Execute script with invalid argument
  91 + self.test_assert(self._execute(cmd+' not_a_valid_argument') != 0,
  92 + 'Check unsuccessful execution with unsupported argument from '
  93 + 'command line')
  94 +
  95 + # Return
  96 + return
test/test_python_cscripts.py
@@ -25,6 +25,7 @@ import cscripts @@ -25,6 +25,7 @@ import cscripts
25 sys.path.append(os.path.dirname(os.path.abspath(__file__))) 25 sys.path.append(os.path.dirname(os.path.abspath(__file__)))
26 import test_cscaldb 26 import test_cscaldb
27 import test_csfindobs 27 import test_csfindobs
  28 +import test_csinfo
28 import test_cslightcrv 29 import test_cslightcrv
29 import test_csmodelinfo 30 import test_csmodelinfo
30 import test_csmodelmerge 31 import test_csmodelmerge
@@ -105,6 +106,7 @@ def test(installed=False, debug=False): @@ -105,6 +106,7 @@ def test(installed=False, debug=False):
105 106
106 # Allocate test suites 107 # Allocate test suites
107 suite_cscaldb = test_cscaldb.Test() 108 suite_cscaldb = test_cscaldb.Test()
  109 + suite_csinfo = test_csinfo.Test()
108 suite_cslightcrv = test_cslightcrv.Test() 110 suite_cslightcrv = test_cslightcrv.Test()
109 suite_csmodelinfo = test_csmodelinfo.Test() 111 suite_csmodelinfo = test_csmodelinfo.Test()
110 suite_csmodelmerge = test_csmodelmerge.Test() 112 suite_csmodelmerge = test_csmodelmerge.Test()
@@ -123,6 +125,7 @@ def test(installed=False, debug=False): @@ -123,6 +125,7 @@ def test(installed=False, debug=False):
123 125
124 # Setup unit tests 126 # Setup unit tests
125 suite_cscaldb.set() 127 suite_cscaldb.set()
  128 + suite_csinfo.set()
126 suite_cslightcrv.set() 129 suite_cslightcrv.set()
127 suite_csmodelinfo.set() 130 suite_csmodelinfo.set()
128 suite_csmodelmerge.set() 131 suite_csmodelmerge.set()
@@ -141,6 +144,7 @@ def test(installed=False, debug=False): @@ -141,6 +144,7 @@ def test(installed=False, debug=False):
141 144
142 # Append tests to container 145 # Append tests to container
143 suites.append(suite_cscaldb) 146 suites.append(suite_cscaldb)
  147 + suites.append(suite_csinfo)
144 suites.append(suite_cslightcrv) 148 suites.append(suite_cslightcrv)
145 suites.append(suite_csmodelinfo) 149 suites.append(suite_csmodelinfo)
146 suites.append(suite_csmodelmerge) 150 suites.append(suite_csmodelmerge)