GLVis  v4.2
Accurate and flexible finite element visualization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
glvis_driver.py
Go to the documentation of this file.
1 # Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
2 # at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 # LICENSE and NOTICE for details. LLNL-CODE-443271.
4 #
5 # This file is part of the GLVis visualization tool and library. For more
6 # information and source code availability see https://glvis.org.
7 #
8 # GLVis is free software; you can redistribute it and/or modify it under the
9 # terms of the BSD-3 license. We welcome feedback and contributions, see file
10 # CONTRIBUTING.md for details.
11 
12 import argparse
13 import sys
14 import os
15 from skimage.io import imread
16 from skimage.metrics import structural_similarity
17 
18 # Below are key commands that are passed to the -keys command-line argument for
19 # glvis in order to perform testing on raw mesh/grid function data (i.e. non-
20 # streams).
21 #
22 # Currently not in use.
23 test_cases = {
24  "magnify": "*****",
25  "axes1": "a",
26  "axes2": "aa",
27  "mesh1": "m",
28  "mesh2": "mm",
29  "cut_plane": "i",
30  "cut_plane_rotate": "iyyyy",
31  "cut_plane_rotate_back": "iyyyyYYYY",
32  "cut_plane_transl": "izzzz",
33  "cut_plane_transl_back": "izzzzZZZZ",
34  "orient2d_1": "R",
35  "orient2d_2": "RR",
36  "orient2d_3": "RRR",
37  "orient2d_4": "RRRR",
38  "orient2d_5": "RRRRR",
39  "orient2d_6": "RRRRRR",
40  "orient3d": "Rr",
41  "perspective": "j",
42 }
43 
44 screenshot_keys = "Sq"
45 screenshot_file = "GLVis_s01.png"
46 
47 cutoff_ssim = 0.999
48 
49 def compare_images(baseline_file, output_file, expect_fail=False):
50  # Try to open output image
51  output_img = imread(output_file)
52  if output_img is None:
53  print("[FAIL] Could not open output image.")
54  return False
55 
56  # Try to open baseline image
57  baseline_img = imread(baseline_file)
58  if baseline_img is None:
59  print("[IGNORE] No baseline exists to compare against.")
60  return True
61 
62  # Compare images with SSIM metrics. For two exactly-equal images, SSIM=1.0.
63  # We set a cutoff of 0.999 to account for possible differences in rendering.
64  ssim = structural_similarity(baseline_img, output_img, multichannel=True)
65  if ssim < cutoff_ssim:
66  if expect_fail:
67  print("[PASS] Differences were detected in the control case.")
68  else:
69  print("[FAIL] Output and baseline are different.")
70  else:
71  if expect_fail:
72  print("[FAIL] Differences were not detected in the control case.")
73  else:
74  print("[PASS] Images match.")
75  print(" actual ssim = {}, cutoff = {}".format(ssim, cutoff_ssim))
76  return ssim >= cutoff_ssim if not expect_fail else ssim < cutoff_ssim
77 
78 # Function to test a given glvis command with a variety of key-based commands.
79 # Not currently in use.
80 def test_case(exec_path, exec_args, baseline, t_group, t_name, cmd):
81  print("Testing {0}:{1}...".format(t_group, t_name))
82  full_screenshot_cmd = cmd + screenshot_keys
83  cmd = "{0} {1} -k \"{2}\"".format(exec_path, exec_args, full_screenshot_cmd)
84  print("Exec: {}".format(cmd))
85  ret = os.system(cmd + " > /dev/null 2>&1")
86  if ret != 0:
87  print("[FAIL] GLVis exited with error code {}.".format(ret))
88  return False
89  if not os.path.exists(t_group):
90  os.mkdir(t_group)
91  output_name = "{0}/{1}.png".format(t_group, t_name)
92 
93  ret = os.system("mv {0} {1}".format(screenshot_file, output_name))
94  if ret != 0:
95  print("[FAIL] Could not move output image: exit code {}.".format(ret))
96  return False
97 
98  if baseline:
99  baseline_name = "{0}/test.{1}.png".format(baseline, test_name)
100  return compare_images(baseline_name, output_name)
101  else:
102  print("[IGNORE] No baseline exists to compare against.")
103  return True
104 
105 def test_stream(exec_path, exec_args, save_file, baseline):
106  if exec_args is None:
107  exec_args = ""
108  test_name = os.path.basename(save_file)
109  print("Testing {}...".format(save_file))
110 
111  # Create new stream file with command to screenshot and close
112  stream_data = None
113  with open(save_file) as in_f:
114  stream_data = in_f.read()
115 
116  output_name = "test.{}.png".format(test_name)
117  output_name_fail = "test.fail.{}.png".format(test_name)
118  tmp_file = "test.saved"
119  with open(tmp_file, 'w') as out_f:
120  out_f.write(stream_data)
121  out_f.write("\nwindow_size 800 600")
122  out_f.write("\nscreenshot {}".format(output_name))
123  # Zooming in should create some difference in the images
124  out_f.write("\nkeys *")
125  out_f.write("\nscreenshot {}".format(output_name_fail))
126  out_f.write("\nkeys q")
127 
128  # Run GLVis with modified stream file
129  cmd = "{0} {1} -saved {2}".format(exec_path, exec_args, tmp_file)
130  print("Exec: {}".format(cmd))
131  ret = os.system(cmd)
132  if ret != 0:
133  print("[FAIL] GLVis exited with error code {}.".format(ret))
134  return False
135 
136  if baseline:
137  baseline_name = "{0}/test.{1}.png".format(baseline, test_name)
138  test_baseline = compare_images(baseline_name, output_name)
139  test_control = compare_images(baseline_name, output_name_fail,
140  expect_fail=True)
141  return (test_baseline and test_control)
142  else:
143  print("[IGNORE] No baseline exists to compare against.")
144  return True
145 
146 def test_cmd(exec_path, exec_args, tgroup, baseline):
147  try:
148  os.remove(screenshot_file)
149  except OSError:
150  pass
151  all_tests_passed = True
152  for testname, cmds in test_cases.items():
153  result = test_case(exec_path, exec_args, baseline, tgroup, testname, cmds)
154  all_tests_passed = all_tests_passed and result
155 
156  if all_tests_passed:
157  print("All tests passed.")
158  else:
159  sys.exit(1)
160 
161 if __name__ == "__main__":
162  parser = argparse.ArgumentParser()
163  parser.add_argument("-s", "--save_stream", help="Path to a GLVis saved stream file.")
164  parser.add_argument("-e", "--exec_cmd", help="Path to the GLVis executable")
165  parser.add_argument("-a", "--exec_args", help="Arguments to pass to GLVis.")
166  parser.add_argument("-n", "--group_name", help="Name of the test group.")
167  parser.add_argument("-b", "--baseline", help="Path to test baseline.")
168  args = parser.parse_args()
169  if args.save_stream is not None:
170  result = test_stream(args.exec_cmd, args.exec_args, args.save_stream, args.baseline)
171  if not result:
172  sys.exit(1)
173  else:
174  test_cmd(args.exec_cmd, args.exec_args, args.group_name, args.baseline)
def compare_images
Definition: glvis_driver.py:49