diff --git a/modules/Scenarios.py b/modules/Scenarios.py index 1a36d12ed4a5d1badd91f98c88e86beb292cab08..173bf01e2b0db6a3808dd3fa6ab0d74a9280f2a3 100644 --- a/modules/Scenarios.py +++ b/modules/Scenarios.py @@ -60,6 +60,92 @@ class Scenarios: return upper_power_green[case-1] + def get_best_green_powers(self, total_req_rate, ratios, max_power_green=500, duration=60, load_type="High"): + """ + Description: Return the green power values that include the max number of cases for the different scenarios. + In: + aaa + Out: + """ + import operator + import pandas as pd + best_power = {} + for power in range(0, max_power_green+1): + best_power[power] = {'case 1': 0, 'case 2': 0, 'case 3': 0, 'case 4': 0} + for ratio in ratios: + rates = self.get_rates(total_req_rate, ratio[0], ratio[1], ratio[2]) + if best_power[power]['case 4'] == 0: + if self.sch.energy(self.sch.configurations[load_type]['QoE'].idxmin(), (rates['sust']), duration, load_type, "Median") >= power * duration: + best_power[power]['case 4'] = 1 + if best_power[power]['case 3'] == 0: + if self.sch.energy(self.sch.configurations[load_type]['QoE'].idxmin(), (rates['sust'] + rates['bal']), duration, load_type, "Median") >= power * duration: + best_power[power]['case 3'] = 1 + if best_power[power]['case 2'] == 0: + if (self.sch.energy(self.sch.configurations[load_type]['QoE'].idxmax(), (rates['perf']), duration, load_type, "Median") + self.sch.energy(self.sch.configurations[load_type]['QoE'].idxmin(), (rates['sust'] + rates['bal']), duration, load_type, "Median")) >= power * duration: + best_power[power]['case 2'] = 1 + if best_power[power]['case 1'] == 0: + if (self.sch.energy(self.sch.configurations[load_type]['QoE'].idxmax(), (rates['sust'] + rates['bal'] + rates['perf']), duration, load_type, "Median")) <= power * duration: + best_power[power]['case 1'] = 1 + #best_power[power] = sum(best_power[power].values()) + #best_power = dict(sorted(best_power.items(), key=operator.itemgetter(1), reverse=True)) + #for power in range(0, max_power_green+1): + # print(best_power[power]['case 2']) + print(pd.DataFrame(best_power)) + + + + + + + + def get_green_power(self, total_req_rate, ratios, max_power_green=500, duration=60, load_type='High', force=False): + """ + Description: Generate randomly green power value for the case 2 of the scenarios. + In: + aaa + Out: + """ + '''if ratio in [self.green_power[1].keys()] and force == False: # 1 for case1, but work also by using one of the other cases. + print("Already defined !") + return self.green_power''' + + import random + #random.seed + green_power = random.randint(int(0.25*max_power_green), int(0.75*max_power_green)) + return green_power + """ + # Choosing randomly a power_green for each case: + green_power = {} + for case in range(1, 5): + down_limit = -1 + up_limit = 1000000000 + for ratio in ratios: + tmp_down_limit = self.__get_green_lower_limit(case, total_req_rate, ratio[0], ratio[1], ratio[2], max_power_green, duration, load_type) + if tmp_down_limit == None: + self.green_power[case][str(ratio)] = None + continue + if down_limit < tmp_down_limit and tmp_down_limit <up_limit: + down_limit = tmp_down_limit + tmp_up_limit = self.__get_green_upper_limit(case, total_req_rate, ratio[0], ratio[1], ratio[2], max_power_green, duration, load_type) + if tmp_up_limit < up_limit and tmp_up_limit > down_limit: + up_limit = tmp_up_limit + + print("Down/up limit for the case", case, ":", down_limit, "/", up_limit) + green_power[case] = random.randint(down_limit, up_limit) + return green_power + """ + + + + + + + + + + + + def get_green_powers(self, total_req_rate, ratio_rate_perf, ratio_rate_bal, ratio_rate_sust, max_power_green=500, duration=60, load_type='High', force=False): """ Description: Generate randomly green powers for the 4 cases of the scenarios. @@ -87,7 +173,7 @@ class Scenarios: up_limit = self.__get_green_lower_limit(case-2, total_req_rate, ratio_rate_perf, ratio_rate_bal, ratio_rate_sust, max_power_green, duration, load_type) if up_limit == None: up_limit = self.__get_green_lower_limit(case-3, total_req_rate, ratio_rate_perf, ratio_rate_bal, ratio_rate_sust, max_power_green, duration, load_type)''' - #print(ratio, "Down/up limit for the case", case, ":", down_limit, "/", up_limit) + print(ratio, "Down/up limit for the case", case, ":", down_limit, "/", up_limit) self.green_power[case][str(ratio)] = random.randint(down_limit, up_limit) return self.green_power @@ -102,15 +188,18 @@ class Scenarios: ratios = [] for perf_ratio in percentages: ratios.append([perf_ratio, 100-perf_ratio, 0]) - ratios.append([perf_ratio, (100-perf_ratio)/2, (100-perf_ratio)/2]) + bal_sust_value = int((100-perf_ratio)/2) if ((100-perf_ratio)/2).is_integer() else ((100-perf_ratio)/2) + ratios.append([perf_ratio, bal_sust_value, bal_sust_value]) ratios.append([perf_ratio, 0, 100-perf_ratio]) for bal_ratio in percentages: ratios.append([100-bal_ratio, bal_ratio, 0]) - ratios.append([(100-bal_ratio)/2, bal_ratio, (100-bal_ratio)/2]) + perf_sust_value = int((100-bal_ratio)/2) if ((100-bal_ratio)/2).is_integer() else ((100-bal_ratio)/2) + ratios.append([perf_sust_value, bal_ratio, perf_sust_value]) ratios.append([0, bal_ratio, 100-bal_ratio]) for sust_ratio in percentages: ratios.append([0, 100-sust_ratio, sust_ratio]) - ratios.append([(100-sust_ratio)/2, (100-sust_ratio)/2, sust_ratio]) + perf_bal_value = int((100-sust_ratio)/2) if ((100-sust_ratio)/2).is_integer() else ((100-sust_ratio)/2) + ratios.append([perf_bal_value, perf_bal_value, sust_ratio]) ratios.append([100-sust_ratio, 0, sust_ratio]) #print("\n\nRATIOS:", ratios) ratios = [list(i) for i in set(map(tuple, ratios))] @@ -165,6 +254,36 @@ class Scenarios: self.next_configuration[case][str(ratio)] = self.sch.get_next_configuration(load_type=load_type) + def next_configurations_v2(self, percentages, total_req_rate, max_power_green, duration, load_type, green_power=False): + """ + Description: + In: + aaa + Out: + """ + self.next_configuration = {} + ratios = self.get_ratios(percentages) + if green_power == False: + self.green_power = self.get_green_power(total_req_rate, ratios, max_power_green, duration, load_type) + else: + self.green_power = green_power + for ratio in ratios: + rates = self.get_rates(total_req_rate, ratio[0], ratio[1], ratio[2]) + self.sch.next_step(duration, self.green_power, rates['sust'], rates['bal'], rates['perf']) + ''' + if self.green_power[case][str(ratio)] == None: + #self.green_power[case][str(ratio)] = 0 + #self.sch.next_step(duration, 0, 0, 0, 0) + self.next_configuration[case][str(ratio)] = None #self.sch.get_next_configuration(load_type=load_type) + #self.next_configuration[case][str(ratio)]['QoE'] = 0 + else: + ''' + self.next_configuration[str(ratio)] = self.sch.get_next_configuration(load_type=load_type) + + + + + def get_next_configurations(self): """ Description: @@ -333,6 +452,442 @@ class Scenarios: + def plot_v2(self, percentages, duration, total_req_rate, load_type, energy=None, date="", case_number=None): + """ + Description: + In: + aaa + Out: + """ + import matplotlib.pyplot as plt + from matplotlib.backends.backend_pdf import PdfPages + + #figs = {} + width = 0.2 + ratios = self.get_ratios(percentages) + baselines = {} + + file_name = '.pdf' if energy == "" else date+'_scenarios'+'.pdf' + with PdfPages('Results/'+file_name) as pdf: + fig = plt.figure(figsize=(11.69, 8.27)) + plt.rcParams.update({'font.size': 8}) + ##### Green power vs power of the proposed configuration ##### + #plt.figure(figsize=(8, 6)) + plt.subplot(2, 2, 1) + plt.xticks([x for x in range(1,len(ratios)+1)], [str(x) for x in ratios], rotation=30, fontsize=8) + plt.axhline(y=self.green_power, color='g', label='Baseline', linestyle='--', linewidth=1) + '''plt.bar([x-width/2 for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['Tot. J (based on median)'][0]/duration for x in ratios], width=width, label='Gray power', color='lightgray') + plt.bar([x-width/2 for x in range(1,len(ratios)+1)], [self.green_power for x in ratios], width=width, label='Green power', color='g') + for x, y in zip(range(1,len(ratios)+1), ratios): + if self.green_power == None: + continue + else: + plt.text(x-width/2, self.green_power+1, f"{self.green_power:.1f}", ha='center', size=7) + ''' + plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['Tot. J (based on median)'][0]/duration for x in ratios], width=width, label='Power(Perf)', color='r') + for x, y in zip(range(1,len(ratios)+1), ratios): + if self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration == 0: + continue + plt.text(x+width/2, self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration+1, f"{self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration:.1f}", ha='center', size=7) + plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [(self.next_configuration[str(x)]['Energy'][1]+self.next_configuration[str(x)]['Energy'][0])/duration for x in ratios], width=width, label='Power(Bal)', color='orange') + plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['Energy'][0]/duration for x in ratios], width=width, label='Power(Sust)', color='lightgreen') + #ax.bar([x+0.1 for x in cases[str(ratio)].keys()], [next_configuration[str(ratio)][x]['Energy'][0]/duration for x in cases[str(ratio)].keys()], width=0.1, label='Power(Sust)', color='lightgreen')#, marker='^') + #plt.scatter([x+width/2 for x in range(1,len(case_ratios)+1)], [baselines[case][str(x)]['Tot. J (based on median)'][0]/duration for x in case_ratios]) + plt.xlabel('Load distribution [%Perf, %Bal, %Sust]') + plt.ylabel('Power (W)') + plt.title('Green power vs power of the proposed configuration') + plt.legend() + plt.tight_layout() + #plt.savefig('Stats/Green-vs-Config_Case'+str(case)+'.pdf', format='pdf', dpi=1200) + #plt.show() + + + ##### without vs with configuration proposition QoE ##### + self.sch.next_step(duration, self.green_power, 0, 0, total_req_rate) + baseline = self.sch.get_next_configuration(load_type=load_type) + max_qoe = baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2] + + #plt.figure(figsize=(8, 6)) + plt.subplot(2, 2, 4) + plt.xticks([0]+[x for x in range(1,len(ratios)+1)], ['Baseline']+[str(x) for x in ratios], rotation=30, fontsize=8) + #plt.axhline(y=baseline['Tot. J (based on median)'][0]/duration, color='b', label='Baseline', linestyle='--', linewidth=2) + plt.bar(0, baseline.loc[baseline['Mode']=='conf_perf', 'QoE']/max_qoe, width=width, label='Baseline') + plt.text(0, baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]/max_qoe, str(baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]/max_qoe), ha='center', size=7) + #plt.xticks([0], ['Baseline']) + plt.bar([x for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['QoE'][2]/max_qoe for x in ratios], width=width, label='QoE(Perf)', color='red') + for x, y in zip(range(1,len(ratios)+1), ratios): + if self.next_configuration[str(y)]['QoE'][2] == 0: + continue + plt.text(x, self.next_configuration[str(y)]['QoE'][2]/max_qoe, f"{self.next_configuration[str(y)]['QoE'][2]/max_qoe:.1f}", ha='center', size=7) + plt.bar([x+width for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['QoE'][1]/max_qoe for x in ratios], width=width, label='QoE(Bal)', color='orange') + for x, y in zip(range(1,len(ratios)+1), ratios): + if self.next_configuration[str(y)]['QoE'][1] == 0: + continue + plt.text(x+width, self.next_configuration[str(y)]['QoE'][1]/max_qoe, f"{self.next_configuration[str(y)]['QoE'][1]/max_qoe:.1f}", ha='center', size=7) + plt.bar([x+2*width for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['QoE'][0]/max_qoe for x in ratios], width=width, label='QoE(Sust)', color='lightgreen') + for x, y in zip(range(1,len(ratios)+1), ratios): + if self.next_configuration[str(y)]['QoE'][0] == 0: + continue + plt.text(x+2*width, self.next_configuration[str(y)]['QoE'][0]/max_qoe, f"{self.next_configuration[str(y)]['QoE'][0]/max_qoe:.1f}", ha='center', size=7) + plt.xlabel('Load distribution [%Perf, %Bal, %Sust]') + plt.ylabel('Quality (QoE)') + plt.title('Without vs with configuration proposition QoE') + plt.legend() + plt.tight_layout() + #plt.savefig('Stats/QoE_Case'+str(case)+'.pdf', bbox_inches='tight', format='pdf', dpi=1200) + #plt.show() + + + + if energy != None: + ##### Estimated vs measured energy of the proposed configuration ##### + #plt.figure(figsize=(8, 6)) + plt.subplot(2, 2, 2) + plt.xticks([x for x in range(1,len(ratios)+1)], [str(x) for x in ratios], rotation=30, fontsize=8) + plt.bar([x+3*width/2 for x in range(1,len(ratios)+1)], [energy[str(x)]/duration for x in ratios], width=width, label='Meas. Power', color='black') + for x, y in zip(range(1,len(ratios)+1), ratios): + if energy[str(y)]/duration == 0: + continue + plt.text(x+3*width/2, energy[str(y)]/duration+1, f"{energy[str(y)]/duration:.1f}", ha='center', size=7) + plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['Tot. J (based on median)'][0]/duration for x in ratios], width=width, label='Power(Perf)', color='r') + for x, y in zip(range(1,len(ratios)+1), ratios): + if self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration == 0: + continue + plt.text(x+width/2, self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration+1, f"{self.next_configuration[str(y)]['Tot. J (based on median)'][0]/duration:.1f}", ha='center', size=7) + plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [(self.next_configuration[str(x)]['Energy'][1]+self.next_configuration[str(x)]['Energy'][0])/duration for x in ratios], width=width, label='Power(Bal)', color='orange') + plt.bar([x+width/2 for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['Energy'][0]/duration for x in ratios], width=width, label='Power(Sust)', color='lightgreen') + + plt.xlabel('Load distribution [%Perf, %Bal, %Sust]') + plt.ylabel('Power (W)') + plt.title('Estimated vs measured energy of the proposition') + plt.legend() + plt.tight_layout() + #plt.savefig('Stats/Estimates-vs-Measured_Case'+str(case)+'.pdf', format='pdf', dpi=1200) + #plt.show() + + + ##### without vs with configuration proposition energies ##### + #from statistics import median + #baseline = median([energy[str(x)] for x in ratios]) + baseline =energy[str([100, 0, 0])] + + #plt.figure(figsize=(8, 6)) + plt.subplot(2, 2, 3) + plt.xticks([0]+[x for x in range(1,len(ratios)+1)], ['Baseline']+[str(x) for x in ratios], rotation=30, fontsize=8) + #plt.axhline(y=baseline['Tot. J (based on median)'][0]/duration, color='b', label='Baseline', linestyle='--', linewidth=2) + plt.bar(0, baseline/duration, width=width, label='Baseline') + plt.text(0, baseline/duration+1, f"{baseline/duration:.1f}", ha='center', size=7) + #plt.xticks([0], ['Baseline']) + plt.bar([x+3*width/2 for x in range(1,len(ratios)+1)], [energy[str(x)]/duration for x in ratios], width=width, label='Meas. Power', color='black') + for x, y in zip(range(1,len(ratios)+1), ratios): + if energy[str(y)]/duration == 0: + continue + plt.text(x+3*width/2, energy[str(y)]/duration+1, f"{energy[str(y)]/duration:.1f}", ha='center', size=7) + plt.xlabel('Load distribution [%Perf, %Bal, %Sust]') + plt.ylabel('Power (W)') + plt.title('Without vs with configuration proposition energies') + plt.legend() + plt.tight_layout() + #plt.savefig('Stats/With-vs-Without_Case'+str(case)+'.pdf', format='pdf', dpi=1200) + #plt.show() + + + + y_max = -1 + for x in range(1, 4): + plt.subplot(2, 2, x) + axes = plt.gca() + y_max = max(y_max, axes.get_ylim()[1]) + for x in range(1, 4): + plt.subplot(2, 2, x) + axes = plt.gca() + axes.set_ylim(0, y_max) + pdf.savefig(fig, orientation='landscape', bbox_inches='tight', dpi=1200) + plt.close() + + + + + + + + + + + + + def get_xticks(self, ratios, width): + """ + Description: + In: + aaa + Out: + """ + #print(ratios) + ticks = [] + labels = [] + shifts = [] + # For the baseline: + ticks.append(0 - width / 2) + labels.append('') + shifts.append(0) + + ticks.append(0 + width / 2) + labels.append('Baseline') + shifts.append(-width / 2) + + for i in range(1, len(ratios)+1): + i1 = i - width/2 + i_perf_width, i_bal_width, i_sust_width = 0, 0, 0 + ticks.append(i1) + labels.append('') + shifts.append(0) + i2 = i + width/2 + if ratios[i-1][0] != 0: + i_perf_width = width * ratios[i-1][0] / 100 + i_perf = i1 + i_perf_width + ticks.append(i_perf) + labels.append(str(ratios[i-1][0]) + '% Perf') + shifts.append(-i_perf_width / 2) + if ratios[i-1][1] != 0: + i_bal_width = width * ratios[i-1][1] / 100 + i_bal = i1 + i_perf_width + i_bal_width + ticks.append(i_bal) + labels.append(str(ratios[i-1][1]) + '% Bal') + shifts.append(-i_bal_width / 2) + if ratios[i-1][2] != 0: + i_sust_width = width * ratios[i-1][2] / 100 + i_sust = i1 + i_perf_width + i_bal_width + i_sust_width + ticks.append(i_sust) + labels.append(str(ratios[i-1][2]) + '% Sust') + shifts.append(-i_sust_width / 2) + #ticks.append(i2) + #labels.append('*') + #print(len(ticks), ticks) + return ticks, labels, shifts + + def plot_x_axis(self, fig, ax, ratios, width): + """ + Description: + In: + aaa + Out: + """ + import matplotlib.pyplot as plt + import matplotlib.transforms + ticks, labels, shifts = self.get_xticks(ratios, width) + ax.set_xlim(ticks[0]- width/2, ticks[-1]+width/2) + ax.set_xticks(ticks, labels) + plt.setp(ax.xaxis.get_majorticklabels(), rotation=90) # Reference: https://stackoverflow.com/questions/28615887/how-to-move-a-tick-label + dy = 0.0 + for i, label in zip(range(len(shifts)), ax.xaxis.get_majorticklabels()): + #print(shifts[i]) + dx = shifts[i] + offset = matplotlib.transforms.ScaledTranslation(dx, dy, fig.dpi_scale_trans) + label.set_transform(label.get_transform() + offset) + + + + def plot_v3(self, percentages, duration, total_req_rate, load_type, energy, date=""): + """ + Description: + In: + aaa + Out: + """ + import matplotlib.pyplot as plt + import matplotlib.transforms + from matplotlib.backends.backend_pdf import PdfPages + import numpy as np + + width = 0.6 + ratios = self.get_ratios(percentages) + baselines = {} + + MOS = ['Poor', 'Medium', 'Good', 'Very good', 'Excellent'] + + fig, axs = plt.subplots(2, figsize=(11.69, 8.27))#, sharex=True) + plt.rcParams.update({'font.size': 8}) + ##### without vs with configuration proposition QoE ##### + self.sch.next_step(duration, self.green_power, 0, 0, total_req_rate) + baseline = self.sch.get_next_configuration(load_type=load_type) + max_qoe = baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2] + + axs[0].grid(axis='y') + #axs[0].grid(axis='x', alpha=0.15) + axs[0].set_axisbelow(True) + #plt.figure(figsize=(8, 6)) + axs[0].tick_params(axis='x', direction='in', pad=-5, top=True, bottom=True)#, pad=-30 + #plt.axhline(y=baseline['Tot. J (based on median)'][0]/duration, color='b', label='Baseline', linestyle='--', linewidth=2) + baseline_label = axs[0].scatter(0, MOS.index(baseline.loc[baseline['Mode']=='conf_perf', 'MOS'][2])+1, label='Baseline') + #axs[0].text(0, baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]/max_qoe+.02, str(baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2]/max_qoe), ha='center', size=7) + #plt.xticks([0], ['Baseline']) + #axs[0].scatter([x for x in range(1,len(ratios)+1)], [self.next_configuration[str(x)]['QoE'][2]/max_qoe for x in ratios], label='QoE(Perf)', color='blue', marker='*') + ticks, labels, shifts = self.get_xticks(ratios, width) + qoe_plots = {'perf':{'x':[], 'y':[]}, 'bal':{'x':[], 'y':[]}, 'sust':{'x':[], 'y':[]}} + i = 2 + for x, y in zip(range(1,len(ratios)+1), ratios): + if self.next_configuration[str(y)]['QoE'][2] != 0: + while labels[i] == '': + i += 1 + qoe_plots['perf']['x'].append(ticks[i]+shifts[i]) + qoe_plots['perf']['y'].append(MOS.index(self.next_configuration[str(y)]['MOS'][2])+1) + #perf_label = axs[0].scatter([ticks[i]+shifts[i]], [MOS.index(self.next_configuration[str(y)]['MOS'][2])+1], label='QoE(Perf)', color='brown', marker='*') + i += 1 + if self.next_configuration[str(y)]['QoE'][1] != 0: + while labels[i] == '': + i += 1 + qoe_plots['bal']['x'].append(ticks[i]+shifts[i]) + qoe_plots['bal']['y'].append(MOS.index(self.next_configuration[str(y)]['MOS'][1])+1) + #bal_label = axs[0].scatter([ticks[i]+shifts[i]], [MOS.index(self.next_configuration[str(y)]['MOS'][1])+1], label='QoE(Bal)', color='orange', marker='D') + i += 1 + if self.next_configuration[str(y)]['QoE'][0] != 0: + while labels[i] == '': + i += 1 + qoe_plots['sust']['x'].append(ticks[i]+shifts[i]) + qoe_plots['sust']['y'].append(MOS.index(self.next_configuration[str(y)]['MOS'][0])+1) + #sust_label = axs[0].scatter([ticks[i]+shifts[i]], [MOS.index(self.next_configuration[str(y)]['MOS'][0])+1], label='QoE(Sust)', color='green', marker='x') + i += 1 + axs[0].scatter(qoe_plots['perf']['x'], qoe_plots['perf']['y'], label='QoE(Perf)', color='brown', marker='*') + axs[0].scatter(qoe_plots['bal']['x'], qoe_plots['bal']['y'], label='QoE(Bal)', color='orange', marker='D') + axs[0].scatter(qoe_plots['sust']['x'], qoe_plots['sust']['y'], label='QoE(Sust)', color='green', marker='x') + axs[0].set_yticks(np.arange(len(MOS)+1)) + axs[0].set_yticklabels(['']+MOS) + axs[0].set_ylabel('Quality (QoE)') + #plt.title('Without vs with configuration proposition QoE') + self.plot_x_axis(fig, axs[0], ratios, width) + plt.setp(axs[0].xaxis.get_majorticklabels(), rotation=90, ha='left', va='bottom', rotation_mode="default") + + axs[0].legend(loc='center left')#(baseline_label, perf_label, bal_label, sust_label), ('Baseline', 'QoE(Perf)', 'QoE(Bal)', 'QoE(Sust)')) + plt.tight_layout() + + ##### without vs with configuration proposition energies ##### + #from statistics import median + #baseline = median([energy[str(x)] for x in ratios]) + baseline =energy[str([100, 0, 0])] + axs[1].bar(0, baseline/duration, width=width, label='Baseline') + axs[1].text(0, baseline/duration+1, f"{baseline/duration:.1f}", ha='center', size=7) + #plt.xticks([0], ['Baseline']) + axs[1].bar([x for x in range(1,len(ratios)+1)], [energy[str(x)]/duration for x in ratios], width=width, label='Meas. Power', color='lightblue') + for x, y in zip(range(1,len(ratios)+1), ratios): + if energy[str(y)]/duration == 0: + continue + plt.text(x, energy[str(y)]/duration+1, f"{energy[str(y)]/duration:.1f}", ha='center', size=7) + + '''axs[1].vlines(qoe_plots['perf']['x'], 0, qoe_plots['perf']['y'], label='QoE(Perf)') + axs[1].vlines(qoe_plots['bal']['x'], 0, qoe_plots['bal']['y'], label='QoE(Bal)') + axs[1].vlines(qoe_plots['sust']['x'], 0, qoe_plots['sust']['y'], label='QoE(Sust)', color='green')''' + + plt.xlabel('Load distribution [%Perf, %Bal, %Sust]') + axs[1].set_ylabel('Power (W)') + axs[1].axhline(y=self.green_power, color='g', label='Green Power', linestyle=':', dashes=(1, 5), linewidth=1) + axs[1].set_yticks(list(axs[1].get_yticks()) + [self.green_power]) + + + axs[1].tick_params(axis='x', direction='out', pad=width/2, top=True, bottom=True) + + self.plot_x_axis(fig, axs[1], ratios, width) + + + fig.suptitle('Power vs QoE depending on Load distribution') + plt.legend() + plt.tight_layout() + file_name = date + '_Power-vs-QoE' + '.pdf' + print("Saving file", file_name) + plt.savefig('Results/'+file_name) + plt.show() + + + def plot_v4(self, percentages, duration, total_req_rate, load_type, energy, date="", annotation=False): + """ + Description: + In: + aaa + Out: + """ + import matplotlib.pyplot as plt + import matplotlib.transforms + from matplotlib.backends.backend_pdf import PdfPages + import numpy as np + + width = 0.6 + ratios = self.get_ratios(percentages) + baselines = {} + + MOS = ['Poor', 'Medium', 'Good', 'Very good', 'Excellent'] + + fig, axs = plt.subplots(figsize=(11.69, 6.2025))#8.27))#, sharex=True) + #plt.rcParams.update({'font.size': 8}) + ##### without vs with configuration proposition QoE ##### + self.sch.next_step(duration, self.green_power, 0, 0, total_req_rate) + baseline = self.sch.get_next_configuration(load_type=load_type) + max_qoe = baseline.loc[baseline['Mode']=='conf_perf', 'QoE'][2] + + + ##### without vs with configuration proposition energies ##### + #from statistics import median + #baseline = median([energy[str(x)] for x in ratios]) + baseline = energy[str([100, 0, 0])] + + if annotation == True: + axs.axhline(y=baseline/duration, color='black', linestyle='--', linewidth=.75, zorder=1) + + axs.axhline(y=self.green_power, color='g', label='Green Power', linestyle='--', zorder=1)#, dashes=(1, 5), linewidth=1) + #axs.text(4.5, baseline/duration+1, "Baseline", ha='center') + #axs.set_yticks(list(axs.get_yticks()) + [baseline/duration]) + #axs.vlines(5, energy[str([0,100,0])]/duration, baseline/duration, color='red', linestyle='-') + #plt.stem(5, baseline/duration) + if annotation == True: + plt.annotate('', xy=(5, baseline/duration), xytext=(5, energy[str([0,100,0])]/duration), arrowprops=dict(arrowstyle='|-|', color='red')) + axs.text(5-.3, (energy[str([0,100,0])]+(baseline-energy[str([0,100,0])])/2)/duration, f"{100*(energy[str([0,100,0])]-baseline)/baseline:.1f}%", ha='center', color='red') + #axs.vlines(9, energy[str([50,25,25])]/duration, baseline/duration, color='red', linestyle='-') + plt.annotate('', xy=(9, baseline/duration), xytext=(9, energy[str([50,25,25])]/duration), arrowprops=dict(arrowstyle='|-|', color='red')) + axs.text(9-.3, (energy[str([50,25,25])]+(baseline-energy[str([50,25,25])])/2)/duration, f"{100*(energy[str([50,25,25])]-baseline)/baseline:.1f}%", ha='center', color='red') + + # For the baseline: + axs.bar(0, baseline/duration, width=width, label='Meas. Power') + axs.text(0, baseline/duration+1, f"{baseline/duration:.1f}", ha='center')#, size=7) + #plt.xticks([0], ['Baseline']) + + axs.bar([x for x in range(1,len(ratios)+1)], [energy[str(x)]/duration for x in ratios], width=width, label='Meas. Power', color='lightblue') + axs.set_yticks(list(axs.get_yticks()) + [self.green_power]) + for x, y in zip(range(1,len(ratios)+1), ratios): + if energy[str(y)]/duration == 0: + continue + plt.text(x, energy[str(y)]/duration+1, f"{energy[str(y)]/duration:.1f}", ha='center')#, size=7) + + '''axs[1].vlines(qoe_plots['perf']['x'], 0, qoe_plots['perf']['y'], label='QoE(Perf)') + axs[1].vlines(qoe_plots['bal']['x'], 0, qoe_plots['bal']['y'], label='QoE(Bal)') + axs[1].vlines(qoe_plots['sust']['x'], 0, qoe_plots['sust']['y'], label='QoE(Sust)', color='green')''' + + plt.xlabel('Load distribution [%Perf, %Bal, %Sust]') + axs.set_ylabel('Power (W)') + + + axs.tick_params(axis='x', direction='out', pad=width/2, top=True, bottom=True, labelsize=11) + axs.tick_params(axis='y', labelsize=11) + + self.plot_x_axis(fig, axs, ratios, width) + + '''axs.axhline(y=baseline/duration, color='white', linestyle=':', dashes=(1, 5), linewidth=1) + axs.vlines(5, energy[str([0,100,0])]/duration, baseline/duration, color='white', linestyle='-') + #plt.stem(5, baseline/duration) + axs.text(5-.3, (energy[str([0,100,0])]+(baseline-energy[str([0,100,0])])/2)/duration, f"{100*(energy[str([0,100,0])]-baseline)/baseline:.1f}%", ha='center', color='white') + axs.vlines(9, energy[str([50,25,25])]/duration, baseline/duration, color='white', linestyle='-') + axs.text(9-.3, (energy[str([50,25,25])]+(baseline-energy[str([50,25,25])])/2)/duration-4.5, f"{100*(energy[str([50,25,25])]-baseline)/baseline:.1f}%", ha='center', color='white')''' + + + + #fig.suptitle('Power vs QoE depending on Load distribution') + plt.legend(loc='upper right', bbox_to_anchor=(0.87,0.88)) + plt.tight_layout() + annot = '' + if annotation == True: + annot = '_annotation' + file_name = date + '_Power-vs-QoE' + annot + '.pdf' + print("Saving file", file_name) + plt.savefig('Results/'+file_name) + plt.show() diff --git a/modules/Scheduler.py b/modules/Scheduler.py index d96ace14440ce06ab08f1d3f8f8aec8030207f6c..e4fcdd5261c06f9620952a57e9a37ea607e17c4b 100644 --- a/modules/Scheduler.py +++ b/modules/Scheduler.py @@ -25,7 +25,23 @@ class Scheduler: self.configurations = {} for load in self.loads: self.configurations[load] = experience.loc[experience['Load type'] == load, ['Image size (px)', 'Filter', 'Req/s', 'Users', 'Mean J/Req', 'Min J/Req', 'Max J/Req', 'Median J/Req']].reset_index(drop=True) + self.configurations[load]['QoE'] = [x + 1 for x in range(len(self.configurations[load]))] + + MOS = [] # Mean Opinion Score + for x in self.configurations[load]['Image size (px)']: + if x >= 1080: + MOS.append("Excellent") + elif x >= 720: + MOS.append("Very good") + elif x >= 480: + MOS.append("Good") + elif x >= 360: + MOS.append("Medium") + else: # elif x >= 144: + MOS.append("Poor") + #print(qualities) + self.configurations[load]['MOS'] = MOS #print("\033[1m" + load + "\033[0m\n", self.configurations[load]) #print(configurations) return self.configurations @@ -75,6 +91,9 @@ class Scheduler: next_configuration['QoE'] = [self.configurations[load]['QoE'][conf_sust] if self.req_rate_sust!=0 else 0, self.configurations[load]['QoE'][conf_bal] if self.req_rate_bal!=0 else 0, self.configurations[load]['QoE'][conf_perf] if self.req_rate_perf!=0 else 0] + next_configuration['MOS'] = [self.configurations[load]['MOS'][conf_sust] if self.req_rate_sust!=0 else 0, + self.configurations[load]['MOS'][conf_bal] if self.req_rate_bal!=0 else 0, + self.configurations[load]['MOS'][conf_perf] if self.req_rate_perf!=0 else 0] next_configuration['Energy'] = [self.energy(conf_sust, self.req_rate_sust, self.duration, load), self.energy(conf_bal, self.req_rate_bal, self.duration, load), self.energy(conf_perf, self.req_rate_perf, self.duration, load)]