Die Migration der Bereiche "Docker Registry" und "Artifiacts" ist fast abgeschlossen. Die letzten Daten werden im Laufe des heutigen Abend (05.08.2021) noch vollständig hochgeladen. Das Anlegen neuer Images und Artifacts funktioniert bereits wieder.

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

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):
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_list)))
print('Modelica results number: ' + str(len(timeseries_names)))
return timeseries
......@@ -86,23 +86,25 @@ def read_timeseries_dpsim_real(filename, timeseries_names=None):
if timeseries_names is None:
# No column names specified, thus read in all and strip spaces
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')
#else:
# # Read in specified column names
# pd_df = pd.read_csv(filename, names=timeseries_names)
# Remove timestamps column name and store separately
column_names.remove('time')
timestamps = pd_df.iloc[:,0]
# 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))
for name in column_names:
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 timestamps number: ' + str(len(timestamps)))
return timeseries_list
def read_timeseries_dpsim_cmpl(filename, timeseries_names=None):
"""Reads complex time series data from DPsim log file. Real and
imaginary part are stored in one complex variable.
......@@ -120,15 +122,15 @@ def read_timeseries_dpsim_cmpl(filename, timeseries_names=None):
# Remove timestamps column name and store separately
column_names.remove('time')
timestamps = pd_df.iloc[:,0]
timestamps = pd_df.iloc[:, 0]
# Calculate number of network nodes since array is [real, imag]
node_number = int(len(column_names) / 2)
node_index = 1
for column in column_names:
if node_index <= node_number:
ts_name = 'n'+ str(node_index)
ts_name = 'n' + str(node_index)
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:
break
node_index = node_index + 1
......@@ -141,6 +143,7 @@ def read_timeseries_dpsim_cmpl(filename, timeseries_names=None):
return timeseries_list
def read_timeseries_dpsim_cmpl_separate(filename, timeseries_names=None):
"""Deprecated - Reads complex time series data from DPsim log file. Real and
imaginary part are stored separately.
......@@ -162,11 +165,11 @@ def read_timeseries_dpsim_cmpl_separate(filename, timeseries_names=None):
node_index = 1
for column in column_names:
if node_index <= node_number:
node_name = 'node '+ str(node_index) +' Re'
timeseries_list.append(TimeSeries(node_name, timestamps, pd_df.iloc[:,column]))
node_name = 'node ' + str(node_index) + ' Re'
timeseries_list.append(TimeSeries(node_name, timestamps, pd_df.iloc[:, column]))
else:
node_name = 'node '+ str(node_index - node_number) +' Im'
timeseries_list.append(TimeSeries(node_name, timestamps, pd_df.iloc[:,column]))
node_name = 'node ' + str(node_index - node_number) + ' Im'
timeseries_list.append(TimeSeries(node_name, timestamps, pd_df.iloc[:, column]))
node_index = node_index + 1
else:
......
......@@ -43,6 +43,19 @@ class TimeSeries:
"""
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
def diff(name, ts1, ts2):
"""Returns difference between values of two Timeseries objects.
......@@ -67,6 +80,18 @@ class TimeSeries:
- self.values.imag*np.sin(2*np.pi*freq*self.time))
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):
""" Not tested yet!
Interpolates complex timeseries with timestep
......@@ -132,5 +157,5 @@ class TimeSeries:
Assumes the same time steps for both timeseries.
"""
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
\ 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