From b1d730e1fb62cf6dc53d066f9d7727fb2382ce61 Mon Sep 17 00:00:00 2001
From: Bichen Li <libichen94@gmail.com>
Date: Wed, 20 Jun 2018 15:20:41 +0200
Subject: [PATCH] - Add simulink read-in function and convert function - Add
 assert_modelica and validate_modelica function - Remove some function from
 Validationtool

---
 dataprocessing/Validationtools.py | 114 ++++++++++++++++--------------
 dataprocessing/readtools.py       |   5 +-
 2 files changed, 64 insertions(+), 55 deletions(-)

diff --git a/dataprocessing/Validationtools.py b/dataprocessing/Validationtools.py
index aa5bd54..a8d7a7e 100644
--- a/dataprocessing/Validationtools.py
+++ b/dataprocessing/Validationtools.py
@@ -3,6 +3,7 @@
 import os
 from dataprocessing.readtools import *
 
+
 def convert_neplan_to_modelica_timeseries(neplan_timeseries):
     """
     Mapping the variable names between modelica and neplan
@@ -46,61 +47,71 @@ def convert_neplan_to_modelica_timeseries(neplan_timeseries):
 
     return neplan_timeseries
 
-
-def compare_modelica_neplan(modelica_res, neplan_res):  # compare the result file from NEPLAN and Modelica
+def convert_simulink_to_modelica_timeseries(simseri):
+    res = []
+    for check in range(len(simseri)):
+        if 'U AB:' in simseri[check].name:
+            simseri[check].name = simseri[check].name.replace('U AB:', '')
+            simseri[check].name = simseri[check].name.replace('Vrms', 'Vpp')
+            simseri[check].name = simseri[check].name.replace('VDegree', 'Vangle')
+            simseri[check].name = simseri[check].name.replace(' ', '')
+            simseri[check].name = simseri[check].name.replace('_', '')
+            if 'Vangle' in simseri[check].name:
+                simseri[check].values = (simseri[check].values - 30)/180 * cmath.pi
+            res.append(simseri[check])
+    return res
+
+
+def compare_timeseries(ts1, ts2):
     """
-    Compare Results from modelic and neplan, the name of the components should be kept consistent.
-    :param modelica_res: the path of the modelica result file, whose suffix should be .mat
-    :param neplan_res: the path of the neplan result file, whose suffix should be .rlf
-    :return:
+    Compare the result from two timeseries.
+    :param ts1: timeseries
+    :param ts2: timeseries
+    :return: an error dic
     """
-    # Read in original neplan result file
-    file_Neplan = os.path.abspath(neplan_res)
-    # Read in original Modelica result file
-    file_Modelica = os.path.abspath(modelica_res)
-    result_neplan = convert_neplan_to_modelica_timeseries(read_timeseries_NEPLAN_loadflow(file_Neplan))
-    result_modelica = read_timeseries_Modelica(file_Modelica)
-
-    # Transfer the angle unit to degree
-    for i in range(len(result_neplan)):
-        result_neplan[i].name = result_neplan[i].name.upper()
-        if 'ANGLE' in result_neplan[i].name:
-            result_neplan[i].values = result_neplan[i].values / cmath.pi * 180  
-    for i in range(len(result_modelica)):
-        result_modelica[i].name = result_modelica[i].name.upper()
-        if 'ANGLE' in result_modelica[i].name:
-            result_modelica[i].values = result_modelica[i].values / cmath.pi * 180
+    if len(ts1) > len(ts2):
+        tmp = ts2
+        ts2 = ts1
+        ts1 = tmp
+    for i in range(len(ts1)):
+        ts1[i].name = ts1[i].name.upper()
+    for i in range(len(ts2)):
+        ts2[i].name = ts2[i].name.upper()
 
     timeseries_names = []  # list for names of components
     timeseries_error = []  # list for error
-    len_limit = len(result_modelica)
+    len_ts1 = len(ts1)
+    len_limit = len(ts2)
 
     # Match the components in result files, and compare them
-    for i in range(len(result_neplan)):
+    for i in range(len_ts1):
         flag_not_found = False
         for j in range(len_limit):
-            if result_neplan[i].name == result_modelica[j].name:  # Find the same variable
-                timeseries_names.append(result_neplan[i].name)
-                timeseries_error.append(TimeSeries.rmse(result_modelica[j], result_neplan[i]))
+            if ts1[i].name == ts2[j].name:  # Find the same variable
+                timeseries_names.append(ts1[i].name)
+                timeseries_error.append(TimeSeries.rmse(ts2[j], ts1[i])/ts1[i].values[1])
+                print(ts1[i].name)
+                print(TimeSeries.rmse(ts2[j], ts1[i])/ts1[i].values[1])
                 flag_not_found = True
         if flag_not_found is False:
             # No such variable in Modelica model, set the error to -1
+            timeseries_names.append(ts1[i].name)
             timeseries_error.append(-1)
     return dict(zip(timeseries_names, timeseries_error))
 
-def assert_modelia_neplan_results(net_name, modelica_res, neplan_res):  # Assert the model using the function above
+
+def assert_modelia_results(net_name, error):
     """
