xboa
CommonTest.py
Go to the documentation of this file.
1 import os
2 
3 from xboa import *
4 from xboa.core import *
5 from xboa.Hit import Hit
6 from xboa.Bunch import Bunch
7 from xboa.Common import rg
8 
10 run_test = xboa.test.TestTools.run_test
11 run_test_group = xboa.test.TestTools.run_test_group
12 __float_tol = xboa.test.TestTools.__float_tol
13 parse_tests = xboa.test.TestTools.parse_tests
14 __test_root_hist = xboa.test.TestTools.test_root_hist
15 __test_root_canvas = xboa.test.TestTools.test_root_canvas
16 __test_root_graph = xboa.test.TestTools.test_root_graph
17 
18 import StringIO
19 import sys
20 import time
21 import math
22 import string
23 import random
24 try:
25  Common.has_numpy()
26  import numpy
27  from numpy import linalg
28 except ImportError:
29  pass
30 try:
31  Common.has_multiprocessing()
32  import multiprocessing
33 except ImportError:
34  pass
35 
36 import operator
37 import bisect
38 
39 #=======================================================================================================================#
40 #====================== COMMON ==============================================================#
41 #=======================================================================================================================#
42 
44  out1 = open('test1.in', 'w')
45  if not out1: return 'warn'
46  out1.write('some test input\nis written here')
47  out1.close()
48  Common.substitute('test1.in', 'test1.out', {'some':'a bit of', 'test':'tested', 'input':'output', 'written':'read', 'there':'here', 'kx':'uga'})
49  out2 = open('test1.out', 'r')
50  if not out2: return 'warn'
51  lines = out2.readlines()
52  out2.close()
53  if not lines == ['a bit of tested output\n','is read here']: return 'fail'
54  os.remove('test1.in')
55  os.remove('test1.out')
56  return 'pass'
57 
59  fgh = []
60  for x in xyz:
61  fgh.append( __sin_x(x) )
62  return fgh
63 
64 def __sin_x(x):
65  y = []
66  for value in x:
67  y.append(math.sin(value))
68  return y
69 
70 
72  solution = Common.nd_newton_raphson1(__sin_x, [1., 1.e-5], [0.1, 0.1], [1.e-3,1.e-3])
73  y = __sin_x(solution)
74  if abs(y[0]) > 1e-5 or abs(y[1] > 1e-5):
75  return 'fail'
76  return 'pass'
77 
79  solution = Common.nd_newton_raphson2(__sin_x_one_pass, [1.e-5, 1.e-5], [0.1, 0.1], [1.e-3,1.e-3])
80  y = __sin_x(solution)
81  if abs(y[0]) > 1e-5 or abs(y[1] > 1e-5):
82  return 'fail'
83  return 'pass'
84 
86  try:
87  Common.has_root()
88  except:
89  return 'warn'
90  return 'pass'
91 
93  try:
94  Common.has_numpy()
95  except:
96  return 'warn'
97  return 'pass'
98 
100  try:
101  Common.has_json()
102  except:
103  return 'warn'
104  return 'pass'
105 
106 
108  testpass = True
109  canvas = Common.make_root_canvas('canvas_name')
110  testpass &= canvas.GetName().find('canvas_name') > -1
111  canvas = Common.make_root_canvas('canvas_name_2', 'canvas_title', bg_color=10, highlight_color=12, border_mode=1, frame_fill_color=2)
112  testpass &= __test_root_canvas(canvas, 'canvas_name_2', 'canvas_title', 10, 12, 1, 2)
113  if testpass: return 'pass'
114  return 'fail'
115 
117  testpass = True
118  n_p = 20000
119  testpass &= Common.n_bins(n_p, n_dimensions=1 ) == (n_p/10+1, 0, 0)
120  testpass &= Common.n_bins(n_p, n_dimensions=2) == (int(n_p**0.7/10.)+1, int(n_p**0.7/10.)+1, 0)
121  testpass &= Common.n_bins(n_p, n_dimensions=3) == (int(n_p**0.5/10.)+1, int(n_p**0.5/10.)+1, int(n_p**0.5/10.)+1)
122  testpass &= Common.n_bins(n_p, nx_bins=10, n_dimensions=3) == (10, int(n_p**0.5/10.)+1, int(n_p**0.5/10.)+1)
123  testpass &= Common.n_bins(n_p, ny_bins=10, n_dimensions=3) == (int(n_p**0.5/10.)+1, 10, int(n_p**0.5/10.)+1)
124  testpass &= Common.n_bins(n_p, nz_bins=10, n_dimensions=3) == (int(n_p**0.5/10.)+1, int(n_p**0.5/10.)+1, 10)
125  if testpass: return 'pass'
126  else: return 'fail'
127 
128 def __sine_list(const1, const2, list_of_x):
129  y = []
130  for x in list_of_x:
131  y.append(const1*math.sin(const2*x))
132  return y
133 
135  test_pass = True
136  out = Common.min_max([-0.1,-0.5,-0.9,0.0])
137  test_pass = test_pass and abs(out[0]--0.99) < __float_tol
138  test_pass = test_pass and abs(out[1]-+0.09) < __float_tol
139  out = Common.min_max(x_float_list=[-0.1,-0.5,-0.9,0.0], weight_list=[1,1,0,1])
140  test_pass = test_pass and abs(out[0]--0.55) < __float_tol
141  test_pass = test_pass and abs(out[1]-+0.05) < __float_tol
142  out = Common.min_max(x_float_list=[-0.1,-0.5,-0.9,0.0], weight_list=[1,1,0,1], margin=0.0)
143  test_pass = test_pass and abs(out[0]--0.5) < __float_tol
144  test_pass = test_pass and abs(out[1]-+0.0) < __float_tol
145  out = Common.min_max(x_float_list=[-0.1,-0.5,-0.9,0.0], weight_list=[1,1,0,1], margin=0.0, xmin=+100.)
146  test_pass = test_pass and abs(out[0]-100.) < __float_tol
147  test_pass = test_pass and abs(out[1]-+0.0) < __float_tol
148  out = Common.min_max(x_float_list=[-0.1,-0.5,-0.9,0.0], weight_list=[1,1,0,1], margin=0.0, xmax=-100.)
149  test_pass = test_pass and abs(out[0]--0.5) < __float_tol
150  test_pass = test_pass and abs(out[1]+100.) < __float_tol
151  out = Common.min_max([-10., 10.], [0.,0.])
152  test_pass = test_pass and abs(out[0]+1.) < __float_tol
153  test_pass = test_pass and abs(out[1]-1.) < __float_tol
154  if test_pass: return 'pass'
155  else: return 'fail'
156 
158  multilist = [[-1,1,0,7,4],['a','c','b','e','d'],['alfred','caltrops','bracken','elven','daphne']]
159  multilist = Common.multisort(multilist)
160 # print multilist
161  if multilist == [[-1,0,1,4,7],['a','b','c','d','e'],['alfred','bracken','caltrops','daphne','elven']]: return 'pass'
162  return 'fail'
163 
165  n = range(-21,101)
166  for i in range(len(n)): n[i] = float(n[i])**2 #note minimum is not n[0]
167  edges = Common.get_bin_edges(n, 20)
168  if len(edges) != 21: return 'fail'
169  if edges[0] != 0. or edges[-1] != n[-1]: return 'fail'
170  for i in range( len(edges) - 1):
171  if abs(edges[i+1] - edges[i] - n[-1]/20.) > __float_tol: return 'fail'
172 
173  edges = Common.get_bin_edges(n, 20, -10, 10)
174  for i,x in enumerate(edges):
175  if abs(x-float(i)+10.) > __float_tol: return 'fail'
176  return 'pass'
177 
178 
180  x_list = range(-200,10000)
181  y_list = range(-100,10100)
182  w_list = []
183  for i in range( len(x_list) ):
184  x_list[i] = float(x_list[i])/10.
185  y_list[i] = float(y_list[i])/20.
186  w_list.append(x_list[i])
187  bin_x = range(-15,100,10)
188  bin_y = range(-4, 200,10)
189 
190  c_1d = numpy.zeros((len(bin_x)-1,1))
191  c_2d = numpy.zeros((len(bin_x)-1,len(bin_y)-1))
192  c_2d_w = numpy.zeros((len(bin_x)-1,len(bin_y)-1))
193 
194  for i,x in enumerate(x_list):
195  p = bisect.bisect_right(bin_x,x_list[i])-1
196  q = bisect.bisect_right(bin_y,y_list[i])-1
197  if p>=0 and p<len(c_1d):
198  c_1d [p] += 1.
199  if q>=0 and q<len(c_2d[0]):
200  c_2d [p][q] += 1.
201  c_2d_w[p][q] += w_list[i]
202 
203  return ( (c_1d, c_2d, c_2d_w), (bin_x, bin_y), (x_list,y_list,w_list))
204 
206  testpass = True
207 
208  ((c_1d, c_2d, c_2d_w), (bin_x, bin_y), (x_list,y_list,w_list)) = __build_test_histogram()
209 
210  hist_1d = Common.histogram(x_list, bin_x)
211  hist_2d = Common.histogram(x_list, bin_x, y_list, bin_y)
212  hist_2d_w = Common.histogram(x_list, bin_x, y_list, bin_y, w_list)
213 
214  testpass &= hist_1d [1] == bin_x
215  testpass &= hist_2d [1] == bin_x and hist_2d [2] == bin_y
216  testpass &= hist_2d_w[1] == bin_x and hist_2d_w[2] == bin_y
217 
218  (pm,qm) = c_2d.shape
219  for p in range( pm ):
220  testpass &= abs(hist_1d[0][p,0] - c_1d[p,0]) < __float_tol
221  for q in range( qm ):
222  testpass &= abs(hist_2d [0][p,q] - c_2d [p,q]) < __float_tol
223  testpass &= abs(hist_2d_w[0][p,q] - c_2d_w[p,q]) < __float_tol
224 
225  return 'pass'
226 
228  x_list = range(0,10000)
229  w_list = []
230  for i in range( len(x_list) ):
231  x_list[i] = float(x_list[i])/10000.
232  w_list.append(x_list[i])
233  y_list = __sine_list(2., 2.*math.pi, x_list)
234  hist1 = Common.make_root_histogram('hist sin(x)', y_list, 'hist of x', 100)
235  hist2 = Common.make_root_histogram('hist sin(x)', y_list, 'hist of x', 50, x_list, 'hist of y', 50)
236  hist3 = Common.make_root_histogram('hist sin(x)', y_list, 'hist of x', 10, x_list, 'hist of y', 10, w_list)
237  testpass = __test_root_hist(hist3,'hist sin(x)','hist of x','hist of y',Common.min_max(y_list, w_list, rg.histo_margin)[0], Common.min_max(y_list, w_list, rg.histo_margin)[1],
238  Common.min_max(x_list, w_list, rg.histo_margin)[0], Common.min_max(x_list, w_list, rg.histo_margin)[1],
239  rg.line_color, rg.line_style, rg.line_width, rg.fill_color, '')
240  hist4 = Common.make_root_histogram('hist sin(x)', y_list, 'hist of x', 10, x_list, 'hist of y', 10, w_list, xmin=y_list[7500],xmax=y_list[2500],ymin=x_list[2500],ymax=x_list[7500],
241  line_color=1, line_style=2, line_width=3, fill_color=4, hist_title_string='title_string')
242  testpass = __test_root_hist(hist4,'hist sin(x)', 'hist of x', 'hist of y', y_list[7500], y_list[2500], x_list[2500], x_list[7500], 1, 2, 3, 4, 'title_string')
243  canvas1 = Common.make_root_canvas('hist_test1')
244  hist1.Draw()
245  canvas2 = Common.make_root_canvas('hist_test2')
246  hist2.Draw('cont1z')
247  canvas3 = Common.make_root_canvas('hist_test3')
248  hist3.Draw('lego')
249  canvas4 = Common.make_root_canvas('hist_test4')
250  hist4.Draw('lego')
251  if not testpass: return 'fail'
252  return 'pass'
253 
255  testpass = True
256  canvas = Common.make_root_canvas('graph_test')
257  x_list = range(0,100)
258  for i in range( len(x_list) ): x_list[i] = float(x_list[i])/100.
259  y_list = __sine_list(2., 2.*math.pi, x_list)
260  mm = Common.min_max(x_list) + Common.min_max(y_list)
261  (hist,graph) = Common.make_root_graph('test', x_list, 'x [2#pi rad]', y_list, 'a*sin(b*x)')
262  if not __test_root_hist(hist, '', 'x [2#pi rad]', 'a*sin(b*x)', mm[0], mm[1], mm[2], mm[3], rg.line_color, rg.line_style, rg.line_width, rg.fill_color, ''): return 'fail'
263  (hist,graph) = Common.make_root_graph('test', x_list, 'x [2#pi rad]', y_list, 'a*sin(b*x)', xmin=-1001., xmax=+1001, ymin=-1002., ymax=+1002.,line_color=201, line_style=202, line_width=203, fill_color=204, hist_title_string='mr title')
264  testpass &= __test_root_hist(hist, 'namey', 'x [2#pi rad]', 'a*sin(b*x)', -1001., +1001., -1002., +1002., rg.line_color, rg.line_style, rg.line_width, rg.fill_color, 'mr title')
265  testpass &= __test_root_graph(graph, 'namey', x_list, y_list, 201, 202, 203, 204)
266  (x_list, y_list) = ([3,2,1], [3,2,1]) #check that x_list and y_list are not changed by sort
267  (hist,graph) = Common.make_root_graph('test', x_list, 'x', y_list, 'y')
268  testpass &= (x_list, y_list) == ([3,2,1], [3,2,1])
269  hist.Draw()
270  graph.Draw()
271  Common.clear_root()
272  if testpass: return 'pass'
273  else: return 'fail'
274 
276  return 'fail'
277 
279  canvas = Common.make_root_canvas('multigraph_test')
280  x_list_of_lists = []
281  y_list_of_lists = []
282  for i in range(2):
283  x_list_of_lists.append(range(0,50))
284  for i in range( len(x_list_of_lists[-1]) ):
285  x_list_of_lists[-1][i] /= 10.
286  x_list_of_lists.append(range(0,100))
287  for i in range( len(x_list_of_lists[-1]) ):
288  x_list_of_lists[-1][i] /= 20.
289  for i in range( len(x_list_of_lists) ):
290  y_list_of_lists.append(__sine_list(i+1, i+1, x_list_of_lists[i]))
291  (hist,list_of_graphs) = Common.make_root_multigraph('test', x_list_of_lists, 'x [rad]', y_list_of_lists, 'a*sin(b*x)')
292  hist.Draw()
293  for graph in list_of_graphs:
294  graph.Draw()
295  return 'pass' # a test that can't fail - excellent!
296 
298  Common.wait_for_root() #cant test with a root canvas as i want to automate the test...
299  return 'pass'
300 
302  Common.has_matplot()
303  return 'pass'
304 
306  Common.wait_for_matplot()
307  return 'pass' # a test that can't fail - excellent!
308 
310  x_list = range(0,100)
311  for i in range( len(x_list) ): x_list[i] = float(x_list[i])/100.
312  y_list = __sine_list(2., 2.*math.pi, x_list)
313  myplot = Common.make_matplot_graph(x_list, 'x [2#pi rad]', y_list, 'a*sin(b*x)')
314  return 'pass' # a test that can't fail - excellent!
315 
317  x_list = range(0,10000)
318  w_list = []
319  for i in range( len(x_list) ):
320  x_list[i] = float(x_list[i])/10000.
321  w_list.append(x_list[i])
322  y_list = __sine_list(2., 2.*math.pi, x_list)
323  Common.make_matplot_histogram(y_list, 'hist of x', 100)
324  Common.make_matplot_histogram(y_list, 'hist of x', 50, x_list, 'hist of y', 50)
325  Common.make_matplot_histogram(y_list, 'hist of x', 10, x_list, 'hist of y', 10, w_list)
326  return 'pass' # a test that can't fail - excellent!
327 
329  x_list = range(0,10000)
330  for i in range( len(x_list) ):
331  x_list[i] = float(x_list[i])/10000.
332  y_list = __sine_list(2., 2.*math.pi, x_list)
333  Common.make_matplot_scatter(y_list, 'hist of x', x_list, 'hist of y')
334  return 'pass' # a test that can't fail - excellent!
335 
336 
338  x_list_of_lists = []
339  y_list_of_lists = []
340  for i in range(2):
341  x_list_of_lists.append(range(0,50))
342  for i in range( len(x_list_of_lists[-1]) ):
343  x_list_of_lists[-1][i] /= 10.
344  x_list_of_lists.append(range(0,100))
345  for i in range( len(x_list_of_lists[-1]) ):
346  x_list_of_lists[-1][i] /= 20.
347  for i in range( len(x_list_of_lists) ):
348  y_list_of_lists.append(__sine_list(i+1, i+1, x_list_of_lists[i]))
349  Common.make_matplot_multigraph(x_list_of_lists, 'x [rad]', y_list_of_lists, 'a*sin(b*x)')
350  return 'pass' # a test that can't fail - excellent!
351 
353  Common.matplot_show_and_continue()
354  return 'pass' # a test that can't fail - excellent!
355 
356 def __subprocess_function_1(some_arg, some_other_arg):
357  if some_arg != 'hello' and some_other_arg != 'world':
358  print 'error in common_subprocess_test - aborting'
359  sys._exit()
360  while True:
361  time.sleep(60)
362 
363 def __subprocess_function_2(some_arg, some_other_arg):
364  if some_arg != 'hello' and some_other_arg != 'world':
365  print 'error in common_subprocess_test - aborting'
366  sys._exit()
367  for i in range(5):
368  print i,' ',
369  print
370 
372  pass
373 
375  pid1 = Common.subprocess(__subprocess_function_1, ('hello', 'world'))
376  pid2 = Common.subprocess(__subprocess_function_2, ('hello', 'world'))
377  return 'pass'
378 
380  import random
381  list_1 = []
382  list_2 = []
383  list_3 = []
384  for i in range(10000): list_1.append( random.gauss(0., 1.) )
385  for i in range(10000): list_2.append( random.gauss(0., 1.) )
386  for i in range(10000): list_3.append( random.gauss(0.1, 1.1) )
387  testpass = True
388  testpass &= 1.-Common.kolmogorov_smirnov_test(list_1, list_1) < __float_tol
389  testpass &= Common.kolmogorov_smirnov_test(list_1, list_2) > 1e-3
390  testpass &= Common.kolmogorov_smirnov_test(list_1, list_3) < 1e-3
391  if testpass: return 'pass'
392  else: return 'fail'
393 
394 
395 def __is_alive(process):
396  if type(process) == type(1):
397  try:
398  os.kill(process, 0)
399  return True
400  except:
401  return False
402  else:
403  return process.is_alive()
404 
406  pid1 = Common.subprocess(__subprocess_function_1, ('hello', 'world'))
407  pid2 = Common.subprocess(__subprocess_function_2, ('hello', 'world'))
408  Common.kill_all_subprocesses()
409  if __is_alive(pid1) or __is_alive(pid2):
410  return 'fail - there is a known issue with python < 2.6 if using PyROOT'
411  return 'pass'
412 
413 
415  import random
416  for dim in range(2,5):
417  for v_count in range(10):
418  vector = numpy.matrix(numpy.zeros(dim))
419  for ind,value in numpy.ndenumerate(vector):
420  vector[ind] = random.random()
421  matrix_inverse = numpy.matrix(numpy.ones([dim,dim]))
422  for (i,j),value in numpy.ndenumerate(matrix_inverse):
423  if i != j: matrix_inverse[i,j] /= (i+1)/10./(j+1)
424  vector = Common.normalise_vector(vector, matrix_inverse)
425  if abs( (vector*matrix_inverse*vector.transpose())[0,0]-1. )>Common.float_tolerance:
426  return 'fail'
427  return 'pass'
428 
430  grid_list = ((2, 2), (3,2), (2,3),(2,4))
431  testpass = True
432  for grid_var in grid_list:
433  n_dim,n_per_dim = grid_var
434  grid = Common.make_grid(*grid_var)
435  #check there are correct number of particles
436  testpass &= len(grid)==n_per_dim**n_dim
437  #check there are no repeats
438  for i,vec1 in enumerate(grid):
439  for j,vec2 in enumerate(grid[i+1:]):
440  testpass &= ((vec1-vec2)*(vec1-vec2).transpose())[0,0] > Common.float_tolerance
441  #check on an integer multiple of grid spacing
442  for vec in grid:
443  for pos in vec.flat:
444  grid_spacing = (1./float(n_per_dim-1))
445  testpass &= abs(pos/grid_spacing-round(pos/grid_spacing)) < Common.float_tolerance
446  if testpass: return 'pass'
447  return 'fail'
448 
450  n_per_dim = 3
451  for dim in range(2,4):
452  matrix = numpy.matrix(numpy.ones([dim,dim]))
453  for (i,j),value in numpy.ndenumerate(matrix):
454  if i != j: matrix[i,j] *= 1./float(i+1)/float(j+1)
455  matrix_inverse = numpy.linalg.inv(matrix)
456  shell = Common.make_shell(n_per_dim, matrix)
457  #check there are correct number of particles
458  if not (len(shell)==n_per_dim**dim or len(shell)==n_per_dim**dim-1):
459  return 'fail'
460  #check they are normalised correctly
461  for vector in shell:
462  if abs( (vector*matrix_inverse*vector.transpose())[0,0]-1. )>Common.float_tolerance:
463  return 'fail'
464  return 'pass'
465 
466 
467 def __test_run(item):
468  if item == 'throw':
469  raise RuntimeError('Throwing item '+str(item))
470  time.sleep(random.random()) # returns to queue in random order
471  return 'output',item
472 
474  queue = multiprocessing.Queue()
475  Common.__function_with_queue((__test_run, queue, ("input",), 5))
476  assert queue.get() == (5, ("output", "input"))
477  Common.__function_with_queue((__test_run, queue, ("throw",), 7))
478  out = queue.get()
479  assert out[0] == 7
480  try:
481  Common.__function_with_queue(('no_args',))
482  assert False # should raise an exception in parent process
483  except Exception:
484  pass
485 
487  process_out = Common.process_list(__test_run, [(i,) for i in range(10)], 3)
488  for i in range(10):
489  assert process_out[i] == ('output',i) # check sorting
490 
492  test_results = []
493  tests = [common_substitute_test, common_min_max_test, common_multisort_test, common_histogram_test, common_get_bin_edges_test, common_subprocess_test, common_kill_subprocesses_test, common_n_bins_test, common_normalise_vector_test]
494  run_test_group(test_results, tests, [()]*len(tests))
495 
496  try:
497  Common.has_multiprocessing()
498  tests = [common_test_function_with_queue, common_test_process_list]
499  run_test_group(test_results, tests, [()]*len(tests))
500  except ImportError:
501  test_results.append('Warning - could not find multiprocessing. Skipping multiprocessing dependent tests')
502 
503 
504  try:
505  Common.has_numpy()
506  tests = [common_has_numpy_test, common_nd_newton_raphson1_test, common_nd_newton_raphson2_test]
507  run_test_group(test_results, tests, [()]*len(tests))
508  except ImportError:
509  test_results.append('Warning - could not find NumPy. Skipping NumPy dependent tests')
510 
511  try:
512  Common.has_root()
513  tests = [common_has_root_test, common_wait_for_root_test, common_make_root_canvas_test, common_make_root_graph_test, common_make_root_histogram_test,
514  common_make_root_multigraph_test, common_make_root_multigraph_test, common_kolmogorov_smirnov_test_test, common_make_grid_test, common_make_shell_test]
515  run_test_group(test_results, tests, [()]*len(tests))
516  except ImportError:
517  test_results.append('Warning - could not find ROOT. Skipping ROOT dependent tests')
518 
519  try:
520  Common.has_matplot()
521  tests = [common_has_matplot_test, common_wait_for_matplot_test, common_make_matplot_graph_test, common_make_matplot_histogram_test,
522  common_make_matplot_multigraph_test, common_make_matplot_scatter_test, common_show_matplot_and_continue_test]
523  run_test_group(test_results, tests, [()]*len(tests))
524  except ImportError:
525  test_results.append('Warning - could not find MatPlotLib. Skipping MatPlotLib dependent tests')
526 
527  results = parse_tests(test_results)
528 
529  print '\n============\n|| COMMON ||\n============'
530  print 'Passed ',results[0],' tests\nFailed ',results[1],' tests\n',results[2],' warnings\n\n\n'
531  return results
532 
533 if __name__ == "__main__":
534  test_common()
535 
536