Completed
Push — master ( 02e3b3...783fd3 )
by
unknown
03:37
created

plot_charging_series_comparison()   A

Complexity

Conditions 1

Size

Total Lines 8
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
nop 2
1
from emobpy import DataBase
2
import pandas as pd
3
import os
4
import numpy as np
5
from reegis import config as cfg
6
from matplotlib import pyplot as plt
7
8
def get_charging_profiles_from_database(path):
9
    """
10
    This function can be used to process results obtained with the library emobpy by DIW Berlin.
11
    It takes a path to data as input and returns the summed charging power.
12
13
    Parameters
14
    ----------
15
    path: String
16
        Path to a folder with stored driving, availability and charging profiles
17
18
    Returns: DataFrame
19
        Summed charging power for 4 different charging strategies
20
    -------
21
    """
22
23
    # Load profiles from Files
24
    manager = DataBase(path)
25
    manager.update()
26
27
    # Liste mit Availability Profilen
28
    keys_driving = [k for k, v in manager.db.items() if v['kind'] == 'driving']
29
    keys_availability = [k for k, v in manager.db.items() if v['kind'] == 'availability']
30
    keys_charging = [k for k, v in manager.db.items() if v['kind'] == 'charging']
31
    keys_immediate = [k for k, v in manager.db.items() if v['kind'] == 'charging' and v['option'] == 'immediate' ]
32
    keys_balanced = [k for k, v in manager.db.items() if v['kind'] == 'charging' and v['option'] == 'balanced' ]
33
    keys_23to8 = [k for k, v in manager.db.items() if v['kind'] == 'charging' and v['option'] == 'from_23_to_8_at_home']
34
    keys_0to24 = [k for k, v in manager.db.items() if v['kind'] == 'charging' and v['option'] == 'from_0_to_24_at_home']
35
36
    # Summenprofil für Fahrleistung in kmd
37
    driving_profiles = pd.DataFrame()
38
    for k in keys_driving:
39
        test = manager.db[k]["timeseries"]["consumption"]
40
        driving_profiles = pd.concat([driving_profiles, test], axis=1)
41
42
    #cum_profile = driving_profiles.sum(axis=1)
43
44
45
    # Summenprofil für Ladeleistung (immediate)
46
    ch_profiles_immediate = pd.DataFrame()
47
    for k in keys_immediate:
48
        tmp = manager.db[k]["timeseries"]["charge_grid"]
49
        ch_profiles_immediate = pd.concat([ch_profiles_immediate, tmp], axis=1)
50
51
    P_immediate = ch_profiles_immediate.sum(axis=1)
52
53
54
    # Summenprofil für Ladeleistung (balanced)
55
    ch_profiles_balanced = pd.DataFrame()
56
    for k in keys_balanced:
57
        tmp = manager.db[k]["timeseries"]["charge_grid"]
58
        ch_profiles_balanced = pd.concat([ch_profiles_balanced, tmp], axis=1)
59
60
    P_balanced = ch_profiles_balanced.sum(axis=1)
61
62
63
    # Summenprofil für Ladeleistung (23 to 8)
64
    ch_profiles_23to8 = pd.DataFrame()
65
    for k in keys_23to8:
66
        tmp = manager.db[k]["timeseries"]["charge_grid"]
67
        ch_profiles_23to8 = pd.concat([ch_profiles_23to8, tmp], axis=1)
68
69
    P_23to8 = ch_profiles_23to8.sum(axis=1)
70
71
72
    # Summenprofil für Ladeleistung (0 to 24)
73
    ch_profiles_0to24 = pd.DataFrame()
74
    for k in keys_0to24:
75
        tmp = manager.db[k]["timeseries"]["charge_grid"]
76
        ch_profiles_0to24 = pd.concat([ch_profiles_0to24, tmp], axis=1)
77
78
    P_0to24 = ch_profiles_0to24.sum(axis=1)
79
80
    P_sum = pd.concat([P_immediate, P_balanced, P_23to8, P_0to24], axis=1)
81
    P_sum.columns = ['immediate', 'balanced', '23to8', '0to24']
82
83
    return P_sum
84
85
86
def return_normalized_charging_series(df):
87
    """
88
    This function normalizes profiles so that the sum of the timeseries is 1. The profiles can then be scaled to
89
    a user defined energy consumption of BEV charging.
90
91
    Parameters
92
    ----------
93
    df: DataFrame
94
        Dataframe with 4 charging timereries
95
96
    Returns: DataFrame
97
        Normalized charging series
98
    -------
99
    """
100
101
    # Cut off initial charging
102
    df.iloc[0:48] = df.iloc[48:96].values
103
    # Cut off end charging to intial SoC
104
    df.iloc[len(df)-48:len(df)] = df.iloc[len(df)-96:len(df)-48].values
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable len does not seem to be defined.
Loading history...
105
    idx = pd.DatetimeIndex(df.index, freq='30min')
106
    df.set_index(idx, inplace=True)
107
    p_immediate = df['immediate']
108
    p_balanced = df['balanced']
109
    p_23to8 = df['23to8']
110
    p_0to24 = df['0to24']
111
112
    # Resample to hourly values
113
    immediate_hourly = p_immediate.resample('H').sum()
114
    balanced_hourly = p_balanced.resample('H').sum()
115
    hourly_23to8 = p_23to8.resample('H').sum()
116
    hourly_0to24 = p_0to24.resample('H').sum()
117
118
    # Normalize Yearly energy use to 1
119
    immediate_norm = immediate_hourly * (1 / immediate_hourly.sum())
120
    balanced_norm = balanced_hourly * (1 / balanced_hourly.sum())
121
    norm_23to8 =  hourly_23to8  * (1 / hourly_23to8 .sum())
122
    norm_0to24 = hourly_0to24 * (1 / hourly_0to24.sum())
123
124
    P_sum_norm = pd.concat([immediate_norm, balanced_norm, norm_23to8, norm_0to24], axis=1)
125
    smaller_zero = P_sum_norm < 0
126
    P_sum_norm[smaller_zero] = 0
127
128
    for n in ['immediate', 'balanced', '23to8', '0to24']:
129
        inc_fac = 1 / P_sum_norm[n].sum()
130
        P_sum_norm[n] = P_sum_norm[n].multiply(inc_fac)
131
132
    return P_sum_norm
133
134
135
def return_sum_charging_power(path=None):
136
    """
137
    This function returns a DataFrame with summed charging power series. Prerequisite is the calculation of profiles
138
    with the library emobpy by DIW Berlin. If the function is run for the first time a path to data must be provided.
139
140
    Parameters
141
    ----------
142
    path: String
143
        Path to a directory containing at least one folder with charging power series files.
144
145
    Returns: DataFrame
146
        Summed charging profiles
147
    -------
148
    """
149
    fn = os.path.join(cfg.get("paths", "scenario_data"), 'sum_charging_power.csv')
150
151
    if not os.path.isfile(fn):
152
        os.chdir(path)
153
        dirs = os.listdir(os.getcwd())
154
        result_dict = dict.fromkeys(dirs)
155
156
        for dir in result_dict.keys():
157
            path = os.path.join(os.getcwd(), dir)
158
            result_dict[dir] = get_charging_profiles_from_database(path)
159
160
        charging_types = result_dict[dir].columns
0 ignored issues
show
introduced by
The variable dir does not seem to be defined in case the for loop on line 156 is not entered. Are you sure this can never be the case?
Loading history...
161
        idx = result_dict[dir].index
162
        P_sum = pd.DataFrame(index=idx, columns=charging_types)
163
        len_series = len(result_dict[list(result_dict.keys())[0]]['immediate'])
164
165
        for ch_type in charging_types:
166
            sum_temp = pd.Series(np.zeros(shape=len_series), index=idx)
167
168
            for key in result_dict.keys():
169
                P_tmp = result_dict[key][ch_type]
170
                sum_temp = sum_temp.add(P_tmp, fill_value=0)
171
172
            P_sum[ch_type] = sum_temp
173
174
        P_sum.to_csv(fn)
175
176
    else:
177
        P_sum = pd.read_csv(fn)
178
        P_sum.set_index('Unnamed: 0', drop=True, inplace=True)
179
180
    return P_sum
181
182
183
def return_averaged_charging_series(weight_im=0.4, weight_bal=0.4, weight_night=0.2):
184
    cs = return_sum_charging_power()
185
    cs_norm = return_normalized_charging_series(cs)
186
187
    im = cs_norm["immediate"]
188
    bal = cs_norm["balanced"]
189
    night = cs_norm["23to8"]
190
191
    P_charge = weight_im * im + weight_bal * bal + weight_night * night
192
193
    return P_charge
194
195
196
def plot_charging_series_comparison(df, df_mean):
197
    fig, axs = plt.subplots(5)
198
    fig.suptitle('Charging strategy comparison')
199
    axs[0].plot(df["immediate"]), axs[0].set_title('Immediate')
200
    axs[1].plot(df["balanced"]), axs[1].set_title('balanced')
201
    axs[2].plot(df["0to24"]), axs[2].set_title('0to24')
202
    axs[3].plot(df["23to8"]), axs[3].set_title('23to8')
203
    axs[4].plot(df_mean), axs[4].set_title('Averaged series')
204