-    Assert the result in Modelica according to the results from neplan
-    :param net_name: The name of the net should be clarified manually
-    :param modelica_res: the path of the modelica result file, whose suffix should be .mat
-    :param neplan_res: the path of the neplan result file, whose suffix should be .rlf
-    :return:
+    assert the result data of a net.
+    :param net_name: name of the network
+    :param modelica_res: timeseries of modelica result
+    :param simulink_res: timeseries of reference result
+    :return: outputs to command line which are the results of the assert
     """
     fail_list = []  # List for all the failed test
-    error = compare_modelica_neplan(modelica_res, neplan_res)
     #  the limitations are set to 0.5
     for name in error.keys():
-        if abs(error[name]) > 0.5:
+        if abs(error[name]) > 0.01:
             fail_list.append(name)
         else:
             print("Test on %s Passed" % name)
@@ -114,20 +125,19 @@ def assert_modelia_neplan_results(net_name, modelica_res, neplan_res):  # Assert
         raise ValueError('Test on %s is not passed!' % net_name)
 
 
-def convert_simulink_to_modelica_timeseries(simseri):
-    for check in range(len(simseri)):
-        simseri[check].name = simseri[check].name.replace('U CA:', '')
-        simseri[check].name = simseri[check].name.replace('Vrms', 'Vpp')
-        simseri[check].name = simseri[check].name.replace('VDegree', 'Vangle')
-        simseri[check].name = simseri[check].name.replace(' ', '')
-
-    for check in range(len(simseri)):
-        if 'Vpp' in simseri[check].name:
-            simseri[check].values = simseri[check].values * 0.577350
-
-        if 'Vangle' in simseri[check].name:
-            simseri[check].values = simseri[check].values - 30
-    return simseri
-
-
-
+def validate_modelica_res(net_name, modelica_res_path, reference_res_path):
+    """
+    Top level function for the validation of modelica, calls all the function needed to execute the validation.
+    :param modelica_res_path: the path of the modelica result file, whose suffix should be .mat
+    :param reference_res_path: the path of the reference result file, whose suffix should be .rep(simulink)/.rlf(neplan)
+    :param reference_res_type: a flag to clarify where the reference come from, should be either Simulink or Neplan
+    :return: outputs to command line which are the results of the validation.
+    """
+    res_mod = read_timeseries_Modelica (modelica_res_path)
+    if os.path.splitext(reference_res_path)[1] == '.rep':
+        res_ref = convert_simulink_to_modelica_timeseries(read_timeseries_simulink_loadflow(reference_res_path))
+    elif os.path.splitext(reference_res_path)[1] == '.rlf':
+        res_ref = convert_neplan_to_modelica_timeseries(read_timeseries_NEPLAN_loadflow(reference_res_path))
+    
+    res_err = compare_timeseries(res_ref, res_mod)
+    assert_modelia_results(net_name, res_err)
diff --git a/dataprocessing/readtools.py b/dataprocessing/readtools.py
index b8aa97c..3b441b5 100644
--- a/dataprocessing/readtools.py
+++ b/dataprocessing/readtools.py
@@ -31,9 +31,6 @@ def read_timeseries_Modelica(filename, timeseries_names=None, is_regex=False):
             for name in timeseries_names:
                 timeseries.append(TimeSeries(name, sim(name).times(), sim(name).values()))
 
-    #print('Modelica results column names: ' + str(timeseries_names))
-    #print('Modelica results number: ' + str(len(timeseries_names)))
-
     return timeseries
 
 
@@ -336,3 +333,5 @@ def read_timeseries_simulink_loadflow(file_name, timeseries_names=None, is_regex
         del timeseries[line_del[len(line_del) - num_to_del - 1]]
 
     return timeseries
+
+
-- 
GitLab