From 9969b44719cce5c835d6a212b10c829be14f59cc Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Thu, 26 Nov 2020 13:56:39 +0100
Subject: [PATCH] normalize-usercode: check simulation

---
 .../Python/PyPersistence/CMakeLists.txt       |  2 +-
 .../Python/PyPersistence}/PyPersistence.py.in |  0
 devtools/code-tools/normalize-usercode.py     | 42 ++++++++++++++-----
 3 files changed, 33 insertions(+), 11 deletions(-)
 rename {cmake/configurables => Tests/Functional/Python/PyPersistence}/PyPersistence.py.in (100%)

diff --git a/Tests/Functional/Python/PyPersistence/CMakeLists.txt b/Tests/Functional/Python/PyPersistence/CMakeLists.txt
index 8746b34e8d5..c1960ad2c3c 100644
--- a/Tests/Functional/Python/PyPersistence/CMakeLists.txt
+++ b/Tests/Functional/Python/PyPersistence/CMakeLists.txt
@@ -17,7 +17,7 @@ function(test_example example tolerance)
 
     # modified example to run as a test
     set(example_mod ${OUTPUT_DIR}/${EXAMPLE_NAME}_mod.py)
-    configure_file(${CONFIGURABLES_DIR}/PyPersistence.py.in ${example_mod} @ONLY)
+    configure_file(PyPersistence.py.in ${example_mod} @ONLY)
 
     add_test(${test_name} ${Python3_EXECUTABLE} -B ${example_mod})
 endfunction()
diff --git a/cmake/configurables/PyPersistence.py.in b/Tests/Functional/Python/PyPersistence/PyPersistence.py.in
similarity index 100%
rename from cmake/configurables/PyPersistence.py.in
rename to Tests/Functional/Python/PyPersistence/PyPersistence.py.in
diff --git a/devtools/code-tools/normalize-usercode.py b/devtools/code-tools/normalize-usercode.py
index 22a41344d6f..0b462303883 100755
--- a/devtools/code-tools/normalize-usercode.py
+++ b/devtools/code-tools/normalize-usercode.py
@@ -32,16 +32,20 @@ def substitute_sample(ti, tc):
     t = re.sub(pat, header+mn.group(3)+mi.group(6), ti)
     return t
 
-def cycle_text(ti, fname):
-    """
-    Returns normalized version of script ti as obtained from BornAgain's export-to-Python function.
-    """
+def retrieve_simulation(ti, fname):
     c=compile(ti, fname, 'exec')
     ns = {}
     exec(c,ns)
     globals().update(ns)
     s = get_simulation()
     s.setSample(get_sample())
+    return s
+
+def cycle_text(ti, fname):
+    """
+    Returns normalized version of script ti as obtained from BornAgain's export-to-Python function.
+    """
+    s = retrieve_simulation(ti, fname)
     return ba.generateSimulationCode(s)
 
 def normalize_text(ti, fname):
@@ -64,35 +68,53 @@ def normalize_file(fname, inplace):
                 print(f'.. read {len(ti.split())} lines')
 
         # normalize
-        t = normalize_text(ti, fname)
+        tf = normalize_text(ti, fname)
         if verbose:
             print(f'.. obtained normalized text')
-        if t == ti:
+        if tf == ti:
             if verbose:
                 print(f'.. nothing changed')
             return 0
         with open('out1.py', 'w') as f:
-            f.write(t)
+            f.write(tf)
         if verbose:
             print(f'.. saved to out1.py')
 
         # check invariance under second normalization
-        t2 = normalize_text(t, fname)
+        t2 = normalize_text(tf, fname)
         if verbose:
             print(f'.. re-normalized')
-        if t2 != t:
+        if t2 != tf:
             with open('out2.py', 'w') as f:
                 f.write(t2)
             exit(f'=> BUG - changed under second normalization, see out2.py vs out1.py')
 
         # check invariance of simulation result:
+        si = retrieve_simulation(ti, fname+".old")
+        sf = retrieve_simulation(tf, fname+".new")
+        if verbose:
+            print(f'.. running old simulation ..')
+        si.runSimulation()
+        ri = si.result()
+        if verbose:
+            print(f'.. running new simulation ..')
+        sf.runSimulation()
+        rf = sf.result()
+        if verbose:
+            print(f'.. done with simulations')
+        diff = ba.getRelativeDifference(ba.importArrayToOutputData(ri.array()),
+                                        ba.importArrayToOutputData(rf.array()))
+        if verbose:
+            print(f'.. relative difference {diff}')
+        if diff>1e-10:
+            exit(f'=> BUG - simulation result changed')
 
         # output
         if inplace:
             os.rename('out1.py', fname)
             print(f'=> NORMALIZED')
         else:
-            print(t)
+            print(tf)
 
         return 1
 
-- 
GitLab