Commit f92f812c authored by Steffen Vogel's avatar Steffen Vogel 🎅🏼

Merge branch 'master' of git.rwth-aachen.de:acs/public/simulation/data-processing

# Conflicts:
#	dataprocessing/readtools.py
parents 0ce21f35 17b46be2
build
dist
# ignore results # ignore results
*.csv *.csv
*.mat *.mat
...@@ -31,4 +34,6 @@ dymosim* ...@@ -31,4 +34,6 @@ dymosim*
__pycache__ __pycache__
# ignore jupyter notebook files # ignore jupyter notebook files
.ipynb_checkpoints .ipynb_checkpoints
\ No newline at end of file
.eggs
\ No newline at end of file
__all__ = ["readtools", "plottools", "timeseries"]
\ No newline at end of file
from dataprocessing.readtools import * from dataprocessing.readtools import *
from dataprocessing.timeseries import * from dataprocessing.timeseries import *
from dataprocessing.plottools import *
def get_node_voltage_phasors(dpsim_timeseries_list): def get_node_voltage_phasors(dpsim_timeseries_list):
"""Calculate voltage phasors of all nodes """Calculate voltage phasors of all nodes
...@@ -24,7 +25,7 @@ def get_node_emt_voltages(timeseries_list, freq): ...@@ -24,7 +25,7 @@ def get_node_emt_voltages(timeseries_list, freq):
""" """
voltages_list = {} voltages_list = {}
for name, ts in timeseries_list.items(): for name, ts in timeseries_list.items():
ts_emt = ts.dynphasor_shift_to_emt(ts.name, freq) ts_emt = ts.frequency_shift(ts.name, freq)
voltages_list[ts.name] = ts_emt voltages_list[ts.name] = ts_emt
return voltages_list return voltages_list
...@@ -56,24 +56,51 @@ def read_timeseries_PLECS(filename, timeseries_names=None): ...@@ -56,24 +56,51 @@ def read_timeseries_PLECS(filename, timeseries_names=None):
def read_timeseries_simulink(filename, timeseries_names=None): def read_timeseries_simulink(filename, timeseries_names=None):
pd_df = pd.read_csv(filename) pd_df = pd.read_csv(filename)
timeseries_list = [] timeseries_list = {}
cmpl_result_columns = []
real_result_columns = []
if timeseries_names is None: if timeseries_names is None:
# No trajectory names specified, thus read in all # No column names specified, thus read in all and strip off spaces
timeseries_names = list(pd_df.columns.values) pd_df.rename(columns=lambda x: x.strip(), inplace=True)
timeseries_names.remove('time') column_names = list(pd_df.columns.values)
for name in timeseries_names:
timeseries_list.append(TimeSeries(name, pd_df['time'].values, pd_df[name].values)) # Remove timestamps column name and store separately
column_names.remove('time')
timestamps = pd_df.iloc[:, 0]
# Find real and complex variable names
real_string = '.real'
imaginary_string = '.imag'
for column in column_names:
if real_string in column:
tmp = column.replace(real_string, '')
cmpl_result_columns.append(tmp)
#print("Found complex variable: " + tmp)
elif not imaginary_string in column:
real_result_columns.append(column)
#print("Found real variable: " + column)
for column in real_result_columns:
timeseries_list[column] = TimeSeries(column, timestamps, pd_df[column])
for column in cmpl_result_columns:
timeseries_list[column] = TimeSeries(column, timestamps,
np.vectorize(complex)(pd_df[column + real_string],
pd_df[column + imaginary_string]))
else: else:
# Read in specified time series # Read in specified time series
for name in timeseries_names: print('cannot read specified columns yet')
timeseries_list.append(TimeSeries(name, pd_df['time'].values, pd_df[name].values))
print('Simulink results column names: ' + str(timeseries_names)) print('Simulink results real column names: ' + str(real_result_columns))
print('Simulink results number: ' + str(len(timeseries_list))) print('Simulink results complex column names: ' + str(cmpl_result_columns))
print('Simulink results variable number: ' + str(len(timeseries_list)))
print('Simulink results length: ' + str(len(timestamps)))
return timeseries_list return timeseries_list
def read_timeseries_dpsim(filename, timeseries_names=None): def read_timeseries_dpsim(filename, timeseries_names=None, print_status=True):
"""Reads complex time series data from DPsim log file. Real and """Reads complex time series data from DPsim log file. Real and
imaginary part are stored in one complex variable. imaginary part are stored in one complex variable.
:param filename: name of the csv file that has the data :param filename: name of the csv file that has the data
...@@ -132,9 +159,39 @@ def read_timeseries_dpsim(filename, timeseries_names=None): ...@@ -132,9 +159,39 @@ def read_timeseries_dpsim(filename, timeseries_names=None):
# Read in specified time series # Read in specified time series
print('cannot read specified columns yet') print('cannot read specified columns yet')
print('DPsim results real column names: ' + str(real_result_columns)) if print_status :
print('DPsim results complex column names: ' + str(cmpl_result_columns)) print('DPsim results real column names: ' + str(real_result_columns))
print('DPsim results variable number: ' + str(len(timeseries_list))) print('DPsim results complex column names: ' + str(cmpl_result_columns))
print('DPsim results length: ' + str(len(timestamps))) print('DPsim results variable number: ' + str(len(timeseries_list)))
print('DPsim results length: ' + str(len(timestamps)))
return timeseries_list return timeseries_list
def read_dpsim_log(log_path):
log_file = open(log_path, "r")
log_lines = [line for line in log_file]
log_file.close()
# Sectionize
log_sections = {'init':[], 'none':[], 'sysmat_stamp':[], 'sysmat_final':[], 'sourcevec_stamp':[], 'sourcevec_final':[], 'ludecomp':[]}
section = 'init'
for line_pos in range(len(log_lines)):
if re.search('DEBUG: Stamping .+ into system matrix:', log_lines[line_pos]):
section = 'sysmat_stamp'
elif re.search('INFO: System matrix:', log_lines[line_pos]):
section = 'sysmat_final'
elif re.search('DEBUG: Stamping .+ into source vector:', log_lines[line_pos]):
section = 'sourcevec_stamp'
elif re.search('INFO: Right side vector:', log_lines[line_pos]):
section = 'sourcevec_final'
elif re.search('INFO: LU decomposition:', log_lines[line_pos]):
section = 'ludecomp'
elif re.search('INFO: Number of network simulation nodes:', log_lines[line_pos]):
section = 'none'
elif re.search('INFO: Added .+ to simulation.', log_lines[line_pos]):
section = 'none'
elif re.search('INFO: Initial switch status:', log_lines[line_pos]):
section = 'none'
log_sections[section].append(line_pos)
return log_lines, log_sections
...@@ -37,6 +37,31 @@ class TimeSeries: ...@@ -37,6 +37,31 @@ class TimeSeries:
ts_phase = TimeSeries(name, self.time, phase_values) ts_phase = TimeSeries(name, self.time, phase_values)
return ts_phase return ts_phase
def phasor(self, name):
"""Calculate phasor of complex time series and return dict with abs and phase.
"""
ts_abs = ts.abs(ts.name + '_abs')
ts_phase = ts.phase(ts.name + '_phase')
ts_phasor = {}
ts_phasor['abs'] = ts_abs
ts_phasor['phase'] = ts_phase
return ts_phasor
@staticmethod
def frequency_shift_list(timeseries_list, freq):
"""Calculate shifted frequency results of all time series
:param timeseries_list: timeseries list retrieved from dpsim results
:param freq: frequency by which the timeseries should be shifted
:return: list of shifted time series
"""
result_list = {}
for name, ts in timeseries_list.items():
ts_emt = ts.frequency_shift(ts.name, freq)
result_list[ts.name] = ts_emt
return result_list
@staticmethod @staticmethod
def rmse(ts1, ts2): def rmse(ts1, ts2):
""" Calculate root mean square error between two time series """ Calculate root mean square error between two time series
...@@ -69,7 +94,7 @@ class TimeSeries: ...@@ -69,7 +94,7 @@ class TimeSeries:
ts_diff = TimeSeries(name, time, (interp_vals_ts2 - interp_vals_ts1)) ts_diff = TimeSeries(name, time, (interp_vals_ts2 - interp_vals_ts1))
return ts_diff return ts_diff
def dynphasor_shift_to_emt(self, name, freq): def frequency_shift(self, name, freq):
""" Shift dynamic phasor values to EMT by frequency freq. """ Shift dynamic phasor values to EMT by frequency freq.
Assumes the same time steps for both timeseries. Assumes the same time steps for both timeseries.
:param name: name of returned time series :param name: name of returned time series
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment