diff --git a/dataprocessing/readtools.py b/dataprocessing/readtools.py
index eeaee0a82cea109115bc14b8a2a350cf899997d1..e33c462154671bd998195351e71ee849d3e488b1 100644
--- a/dataprocessing/readtools.py
+++ b/dataprocessing/readtools.py
@@ -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:
diff --git a/dataprocessing/timeseries.py b/dataprocessing/timeseries.py
index 424e4b0256d65ed71fd7f833cb0dbf7f2915c81b..8ab1966433c2e4611acb41ff2530e91f9aa8a932 100644
--- a/dataprocessing/timeseries.py
+++ b/dataprocessing/timeseries.py
@@ -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
diff --git a/examples/CompareResults/compare_modelica_distaix.py b/examples/CompareResults/compare_modelica_distaix.py
new file mode 100644
index 0000000000000000000000000000000000000000..ead439ad4dcf2518577f8a8cfa7b9df4212a8b17
--- /dev/null
+++ b/examples/CompareResults/compare_modelica_distaix.py
@@ -0,0 +1,27 @@
+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)
diff --git a/examples/Distaix/read_distaix_examples.py b/examples/Distaix/read_distaix_examples.py
new file mode 100644
index 0000000000000000000000000000000000000000..f10131e4d6a99a380f446c2c89bae52919117b08
--- /dev/null
+++ b/examples/Distaix/read_distaix_examples.py
@@ -0,0 +1,13 @@
+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)