diff --git a/dataprocessing/readtools.py b/dataprocessing/readtools.py index 9eba697f39539338cdf9c9b7d6a33a2a21e2c61d..8c5f4501fbb58d8b01d3f9298129c7bd3de45b2b 100644 --- a/dataprocessing/readtools.py +++ b/dataprocessing/readtools.py @@ -162,20 +162,28 @@ def read_timeseries_dpsim_cmpl_separate(filename, timeseries_names=None): return timeseries_list -def read_timeseries_NEPLAN_loadflow(file_name, timeseries_names = None, is_regex = False): +def read_timeseries_NEPLAN_loadflow(file_name, timeseries_names=None, is_regex=False): + """ + Read in NEPLAN loadflow result from result file, the result is in angle notation, amplitude and angle are stored + separately + :param file_name: name of the mat file for the loadflow result from neplan + :param timeseries_names: column name to be read + :param is_regex: flag for using regular expression + :return: list of Timeseries objects + """ str_tmp = open(file_name, "r") # Read in files low = 0 # flag for the start of a new data in str_cmp high = 0 # flag for the end of this new data in str_cmp flag = True # To judge if this the first line of the file, which will be the names for the data type # Read in data from result file of neplan - seq = [] # list for datatype names + seq = [] # list for data type names value = [] # list for data i = 0 namelist = ['Vpp', 'Vangle', 'I', 'Iangle'] timeseries = [] - line_del = [] # a list for the value to be deleted - isfloat = re.compile(r'^[-+]?[0-9]+\.[0-9]+$') + line_del = [] # a list for the value to be deleted + isfloat = re.compile(r'^[-+]?[0-9]+\.[0-9]+$') # regular expression to find float values for line in str_tmp.readlines(): line = line.replace(",", ".") high -= high @@ -184,7 +192,7 @@ def read_timeseries_NEPLAN_loadflow(file_name, timeseries_names = None, is_regex for letter in line: if letter == " " or letter == "\n": # different data( separated by ' ') or end(/n) - if low is not high: # low is high, no data read in + if low is not high: # if low is equal to high, no data read in if flag: # first line of the file, list for data-type name seq.append(line[low:high]) else: # not first line of the file,list for data @@ -198,30 +206,32 @@ def read_timeseries_NEPLAN_loadflow(file_name, timeseries_names = None, is_regex high += 1 """ - A typical load current in neplan has two parts from both end, so the calculation of the - current is necessary, which is the function of this part + A typical line current in neplan has two parts from both end, but we doesn't have to calculate them + under the assumption that the topology of the gird should be correct with which we can validate the + current by compare the voltage of the nodes connected to the ends of the line """ if flag is False: i += 1 check_pass = True # Check for current of the same component if value[0] == '0': # value[0] == '0', no current data to be expected for m in range(2): - timeseries.append(TimeSeries(value[1] + '.' + namelist[m], np.array([0., 1.]), np.array([value[m + 6], value[m + 6]]))) + timeseries.append(TimeSeries(value[1] + '.' + namelist[m], + np.array([0., 1.]), np.array([value[m + 6], value[m + 6]]))) else: for check in range(len(timeseries) - 1): if timeseries[check].name == value[3] + '.' + namelist[2]: - check_pass = False # Find current of the same component, Calculate the current using (r,tha) - line_del.append(check) - if check_pass: + # Find current of the same component, which means the current needn't to be validated + check_pass = False + line_del.append(check) # delete the unnecessary data + line_del.append(check + 1) + if check_pass: # The load current for m in range(2, 4): timeseries.append(TimeSeries(value[3] + '.' + namelist[m], np.array([0., 1.]), np.array([value[m + 8], value[m + 8]]))) flag = False str_tmp.close() - - - if is_regex is True: # Read in variables which match with regex + if is_regex is True: p = re.compile(timeseries_names) length = len(timeseries) for rule_check in range(length): @@ -230,8 +240,8 @@ def read_timeseries_NEPLAN_loadflow(file_name, timeseries_names = None, is_regex else: line_del.append(rule_check) - elif timeseries_names is not None: # Read in specified time series + elif timeseries_names is not None: length = len(timeseries) for rule_check in range(length): if timeseries_names == timeseries[rule_check].name: diff --git a/examples/CompareResults/compare_madelica_neplan.py b/examples/CompareResults/compare_madelica_neplan.py index 39dea553e4b2916df516e866668320abce335557..cf431055d8b22f0e567c7276f6a62376542957eb 100644 --- a/examples/CompareResults/compare_madelica_neplan.py +++ b/examples/CompareResults/compare_madelica_neplan.py @@ -3,14 +3,21 @@ import re from dataprocessing.readtools import * +from readin import read_timeseries_NEPLAN_loadflow1 -file_Neplan = r"C:\Users\admin\Desktop\Load_read\WCSS\Load_flow_WCSS.rlf" -file_Modelica = r"C:\Users\admin\Desktop\Load_read\WCSS.mat" +# Read in original nepaln result file +file_Neplan = r"C:\Users\admin\Desktop\Slack_RxLine_PVNode\Slack_RxLine_PVNode.rlf" +# Read in original Modeliac result file +file_Modelica = r"C:\Users\admin\Desktop\Slack_RxLine_PVNode\Slack_RxLine_PVNode.mat" result_neplan = read_timeseries_NEPLAN_loadflow1(file_Neplan) result_modelica = read_timeseries_Modelica(file_Modelica) -f_neplan = open(r"C:\Users\admin\Desktop\Load_read\output_neplan.txt", "w") -f_modelica = open(r"C:\Users\admin\Desktop\Load_read\output_modelica.txt", "w") -f_error = open(r"C:\Users\admin\Desktop\Load_read\output_error_modelica-neplan.txt", "w") + +# neplan result output +f_neplan = open(r"C:\Users\admin\Desktop\Slack_RxLine_PVNode\Slack_RxLine_PVNode_neplan.txt", "w") +# modelica result output +f_modelica = open(r"C:\Users\admin\Desktop\Slack_RxLine_PVNode\Slack_RxLine_PVNode_modelica.txt", "w") +# error result output +f_error = open(r"C:\Users\admin\Desktop\Slack_RxLine_PVNode\output_error_modelica-neplan.txt", "w") list_del = [] for i in range(len(result_neplan)): result_neplan[i].name = result_neplan[i].name.replace(' ', '') @@ -18,29 +25,31 @@ for i in range(len(result_neplan)): if 'ANGLE' in result_neplan[i].name: pass else: - result_neplan[i].values = result_neplan[i].values * 1000 - f_neplan.write('%s is %s \n' % (result_neplan[i].name, result_neplan[i].values)) # result as list of TimeSeries + result_neplan[i].values = result_neplan[i].values * 1000 # unification of the unit,which is kV/kA in neplan + f_neplan.write('%s is %s \n' % (result_neplan[i].name, result_neplan[i].values[0])) # result as list of TimeSeries 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 + result_modelica[i].values = result_modelica[i].values / cmath.pi * 180 # unification of the unit f_modelica.write('%s is %s \n' % (result_modelica[i].name, result_modelica[i].values[1])) -timeseries_error = [] +timeseries_error = [] # list for error len_limit = len(result_modelica) for i in range(len(result_neplan)): flag_NOT_found = False for j in range(len_limit): - if result_neplan[i].name == result_modelica[j].name: - timeseries_error.append(TimeSeries(result_neplan[i].name, 0, abs(result_modelica[j].values[1] - - result_neplan[i].values))) + if result_neplan[i].name == result_modelica[j].name: # Find the same variable + timeseries_error.append(TimeSeries(result_neplan[i].name, result_modelica[j].time, + TimeSeries.rmse(result_modelica[j], result_neplan[i]))) j = len_limit + 1 flag_NOT_found = True if not flag_NOT_found: timeseries_error.append(TimeSeries(result_neplan[i].name, 0, -1)) + # No such variable in Modelica model, set the error to -1 + f_error.write('Error of %s is %f \n Base value' - ' of %s is %f \n\n' % (timeseries_error[i].name, timeseries_error[i].values, - timeseries_error[i].name, result_neplan[i].values)) + ' of %s is %s \n\n' % (timeseries_error[i].name, timeseries_error[i].values, + timeseries_error[i].name, result_neplan[i].values[0]))