Commit 87b06c36 authored by Markus Mirz's avatar Markus Mirz

Merge branch 'dev' into 'master'

Dev

See merge request acs/public/simulation/data-processing!1
parents a3ba9ed8 a99eaa5b
...@@ -30,7 +30,7 @@ def read_timeseries_Modelica(filename, timeseries_names=None, is_regex=False): ...@@ -30,7 +30,7 @@ def read_timeseries_Modelica(filename, timeseries_names=None, is_regex=False):
timeseries.append(TimeSeries(name, sim(name).times(), sim(name).values())) timeseries.append(TimeSeries(name, sim(name).times(), sim(name).values()))
print('Modelica results column names: ' + str(timeseries_names)) print('Modelica results column names: ' + str(timeseries_names))
print('Modelica results number: ' + str(len(timeseries_list))) print('Modelica results number: ' + str(len(timeseries_names)))
return timeseries return timeseries
...@@ -86,23 +86,25 @@ def read_timeseries_dpsim_real(filename, timeseries_names=None): ...@@ -86,23 +86,25 @@ def read_timeseries_dpsim_real(filename, timeseries_names=None):
if timeseries_names is None: if timeseries_names is None:
# No column names specified, thus read in all and strip spaces # No column names specified, thus read in all and strip spaces
pd_df.rename(columns=lambda x: x.strip(), inplace=True) pd_df.rename(columns=lambda x: x.strip(), inplace=True)
column_names = list(pd_df.columns.values) timeseries_names = list(pd_df.columns.values)
timeseries_names.remove('time')
# Remove timestamps column name and store separately #else:
column_names.remove('time') # # Read in specified column names
timestamps = pd_df.iloc[:,0] # pd_df = pd.read_csv(filename, names=timeseries_names)
for name in column_names: # store columns of interest in list of timeseries
# note: timestamps must be given in first column of csv file
timestamps = pd_df.iloc[:, 0]
for name in timeseries_names:
timeseries_list.append(TimeSeries(name, timestamps, pd_df[name].values)) timeseries_list.append(TimeSeries(name, timestamps, pd_df[name].values))
else:
# Read in specified time series
print('no column names specified yet')
print('DPsim results column names: ' + str(column_names)) print('DPsim results column names: ' + str(timeseries_names))
print('DPsim results number: ' + str(len(timeseries_list))) print('DPsim results number: ' + str(len(timeseries_list)))
print('DPsim results timestamps number: ' + str(len(timestamps)))
return timeseries_list return timeseries_list
def read_timeseries_dpsim_cmpl(filename, timeseries_names=None): def read_timeseries_dpsim_cmpl(filename, timeseries_names=None):
"""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.
...@@ -120,15 +122,15 @@ def read_timeseries_dpsim_cmpl(filename, timeseries_names=None): ...@@ -120,15 +122,15 @@ def read_timeseries_dpsim_cmpl(filename, timeseries_names=None):
# Remove timestamps column name and store separately # Remove timestamps column name and store separately
column_names.remove('time') column_names.remove('time')
timestamps = pd_df.iloc[:,0] timestamps = pd_df.iloc[:, 0]
# Calculate number of network nodes since array is [real, imag] # Calculate number of network nodes since array is [real, imag]
node_number = int(len(column_names) / 2) node_number = int(len(column_names) / 2)
node_index = 1 node_index = 1
for column in column_names: for column in column_names:
if node_index <= node_number: if node_index <= node_number:
ts_name = 'n'+ str(node_index) ts_name = 'n' + str(node_index)
timeseries_list.append( timeseries_list.append(
TimeSeries(ts_name, timestamps, np.vectorize(complex)(pd_df.iloc[:,node_index],pd_df.iloc[:,node_index + node_number]))) TimeSeries(ts_name, timestamps, np.vectorize(complex)(pd_df.iloc[:, node_index], pd_df.iloc[:, node_index + node_number])))
else: else:
break break
node_index = node_index + 1 node_index = node_index + 1
...@@ -141,6 +143,7 @@ def read_timeseries_dpsim_cmpl(filename, timeseries_names=None): ...@@ -141,6 +143,7 @@ def read_timeseries_dpsim_cmpl(filename, timeseries_names=None):
return timeseries_list return timeseries_list
def read_timeseries_dpsim_cmpl_separate(filename, timeseries_names=None): def read_timeseries_dpsim_cmpl_separate(filename, timeseries_names=None):
"""Deprecated - Reads complex time series data from DPsim log file. Real and """Deprecated - Reads complex time series data from DPsim log file. Real and
imaginary part are stored separately. imaginary part are stored separately.
...@@ -162,11 +165,11 @@ def read_timeseries_dpsim_cmpl_separate(filename, timeseries_names=None): ...@@ -162,11 +165,11 @@ def read_timeseries_dpsim_cmpl_separate(filename, timeseries_names=None):
node_index = 1 node_index = 1
for column in column_names: for column in column_names:
if node_index <= node_number: if node_index <= node_number:
node_name = 'node '+ str(node_index) +' Re' node_name = 'node ' + str(node_index) + ' Re'
timeseries_list.append(TimeSeries(node_name, timestamps, pd_df.iloc[:,column])) timeseries_list.append(TimeSeries(node_name, timestamps, pd_df.iloc[:, column]))
else: else:
node_name = 'node '+ str(node_index - node_number) +' Im' node_name = 'node ' + str(node_index - node_number) + ' Im'
timeseries_list.append(TimeSeries(node_name, timestamps, pd_df.iloc[:,column])) timeseries_list.append(TimeSeries(node_name, timestamps, pd_df.iloc[:, column]))
node_index = node_index + 1 node_index = node_index + 1
else: else:
......
...@@ -43,6 +43,19 @@ class TimeSeries: ...@@ -43,6 +43,19 @@ class TimeSeries:
""" """
return np.sqrt((TimeSeries.diff('diff', ts1, ts2).values ** 2).mean()) return np.sqrt((TimeSeries.diff('diff', ts1, ts2).values ** 2).mean())
@staticmethod
def norm_rmse(ts1, ts2):
""" Calculate root mean square error between two time series,
normalized using the mean value of both mean values of ts1 and ts2
"""
if np.mean(np.array(ts1.values.mean(),ts2.values.mean())) != 0:
nrmse = np.sqrt((TimeSeries.diff('diff', ts1, ts2).values ** 2).mean())/np.mean(np.array(ts1.values.mean(),ts2.values.mean()))
is_norm = True
else:
nrmse = np.sqrt((TimeSeries.diff('diff', ts1, ts2).values ** 2).mean())
is_norm = False
return (nrmse,is_norm)
@staticmethod @staticmethod
def diff(name, ts1, ts2): def diff(name, ts1, ts2):
"""Returns difference between values of two Timeseries objects. """Returns difference between values of two Timeseries objects.
...@@ -67,6 +80,18 @@ class TimeSeries: ...@@ -67,6 +80,18 @@ class TimeSeries:
- self.values.imag*np.sin(2*np.pi*freq*self.time)) - self.values.imag*np.sin(2*np.pi*freq*self.time))
return ts_shift return ts_shift
def calc_freq_spectrum(self):
""" Calculates frequency spectrum of the time series using FFT
:param name: name of returned time series
:param freq: shift frequency
:return: new timeseries with shifted time domain values
"""
Ts = self.time[1]-self.time[0]
fft_values = np.fft.fft(self.values)
freqs_num = int(len(fft_values)/2)
fft_freqs = np.fft.fftfreq(len(fft_values),d=Ts)
return fft_freqs[:freqs_num], np.abs(fft_values[:freqs_num])/freqs_num
def interpolate_cmpl(self, name, timestep): def interpolate_cmpl(self, name, timestep):
""" Not tested yet! """ Not tested yet!
Interpolates complex timeseries with timestep Interpolates complex timeseries with timestep
...@@ -132,5 +157,5 @@ class TimeSeries: ...@@ -132,5 +157,5 @@ class TimeSeries:
Assumes the same time steps for both timeseries. Assumes the same time steps for both timeseries.
""" """
ts_complex = np.vectorize(complex)(ts_real.values, ts_imag.values) ts_complex = np.vectorize(complex)(ts_real.values, ts_imag.values)
ts_abs = TimeSeries(name, ts_real.time, ts_complex.abs()) ts_abs = TimeSeries(name, ts_real.time, np.absolute(ts_complex))
return ts_abs return ts_abs
\ No newline at end of file
from dataprocessing.readtools import *
from dataprocessing.plottools import *
import matplotlib.pyplot as plt
from plottingtools.config import *
import numpy as np
# Comparison of P, Q and delta for 3rd order Synchronous Generator
syngen_modelica_1us = read_timeseries_Modelica(
r"\\tsclient\N\Research\German Public\ACS0049_SINERGIEN_bsc\Data\WorkData\SimulationResults\SynchronousGenerator\DP\Modelica\SinglePhase\SMIB_3rdOrderModel_PmStep_ThetaVolt0_Euler_1us.mat",
timeseries_names=["synchronousGenerator_Park.P", "synchronousGenerator_Park.Q", "synchronousGenerator_Park.delta", "synchronousGenerator_Park.i.re", "synchronousGenerator_Park.i.im"])
syngen_distaix = read_timeseries_dpsim_real(
r"\\tsclient\N\Research\German Public\ACS0050_Swarmgrid_tis\Data\WorkData\AP5\simulation-results\distaix_syngen_power_step\10ms\agent_3.csv",
timeseries_names=["P [W]", "Q [var]", "delta [rad]", "i.re [A]", "i.im [A]"])
num_vars = 5
subplot_title_list = ["P [W]\n", "Q [var]\n", "delta [rad]\n", "i.re [A]", "i.im [A]"]
plt.figure(1, figsize=(12, 8))
for i in range(num_vars):
plt.subplot(num_vars, 1, i + 1)
set_timeseries_labels(syngen_modelica_1us, ["Modelica 1us", "Modelica 1us", "Modelica 1us", "Modelica 1us", "Modelica 1us"])
plt.plot(syngen_modelica_1us[i].time, syngen_modelica_1us[i].values, label=syngen_modelica_1us[i].label)
set_timeseries_labels(syngen_distaix, ["DistAIX 10ms", "DistAIX 10ms", "DistAIX 10ms", "DistAIX 10ms", "DistAIX 10ms"])
plt.plot(syngen_distaix[i].time, syngen_distaix[i].values, label=syngen_distaix[i].label, linestyle=':')
plt.legend()
plt.xlim([0, 30])
plt.ylabel(subplot_title_list[i])
plt.show(block=True)
from dataprocessing.readtools import *
from dataprocessing.plottools import *
import matplotlib.pyplot as plt
# Example 1: read in single variable included in the Modelica results file
agent3_i_re = read_timeseries_dpsim_real(
r"\\tsclient\N\Research\German Public\ACS0050_Swarmgrid_tis\Data\WorkData\AP5\simulation-results\distaix_syngen_power_const\agent_3.csv",
timeseries_names=["i.re [A]"])
plt.figure(1, figsize=(12, 8))
set_timeseries_labels(agent3_i_re[0], "Agent 1 Ireal")
plt.plot(agent3_i_re[0].time, agent3_i_re[0].values, label=agent3_i_re[0].label)
plt.legend()
plt.show(block=True)
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