Coverage for tests/musclex_tester.py: 87%
266 statements
« prev ^ index » next coverage.py v7.0.4, created at 2023-01-10 09:27 -0600
« prev ^ index » next coverage.py v7.0.4, created at 2023-01-10 09:27 -0600
1"""
2Copyright 1999 Illinois Institute of Technology
4Permission is hereby granted, free of charge, to any person obtaining
5a copy of this software and associated documentation files (the
6"Software"), to deal in the Software without restriction, including
7without limitation the rights to use, copy, modify, merge, publish,
8distribute, sublicense, and/or sell copies of the Software, and to
9permit persons to whom the Software is furnished to do so, subject to
10the following conditions:
12The above copyright notice and this permission notice shall be
13included in all copies or substantial portions of the Software.
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18IN NO EVENT SHALL ILLINOIS INSTITUTE OF TECHNOLOGY BE LIABLE FOR ANY
19CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23Except as contained in this notice, the name of Illinois Institute
24of Technology shall not be used in advertising or otherwise to promote
25the sale, use or other dealings in this Software without prior written
26authorization from Illinois Institute of Technology.
27"""
29import os
30import sys
31import unittest
32# import subprocess
33import shutil
34from time import gmtime, strftime
35import pandas as pd
36from musclex import __version__
37try:
38 from ..ui.EQStartWindowh import EQStartWindowh
39 from ..ui.QuadrantFoldingh import QuadrantFoldingh
40 from ..ui.DIImageWindowh import DIImageWindowh
41except: # for coverage
42 from ui.EQStartWindowh import EQStartWindowh
43 from ui.QuadrantFoldingh import QuadrantFoldingh
44 from ui.DIImageWindowh import DIImageWindowh
46class MuscleXGlobalTester(unittest.TestCase):
47 """
48 Unittest class testing musclex through headless version and comparing it to saved results created with GUI
49 """
50 @classmethod
51 def setUpClass(cls):
52 if getattr(sys, 'frozen', False):
53 cls.currdir = os.path.join(os.path.dirname(sys._MEIPASS), "musclex")
54 cls.run_cmd = "./musclex-main"
55 else:
56 cls.currdir = os.path.dirname(__file__)
57 cls.run_cmd = "musclex"
58 cls.inpath = os.path.join(cls.currdir, "test_images")
59 cls.testversion = __version__ # change this to test against a different version
60 cls.input_types = ['.adsc', '.cbf', '.edf', '.fit2d', '.mar345', '.marccd', '.pilatus', '.tif', '.hdf5', '.smv']
61 cls.logname = os.path.join(cls.currdir,"test_logs", "test.log")
62 if not os.path.isdir(os.path.dirname(cls.logname)):
63 os.mkdir(os.path.dirname(cls.logname))
64 if os.path.exists(cls.logname):
65 append_write = 'a'
66 else:
67 append_write = 'w'
69 with open(cls.logname, append_write) as lf:
70 lf.write("\n{}\n".format("-"*80))
71 lf.write("Beginning test at {}\n".format(strftime("%Y-%m-%d %H:%M:%S", gmtime())))
72 lf.write(f"Testing MuscleX version: {__version__}\n")
73 lf.write("\nSummary of Test Results\n")
75 @classmethod
76 def tearDownClass(cls):
77 with open(cls.logname, 'a') as lf:
78 lf.write("Ending test at {}\n".format(strftime("%Y-%m-%d %H:%M:%S", gmtime())))
79 lf.write(f'\n{"-"*80}\n')
81 ####### EQUATOR TEST #######
82 def testHeadlessMarEquator(self):
83 mar_dir = os.path.join(self.currdir, "testImages", "MARimages")
84 for filename in os.listdir(mar_dir):
85 _, ext = os.path.splitext(str(filename))
86 if ext in self.input_types:
87 f = os.path.join(mar_dir, filename)
88 EQStartWindowh(f, True, True, os.path.join(mar_dir, "eqsettings.json"))
89 # subprocess.Popen([self.run_cmd, os.path.join(self.currdir, "..", "main.py"), "eq", "-h", "-i", f, "-s", os.path.join(mar_dir, "eqsettings.json"), "-d"], cwd=self.currdir).wait()
91 print(f"\033[3;33m\nVerifying that generated headless Equator is equivalent to GUI Equator\033[0;3140m")
92 generated_results = os.path.join(mar_dir, "eq_results", "summary2.csv")
93 release_results = os.path.join(self.currdir, "testResults", "MARimages", "eq_results", "summary2.csv")
94 pass_test = True
95 file1 = pd.read_csv(generated_results).round(3) # Rounds up to 3 decimals to avoid computer errors
96 file2 = pd.read_csv(release_results).round(3)
97 res = pd.merge(file1, file2)
98 if len(res.index) != len(file1.index):
99 pass_test = False
100 if not pass_test:
101 print(f"\nTesting Equator on {mar_dir} ..... \033[0;31mFAILED\033[0;3140m\033[0;3840m")
102 print("Compare the following files for more information:\n" \
103 "File generated for testing: {p1}\nReference file: {p2}\n" \
104 .format(p1 = generated_results, p2 = release_results))
105 else:
106 print(f"Testing Equator on {mar_dir} ..... \033[0;32mPASSED\033[0;3140m")
107 self.log_results(pass_test, "Equator MAR Image")
108 self.assertTrue(pass_test,"Equator Image Headless Test for MAR image failed.")
110 # Remove cache folders
111 if os.path.exists(os.path.join(mar_dir, "eq_cache")):
112 shutil.rmtree(os.path.join(mar_dir, "eq_cache"))
114 def testHeadlessEigerEquator(self):
115 eiger_dir = os.path.join(self.currdir, "testImages", "EIGERimages")
116 for filename in os.listdir(eiger_dir):
117 _, ext = os.path.splitext(str(filename))
118 if ext in self.input_types:
119 f = os.path.join(eiger_dir, filename)
120 EQStartWindowh(f, True, True, os.path.join(eiger_dir, "eqsettings.json"))
121 # subprocess.Popen([self.run_cmd, os.path.join(self.currdir, "..", "main.py"), "eq", "-h", "-i", f, "-s", os.path.join(eiger_dir, "eqsettings.json"), "-d"], cwd=self.currdir).wait()
123 print(f"\033[3;33m\nVerifying that generated headless Equator is equivalent to GUI Equator\033[0;3140m")
124 generated_results = os.path.join(eiger_dir, "eq_results", "summary2.csv")
125 release_results = os.path.join(self.currdir, "testResults", "EIGERimages", "eq_results", "summary2.csv")
126 pass_test = True
127 file1 = pd.read_csv(generated_results).round(1)
128 file2 = pd.read_csv(release_results).round(1)
129 res = pd.merge(file1, file2)
130 if len(res.index) != len(file1.index):
131 pass_test = False
132 if not pass_test:
133 print(f"\nTesting Equator on {eiger_dir} ..... \033[0;31mFAILED\033[0;3140m\033[0;3840m")
134 print("Compare the following files for more information:\n" \
135 "File generated for testing: {p1}\nReference file: {p2}\n" \
136 .format(p1 = generated_results, p2 = release_results))
137 else:
138 print(f"Testing Equator on {eiger_dir} ..... \033[0;32mPASSED\033[0;3140m")
139 self.log_results(pass_test, "Equator EIGER Image")
140 self.assertTrue(pass_test,"Equator Image Headless Test for EIGER image failed.")
142 # Remove cache folders
143 if os.path.exists(os.path.join(eiger_dir, "eq_cache")):
144 shutil.rmtree(os.path.join(eiger_dir, "eq_cache"))
146 def testHeadlessPilatusEquator(self):
147 pilatus_dir = os.path.join(self.currdir, "testImages", "PILATUSimages")
148 for filename in os.listdir(pilatus_dir):
149 _, ext = os.path.splitext(str(filename))
150 if ext in self.input_types:
151 f = os.path.join(pilatus_dir, filename)
152 EQStartWindowh(f, True, True, os.path.join(pilatus_dir, "eqsettings.json"))
153 # subprocess.Popen([self.run_cmd, os.path.join(self.currdir, "..", "main.py"), "eq", "-h", "-i", f, "-s", os.path.join(pilatus_dir, "eqsettings.json"), "-d"], cwd=self.currdir).wait()
155 print(f"\033[3;33m\nVerifying that generated headless Equator is equivalent to GUI Equator\033[0;3140m")
156 generated_results = os.path.join(pilatus_dir, "eq_results", "summary2.csv")
157 release_results = os.path.join(self.currdir, "testResults", "PILATUSimages", "eq_results", "summary2.csv")
158 pass_test = True
159 file1 = pd.read_csv(generated_results).round(2)
160 file2 = pd.read_csv(release_results).round(2)
161 res = pd.merge(file1, file2)
162 if len(res.index) != len(file1.index):
163 pass_test = False
164 if not pass_test:
165 print(f"\nTesting Equator on {pilatus_dir} ..... \033[0;31mFAILED\033[0;3140m\033[0;3840m")
166 print("Compare the following files for more information:\n" \
167 "File generated for testing: {p1}\nReference file: {p2}\n" \
168 .format(p1 = generated_results, p2 = release_results))
169 else:
170 print(f"Testing Equator on {pilatus_dir} ..... \033[0;32mPASSED\033[0;3140m")
171 self.log_results(pass_test, "Equator PILATUS Image")
172 self.assertTrue(pass_test,"Equator Image Headless Test for PILATUS image failed.")
174 # Remove cache folders
175 if os.path.exists(os.path.join(pilatus_dir, "eq_cache")):
176 shutil.rmtree(os.path.join(pilatus_dir, "eq_cache"))
178 ####### QUADRANT FOLDER TEST #######
179 def testHeadlessMarQuadrantFolder(self):
180 mar_dir = os.path.join(self.currdir, "testImages", "MARimages")
181 for filename in os.listdir(mar_dir):
182 _, ext = os.path.splitext(str(filename))
183 if ext in self.input_types:
184 f = os.path.join(mar_dir, filename)
185 QuadrantFoldingh(f, True, True, os.path.join(mar_dir, "qfsettings.json"))
186 # subprocess.Popen([self.run_cmd, os.path.join(self.currdir, "..", "main.py"), "qf", "-h", "-i", f, "-s", os.path.join(mar_dir, "qfsettings.json"), "-d"], cwd=self.currdir).wait()
188 print(f"\033[3;33m\nVerifying that generated headless QuadrantFolder is equivalent to GUI QuadrantFolder\033[0;3140m")
189 generated_results = os.path.join(mar_dir, "qf_results", "summary.csv")
190 release_results = os.path.join(self.currdir, "testResults", "MARimages", "qf_results", "summary.csv")
191 pass_test = True
192 file1 = pd.read_csv(generated_results).round(4)
193 file2 = pd.read_csv(release_results).round(4)
194 res = pd.merge(file1, file2)
195 if len(res.index) != len(file1.index):
196 pass_test = False
197 if not pass_test:
198 print(f"\nTesting QuadrantFolder on {mar_dir} ..... \033[0;31mFAILED\033[0;3140m\033[0;3840m")
199 print("Compare the following files for more information:\n" \
200 "File generated for testing: {p1}\nReference file: {p2}\n" \
201 .format(p1 = generated_results, p2 = release_results))
202 else:
203 print(f"Testing QuadrantFolder on {mar_dir} ..... \033[0;32mPASSED\033[0;3140m")
204 self.log_results(pass_test, "QuadrantFolder MAR Image")
205 self.assertTrue(pass_test,"QuadrantFolder Image Headless Test for MAR image failed.")
207 # Remove cache folders
208 if os.path.exists(os.path.join(mar_dir, "qf_cache")):
209 shutil.rmtree(os.path.join(mar_dir, "qf_cache"))
211 def testHeadlessEigerQuadrantFolder(self):
212 eiger_dir = os.path.join(self.currdir, "testImages", "EIGERimages")
213 for filename in os.listdir(eiger_dir):
214 _, ext = os.path.splitext(str(filename))
215 if ext in self.input_types:
216 f = os.path.join(eiger_dir, filename)
217 QuadrantFoldingh(f, True, True, os.path.join(eiger_dir, "qfsettings.json"))
218 # subprocess.Popen([self.run_cmd, os.path.join(self.currdir, "..", "main.py"), "qf", "-h", "-i", f, "-s", os.path.join(eiger_dir, "qfsettings.json"), "-d"], cwd=self.currdir).wait()
220 print(f"\033[3;33m\nVerifying that generated headless QuadrantFolder is equivalent to GUI QuadrantFolder\033[0;3140m")
221 generated_results = os.path.join(eiger_dir, "qf_results", "summary.csv")
222 release_results = os.path.join(self.currdir, "testResults", "EIGERimages", "qf_results", "summary.csv")
223 pass_test = True
224 file1 = pd.read_csv(generated_results).round(4)
225 file2 = pd.read_csv(release_results).round(4)
226 res = pd.merge(file1, file2)
227 if len(res.index) != len(file1.index):
228 pass_test = False
229 if not pass_test:
230 print(f"\nTesting QuadrantFolder on {eiger_dir} ..... \033[0;31mFAILED\033[0;3140m\033[0;3840m")
231 print("Compare the following files for more information:\n" \
232 "File generated for testing: {p1}\nReference file: {p2}\n" \
233 .format(p1 = generated_results, p2 = release_results))
234 else:
235 print(f"Testing QuadrantFolder on {eiger_dir} ..... \033[0;32mPASSED\033[0;3140m")
236 self.log_results(pass_test, "QuadrantFolder EIGER Image")
237 self.assertTrue(pass_test,"QuadrantFolder Image Headless Test for EIGER image failed.")
239 # Remove cache folders
240 if os.path.exists(os.path.join(eiger_dir, "qf_cache")):
241 shutil.rmtree(os.path.join(eiger_dir, "qf_cache"))
243 def testHeadlessPilatusQuadrantFolder(self):
244 pilatus_dir = os.path.join(self.currdir, "testImages", "PILATUSimages")
245 for filename in os.listdir(pilatus_dir):
246 _, ext = os.path.splitext(str(filename))
247 if ext in self.input_types:
248 f = os.path.join(pilatus_dir, filename)
249 QuadrantFoldingh(f, True, True, os.path.join(pilatus_dir, "qfsettings.json"))
250 # subprocess.Popen([self.run_cmd, os.path.join(self.currdir, "..", "main.py"), "qf", "-h", "-i", f, "-s", os.path.join(pilatus_dir, "qfsettings.json"), "-d"], cwd=self.currdir).wait()
252 print(f"\033[3;33m\nVerifying that generated headless QuadrantFolder is equivalent to GUI QuadrantFolder\033[0;3140m")
253 generated_results = os.path.join(pilatus_dir, "qf_results", "summary.csv")
254 release_results = os.path.join(self.currdir, "testResults", "PILATUSimages", "qf_results", "summary.csv")
255 pass_test = True
256 file1 = pd.read_csv(generated_results).round(4)
257 file2 = pd.read_csv(release_results).round(4)
258 res = pd.merge(file1, file2)
259 if len(res.index) != len(file1.index):
260 pass_test = False
261 if not pass_test:
262 print(f"\nTesting QuadrantFolder on {pilatus_dir} ..... \033[0;31mFAILED\033[0;3140m\033[0;3840m")
263 print("Compare the following files for more information:\n" \
264 "File generated for testing: {p1}\nReference file: {p2}\n" \
265 .format(p1 = generated_results, p2 = release_results))
266 else:
267 print(f"Testing QuadrantFolder on {pilatus_dir} ..... \033[0;32mPASSED\033[0;3140m")
268 self.log_results(pass_test, "QuadrantFolder PILATUS Image")
269 self.assertTrue(pass_test,"QuadrantFolder Image Headless Test for PILATUS image failed.")
271 # Remove cache folders
272 if os.path.exists(os.path.join(pilatus_dir, "qf_cache")):
273 shutil.rmtree(os.path.join(pilatus_dir, "qf_cache"))
275 ####### DIFFRACTION TEST #######
276 def testHeadlessMarDiffraction(self):
277 mar_dir = os.path.join(self.currdir, "testImages", "MARimages")
278 for filename in os.listdir(mar_dir):
279 _, ext = os.path.splitext(str(filename))
280 if ext in self.input_types:
281 f = os.path.join(mar_dir, filename)
282 DIImageWindowh(filename, mar_dir, True, True, os.path.join(mar_dir, "disettings.json"))
283 # subprocess.Popen([self.run_cmd, os.path.join(self.currdir, "..", "main.py"), "di", "-h", "-i", f, "-s", os.path.join(mar_dir, "disettings.json"), "-d"], cwd=self.currdir).wait()
285 print(f"\033[3;33m\nVerifying that generated headless Diffraction is equivalent to GUI Diffraction\033[0;3140m")
286 generated_results = os.path.join(mar_dir, "di_results", "summary.csv")
287 release_results = os.path.join(self.currdir, "testResults", "MARimages", "di_results", "summary.csv")
288 pass_test = True
289 file1 = pd.read_csv(generated_results).round(4)
290 file2 = pd.read_csv(release_results).round(4)
291 res = pd.merge(file1, file2)
292 if len(res.index) != len(file1.index):
293 pass_test = False
294 if not pass_test:
295 print(f"\nTesting Diffraction on {mar_dir} ..... \033[0;31mFAILED\033[0;3140m\033[0;3840m")
296 print("Compare the following files for more information:\n" \
297 "File generated for testing: {p1}\nReference file: {p2}\n" \
298 .format(p1 = generated_results, p2 = release_results))
299 else:
300 print(f"Testing Diffraction on {mar_dir} ..... \033[0;32mPASSED\033[0;3140m")
301 self.log_results(pass_test, "Diffraction MAR Image")
302 self.assertTrue(pass_test,"Diffraction Image Headless Test for MAR image failed.")
304 # Remove cache folders
305 if os.path.exists(os.path.join(mar_dir, "di_cache")):
306 shutil.rmtree(os.path.join(mar_dir, "di_cache"))
308 def testHeadlessEigerDiffraction(self):
309 eiger_dir = os.path.join(self.currdir, "testImages", "EIGERimages")
310 for filename in os.listdir(eiger_dir):
311 _, ext = os.path.splitext(str(filename))
312 if ext in self.input_types:
313 f = os.path.join(eiger_dir, filename)
314 DIImageWindowh(filename, eiger_dir, True, True, os.path.join(eiger_dir, "disettings.json"))
315 # subprocess.Popen([self.run_cmd, os.path.join(self.currdir, "..", "main.py"), "di", "-h", "-i", f, "-s", os.path.join(eiger_dir, "disettings.json"), "-d"], cwd=self.currdir).wait()
317 print(f"\033[3;33m\nVerifying that generated headless Diffraction is equivalent to GUI Diffraction\033[0;3140m")
318 generated_results = os.path.join(eiger_dir, "di_results", "summary.csv")
319 release_results = os.path.join(self.currdir, "testResults", "EIGERimages", "di_results", "summary.csv")
320 pass_test = True
321 file1 = pd.read_csv(generated_results).round(4)
322 file2 = pd.read_csv(release_results).round(4)
323 res = pd.merge(file1, file2)
324 if len(res.index) != len(file1.index):
325 pass_test = False
326 if not pass_test:
327 print(f"\nTesting Diffraction on {eiger_dir} ..... \033[0;31mFAILED\033[0;3140m\033[0;3840m")
328 print("Compare the following files for more information:\n" \
329 "File generated for testing: {p1}\nReference file: {p2}\n" \
330 .format(p1 = generated_results, p2 = release_results))
331 else:
332 print(f"Testing Diffraction on {eiger_dir} ..... \033[0;32mPASSED\033[0;3140m")
333 self.log_results(pass_test, "Diffraction EIGER Image")
334 self.assertTrue(pass_test,"Diffraction Image Headless Test for EIGER image failed.")
336 # Remove cache folders
337 if os.path.exists(os.path.join(eiger_dir, "di_cache")):
338 shutil.rmtree(os.path.join(eiger_dir, "di_cache"))
340 def testHeadlessPilatusDiffraction(self):
341 pilatus_dir = os.path.join(self.currdir, "testImages", "PILATUSimages")
342 for filename in os.listdir(pilatus_dir):
343 _, ext = os.path.splitext(str(filename))
344 if ext in self.input_types:
345 f = os.path.join(pilatus_dir, filename)
346 DIImageWindowh(filename, pilatus_dir, True, True, os.path.join(pilatus_dir, "disettings.json"))
347 # subprocess.Popen([self.run_cmd, os.path.join(self.currdir, "..", "main.py"), "di", "-h", "-i", f, "-s", os.path.join(pilatus_dir, "disettings.json"), "-d"], cwd=self.currdir).wait()
349 print(f"\033[3;33m\nVerifying that generated headless Diffraction is equivalent to GUI Diffraction\033[0;3140m")
350 generated_results = os.path.join(pilatus_dir, "di_results", "summary.csv")
351 release_results = os.path.join(self.currdir, "testResults", "PILATUSimages", "di_results", "summary.csv")
352 pass_test = True
353 file1 = pd.read_csv(generated_results).round(4)
354 file2 = pd.read_csv(release_results).round(4)
355 res = pd.merge(file1, file2)
356 if len(res.index) != len(file1.index):
357 pass_test = False
358 if not pass_test:
359 print(f"\nTesting Diffraction on {pilatus_dir} ..... \033[0;31mFAILED\033[0;3140m\033[0;3840m")
360 print("Compare the following files for more information:\n" \
361 "File generated for testing: {p1}\nReference file: {p2}\n" \
362 .format(p1 = generated_results, p2 = release_results))
363 else:
364 print(f"Testing Diffraction on {pilatus_dir} ..... \033[0;32mPASSED\033[0;3140m")
365 self.log_results(pass_test, "Diffraction PILATUS Image")
366 self.assertTrue(pass_test,"Diffraction Image Headless Test for PILATUS image failed.")
368 # Remove cache folders
369 if os.path.exists(os.path.join(pilatus_dir, "di_cache")):
370 shutil.rmtree(os.path.join(pilatus_dir, "di_cache"))
372 ############################
373 def log_results(self, pass_test, testname):
374 """
375 Save the result in the log file
376 """
377 if pass_test:
378 result = 'pass'
379 else:
380 result = 'fail'
381 with open(self.logname, 'a') as lf:
382 lf.write(f"{testname} Test: {result}\n")
384if __name__=="__main__":
385 unittest.main(verbosity=2)