From 57af48bf0e943871716d43e8b20e9239591d23e8 Mon Sep 17 00:00:00 2001 From: HajarZaiz Date: Wed, 22 Mar 2023 23:17:19 +0000 Subject: [PATCH 01/11] Average runs --- DAS/visualizer.py | 66 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/DAS/visualizer.py b/DAS/visualizer.py index 047e513..bb8c527 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -16,11 +16,11 @@ class Visualizer: self.minimumDataPoints = 2 def plottingData(self): - #Store data with a unique key for each params combination + """Store data with a unique key for each params combination""" data = {} - #Loop over the xml files in the folder + """Loop over the xml files in the folder""" for filename in os.listdir(self.folderPath): - #Loop over the xmls and store the data in variables + """Loop over the xmls and store the data in variables""" if filename.endswith('.xml'): tree = ET.parse(os.path.join(self.folderPath, filename)) root = tree.getroot() @@ -32,24 +32,24 @@ class Visualizer: chi = int(root.find('chi').text) tta = int(root.find('tta').text) - # Loop over all possible combinations of length 4 of the parameters + """Loop over all possible combinations of length 4 of the parameters""" for combination in combinations(self.parameters, 4): - # Get the indices and values of the parameters in the combination + """Get the indices and values of the parameters in the combination""" indices = [self.parameters.index(element) for element in combination] selectedValues = [run, blockSize, failureRate, numberValidators, netDegree, chi] values = [selectedValues[index] for index in indices] names = [self.parameters[i] for i in indices] keyComponents = [f"{name}_{value}" for name, value in zip(names, values)] key = tuple(keyComponents[:4]) - #Get the names of the other 2 parameters that are not included in the key + """Get the names of the other 2 parameters that are not included in the key""" otherParams = [self.parameters[i] for i in range(6) if i not in indices] - #Append the values of the other 2 parameters and the ttas to the lists for the key + """Append the values of the other 2 parameters and the ttas to the lists for the key""" otherIndices = [i for i in range(len(self.parameters)) if i not in indices] - #Initialize the dictionary for the key if it doesn't exist yet + """Initialize the dictionary for the key if it doesn't exist yet""" if key not in data: data[key] = {} - #Initialize lists for the other 2 parameters and the ttas with the key + """Initialize lists for the other 2 parameters and the ttas with the key""" data[key][otherParams[0]] = [] data[key][otherParams[1]] = [] data[key]['ttas'] = [] @@ -65,9 +65,42 @@ class Visualizer: data[key]['ttas'].append(tta) print("Getting data from the folder...") return data + + def averageRuns(self, data): + """Get the average of run 0 and run 1 for each key""" + newData = {} + for key, value in data.items(): + runExists = False + """Check if the key contains 'run_' with a numerical value""" + for item in key: + if item.startswith('run_0'): + runExists = True + break + if runExists: + for item in key: + """Create a new key with the other items in the tuple""" + if item.startswith('run_'): + newKey = tuple([x for x in key if x != item]) + key0 = ('run_0',) + newKey + data0 = data[key0] + key1 = ('run_1',) + newKey + data1 = data[key1] + averages = {} + for key in data0.keys(): + if key in data1: + values = [] + for i in range(len(data0[key])): + value = (data0[key][i] + data1[key][i]) / 2.0 + if isinstance(data0[key][i], int) and isinstance(data1[key][i], int) and key != 'ttas': + value = int(value) + values.append(value) + averages[key] = values + newData[newKey] = averages + print("Getting the average of the runs...") + return newData def similarKeys(self, data): - #Get the keys for all data with the same x and y labels + """Get the keys for all data with the same x and y labels""" filteredKeys = {} for key1, value1 in data.items(): subKeys1 = list(value1.keys()) @@ -83,28 +116,29 @@ class Visualizer: return filteredKeys def formatLabel(self, label): - #Label formatting for the figures + """Label formatting for the figures""" result = ''.join([f" {char}" if char.isupper() else char for char in label]) return result.title() def formatTitle(self, key): - #Title formatting for the figures + """Title formatting for the figures""" name = ''.join([f" {char}" if char.isupper() else char for char in key.split('_')[0]]) number = key.split('_')[1] return f"{name.title()}: {number} " def plotHeatmaps(self): - #Plot and store the 2D heatmaps in subfolders + """Plot and store the 2D heatmaps in subfolders""" data = self.plottingData() + data = self.averageRuns(data) filteredKeys = self.similarKeys(data) print("Plotting heatmaps...") - #Create the directory if it doesn't exist already + """Create the directory if it doesn't exist already""" heatmapsFolder = self.folderPath + '/heatmaps' if not os.path.exists(heatmapsFolder): os.makedirs(heatmapsFolder) - #Plot + """Plot""" for labels, keys in filteredKeys.items(): for key in keys: xlabels = np.sort(np.unique(data[key][labels[0]])) @@ -121,7 +155,7 @@ class Visualizer: title = "" paramValueCnt = 0 for param in self.parameters: - if param != labels[0] and param != labels[1]: + if param != labels[0] and param != labels[1] and param != 'run': filename += f"{key[paramValueCnt]}" formattedTitle = self.formatTitle(key[paramValueCnt]) title += formattedTitle From 89368d5fbe441b74950e0d9a2987f726a5a0a54b Mon Sep 17 00:00:00 2001 From: HajarZaiz Date: Thu, 30 Mar 2023 11:24:30 +0000 Subject: [PATCH 02/11] fixed bug and generalized averaging --- DAS/visualizer.py | 79 +++++++++++++++++++++++++++++++---------------- config_example.py | 18 +++++------ 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/DAS/visualizer.py b/DAS/visualizer.py index c44d32a..be05ed0 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -6,19 +6,21 @@ import matplotlib.pyplot as plt import numpy as np import seaborn as sns from itertools import combinations +from config_example import runs class Visualizer: def __init__(self, execID): self.execID = execID self.folderPath = "results/"+self.execID - self.parameters = ['run', 'blockSize', 'failureRate', 'numberNodes', 'netDegree', - 'chi', 'vpn1', 'vpn2', 'bwUplinkProd', 'bwUplink1', 'bwUplink2'] + self.parameters = ['run', 'blockSize', 'failureRate', 'numberNodes', 'netDegree', 'chi', 'vpn1', 'vpn2', 'class1ratio', 'bwUplinkProd', 'bwUplink1', 'bwUplink2'] self.minimumDataPoints = 2 + self.maxTTA = 999 def plottingData(self): """Store data with a unique key for each params combination""" data = {} + bw = [] """Loop over the xml files in the folder""" for filename in os.listdir(self.folderPath): """Loop over the xmls and store the data in variables""" @@ -29,6 +31,7 @@ class Visualizer: blockSize = int(root.find('blockSize').text) failureRate = int(root.find('failureRate').text) numberNodes = int(root.find('numberNodes').text) + class1ratio = float(root.find('class1ratio').text) netDegree = int(root.find('netDegree').text) chi = int(root.find('chi').text) vpn1 = int(root.find('vpn1').text) @@ -38,25 +41,31 @@ class Visualizer: bwUplink2 = int(root.find('bwUplink2').text) tta = int(root.find('tta').text) - """Loop over all possible combinations of length 4 of the parameters""" + # if tta == -1: + # tta = self.maxTTA + + """Store BW""" + bw.append(bwUplinkProd) + + """Loop over all possible combinations of length of the parameters minus x, y params""" for combination in combinations(self.parameters, len(self.parameters)-2): # Get the indices and values of the parameters in the combination indices = [self.parameters.index(element) for element in combination] - selectedValues = [run, blockSize, failureRate, numberNodes, netDegree, chi, vpn1, vpn2, bwUplinkProd, bwUplink1, bwUplink2] + selectedValues = [run, blockSize, failureRate, numberNodes, netDegree, chi, vpn1, vpn2, class1ratio, bwUplinkProd, bwUplink1, bwUplink2] values = [selectedValues[index] for index in indices] names = [self.parameters[i] for i in indices] keyComponents = [f"{name}_{value}" for name, value in zip(names, values)] key = tuple(keyComponents[:len(self.parameters)-2]) - """Get the names of the other 2 parameters that are not included in the key""" + """Get the names of the other parameters that are not included in the key""" otherParams = [self.parameters[i] for i in range(len(self.parameters)) if i not in indices] - """Append the values of the other 2 parameters and the ttas to the lists for the key""" + """Append the values of the other parameters and the ttas to the lists for the key""" otherIndices = [i for i in range(len(self.parameters)) if i not in indices] """Initialize the dictionary for the key if it doesn't exist yet""" if key not in data: data[key] = {} - """Initialize lists for the other 2 parameters and the ttas with the key""" + """Initialize lists for the other parameters and the ttas with the key""" data[key][otherParams[0]] = [] data[key][otherParams[1]] = [] data[key]['ttas'] = [] @@ -73,14 +82,14 @@ class Visualizer: print("Getting data from the folder...") return data - def averageRuns(self, data): + def averageRuns(self, data, runs): """Get the average of run 0 and run 1 for each key""" newData = {} for key, value in data.items(): runExists = False """Check if the key contains 'run_' with a numerical value""" for item in key: - if item.startswith('run_0'): + if item.startswith('run_'): runExists = True break if runExists: @@ -88,20 +97,20 @@ class Visualizer: """Create a new key with the other items in the tuple""" if item.startswith('run_'): newKey = tuple([x for x in key if x != item]) - key0 = ('run_0',) + newKey - data0 = data[key0] - key1 = ('run_1',) + newKey - data1 = data[key1] + """Average the similar key values""" + total = [0] * len(data[key]['ttas']) + for i in range(runs): + key0 = (f'run_{i}',) + newKey + for cnt, tta in enumerate(data[key0]['ttas']): + total[cnt] += tta + for i in range(len(total)): + total[i] = total[i]/runs averages = {} - for key in data0.keys(): - if key in data1: - values = [] - for i in range(len(data0[key])): - value = (data0[key][i] + data1[key][i]) / 2.0 - if isinstance(data0[key][i], int) and isinstance(data1[key][i], int) and key != 'ttas': - value = int(value) - values.append(value) - averages[key] = values + for subkey in data[key].keys(): + if subkey == 'ttas': + averages[subkey] = total + else: + averages[subkey] = data[key][subkey] newData[newKey] = averages print("Getting the average of the runs...") return newData @@ -135,9 +144,12 @@ class Visualizer: def plotHeatmaps(self): """Plot and store the 2D heatmaps in subfolders""" - data = self.plottingData() - data = self.averageRuns(data) + data= self.plottingData() + """Average the runs if needed""" + if(len(runs) > 1): + data = self.averageRuns(data, len(runs)) filteredKeys = self.similarKeys(data) + vmin, vmax = 0, self.maxTTA print("Plotting heatmaps...") """Create the directory if it doesn't exist already""" @@ -152,10 +164,10 @@ class Visualizer: ylabels = np.sort(np.unique(data[key][labels[1]])) if len(xlabels) < self.minimumDataPoints or len(ylabels) < self.minimumDataPoints: continue - hist, xedges, yedges = np.histogram2d(data[key][labels[0]], data[key][labels[1]], bins=(len(xlabels), len(ylabels)), weights=data[key]['ttas']) + hist, xedges, yedges = np.histogram2d(data[key][labels[0]], data[key][labels[1]], bins=(len(xlabels), len(ylabels)), weights=data[key]['ttas'], normed=False) hist = hist.T fig, ax = plt.subplots(figsize=(10, 6)) - sns.heatmap(hist, xticklabels=xlabels, yticklabels=ylabels, cmap='Purples', cbar_kws={'label': 'Time to block availability'}, linecolor='black', linewidths=0.3, annot=True, fmt=".2f", ax=ax) + sns.heatmap(hist, xticklabels=xlabels, yticklabels=ylabels, cmap='Purples', cbar_kws={'label': 'Time to block availability'}, linecolor='black', linewidths=0.3, annot=True, fmt=".2f", ax=ax, vmin=vmin, vmax=vmax) plt.xlabel(self.formatLabel(labels[0])) plt.ylabel(self.formatLabel(labels[1])) filename = "" @@ -177,3 +189,18 @@ class Visualizer: plt.savefig(os.path.join(targetFolder, filename)) plt.close() plt.clf() + + def plotHist(self, bandwidth): + """Plot Bandwidth Frequency Histogram""" + plt.hist(bandwidth, bins=5) + plt.xlabel('Bandwidth') + plt.ylabel('Frequency') + plt.title('Bandwidth Histogram') + + """Create the directory if it doesn't exist already""" + histogramFolder = self.folderPath + '/histogram' + if not os.path.exists(histogramFolder): + os.makedirs(histogramFolder) + filename = os.path.join(histogramFolder, 'histogram.png') + plt.savefig(filename) + plt.clf() \ No newline at end of file diff --git a/config_example.py b/config_example.py index af55fc2..9e99c18 100644 --- a/config_example.py +++ b/config_example.py @@ -24,36 +24,36 @@ logLevel = logging.INFO # number of parallel workers. -1: all cores; 1: sequential # for more details, see joblib.Parallel -numJobs = 3 +numJobs = -1 # distribute rows/columns evenly between validators (True) # or generate it using local randomness (False) evenLineDistribution = True # Number of simulation runs with the same parameters for statistical relevance -runs = range(10) +runs = range(3) # Number of validators -numberNodes = range(256, 513, 128) +numberNodes = range(256, 313, 128) # Percentage of block not released by producer -failureRates = range(10, 91, 40) +failureRates = range(10, 31, 40) # Block size in one dimension in segments. Block is blockSizes * blockSizes segments. -blockSizes = range(32,65,16) +blockSizes = range(32,35,16) # Per-topic mesh neighborhood size netDegrees = range(6, 9, 2) # number of rows and columns a validator is interested in -chis = range(1, 5, 2) +chis = range(2, 5, 2) # ratio of class1 nodes (see below for parameters per class) -class1ratios = np.arange(0, 1, .2) +class1ratios = [0.8, 0.9] # Number of validators per beacon node validatorsPerNode1 = [1] -validatorsPerNode2 = [2, 4, 8, 16, 32] +validatorsPerNode2 = [50] # Set uplink bandwidth. In segments (~560 bytes) per timestep (50ms?) # 1 Mbps ~= 1e6 / 20 / 8 / 560 ~= 11 @@ -62,7 +62,7 @@ bwUplinks1 = [110] bwUplinks2 = [2200] # Set to True if you want your run to be deterministic, False if not -deterministic = False +deterministic = True # If your run is deterministic you can decide the random seed. This is ignore otherwise. randomSeed = "DAS" From b36a94e269a02a3785b00add18d95783c19da567 Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Thu, 20 Apr 2023 18:15:02 +0200 Subject: [PATCH 03/11] Fix runs bug --- DAS/visualizer.py | 16 ++++++++-------- study.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/DAS/visualizer.py b/DAS/visualizer.py index be05ed0..8f4abc6 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -6,12 +6,12 @@ import matplotlib.pyplot as plt import numpy as np import seaborn as sns from itertools import combinations -from config_example import runs class Visualizer: - def __init__(self, execID): + def __init__(self, execID, config): self.execID = execID + self.config = config self.folderPath = "results/"+self.execID self.parameters = ['run', 'blockSize', 'failureRate', 'numberNodes', 'netDegree', 'chi', 'vpn1', 'vpn2', 'class1ratio', 'bwUplinkProd', 'bwUplink1', 'bwUplink2'] self.minimumDataPoints = 2 @@ -81,7 +81,7 @@ class Visualizer: data[key]['ttas'].append(tta) print("Getting data from the folder...") return data - + def averageRuns(self, data, runs): """Get the average of run 0 and run 1 for each key""" newData = {} @@ -146,12 +146,12 @@ class Visualizer: """Plot and store the 2D heatmaps in subfolders""" data= self.plottingData() """Average the runs if needed""" - if(len(runs) > 1): - data = self.averageRuns(data, len(runs)) + if(len(self.config.runs) > 1): + data = self.averageRuns(data, len(self.config.runs)) filteredKeys = self.similarKeys(data) vmin, vmax = 0, self.maxTTA print("Plotting heatmaps...") - + """Create the directory if it doesn't exist already""" heatmapsFolder = self.folderPath + '/heatmaps' if not os.path.exists(heatmapsFolder): @@ -189,7 +189,7 @@ class Visualizer: plt.savefig(os.path.join(targetFolder, filename)) plt.close() plt.clf() - + def plotHist(self, bandwidth): """Plot Bandwidth Frequency Histogram""" plt.hist(bandwidth, bins=5) @@ -203,4 +203,4 @@ class Visualizer: os.makedirs(histogramFolder) filename = os.path.join(histogramFolder, 'histogram.png') plt.savefig(filename) - plt.clf() \ No newline at end of file + plt.clf() diff --git a/study.py b/study.py index 2b2aab6..a15e7b2 100644 --- a/study.py +++ b/study.py @@ -60,7 +60,7 @@ def study(): sim.logger.info("Results dumped into results/%s/" % (execID), extra=sim.format) if config.visualization: - vis = Visualizer(execID) + vis = Visualizer(execID, config) vis.plotHeatmaps() From c7f9577d4531e80a47d7e6baeb2b0ab1d6102c04 Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Thu, 20 Apr 2023 21:53:25 +0200 Subject: [PATCH 04/11] Fix max value for tta --- DAS/visualizer.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/DAS/visualizer.py b/DAS/visualizer.py index 8f4abc6..c237a95 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -85,6 +85,8 @@ class Visualizer: def averageRuns(self, data, runs): """Get the average of run 0 and run 1 for each key""" newData = {} + allTta = [] + print("Getting the average of the runs...") for key, value in data.items(): runExists = False """Check if the key contains 'run_' with a numerical value""" @@ -97,12 +99,15 @@ class Visualizer: """Create a new key with the other items in the tuple""" if item.startswith('run_'): newKey = tuple([x for x in key if x != item]) + print(newKey) """Average the similar key values""" total = [0] * len(data[key]['ttas']) for i in range(runs): key0 = (f'run_{i}',) + newKey for cnt, tta in enumerate(data[key0]['ttas']): total[cnt] += tta + allTta.append(tta) + print(tta) for i in range(len(total)): total[i] = total[i]/runs averages = {} @@ -112,7 +117,7 @@ class Visualizer: else: averages[subkey] = data[key][subkey] newData[newKey] = averages - print("Getting the average of the runs...") + self.maxTTA = max(allTta) + 10 return newData def similarKeys(self, data): From 9d699ada5127f332ac66542d90daabd711bc9c66 Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Fri, 21 Apr 2023 07:14:45 +0200 Subject: [PATCH 05/11] Remove debug lines --- DAS/visualizer.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/DAS/visualizer.py b/DAS/visualizer.py index c237a95..0d72a94 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -99,7 +99,6 @@ class Visualizer: """Create a new key with the other items in the tuple""" if item.startswith('run_'): newKey = tuple([x for x in key if x != item]) - print(newKey) """Average the similar key values""" total = [0] * len(data[key]['ttas']) for i in range(runs): @@ -107,7 +106,6 @@ class Visualizer: for cnt, tta in enumerate(data[key0]['ttas']): total[cnt] += tta allTta.append(tta) - print(tta) for i in range(len(total)): total[i] = total[i]/runs averages = {} From 4f0e888c1bdc1a312e61e06f167c6cd95a51162d Mon Sep 17 00:00:00 2001 From: HajarZaiz Date: Fri, 21 Apr 2023 09:45:17 +0000 Subject: [PATCH 06/11] Other plots --- .gitignore | 1 + DAS/visualizer.py | 38 ++++++++++++++++++++++++++++++- config_example.py => smallConf.py | 37 +++++++++++++++++++++++------- 3 files changed, 67 insertions(+), 9 deletions(-) rename config_example.py => smallConf.py (79%) diff --git a/.gitignore b/.gitignore index 492044a..3304f8f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ myenv doc/_build !results/plots.py Frontend/ +smallConf.py diff --git a/DAS/visualizer.py b/DAS/visualizer.py index 0d72a94..b28016a 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -6,6 +6,7 @@ import matplotlib.pyplot as plt import numpy as np import seaborn as sns from itertools import combinations +from mplfinance.original_flavor import candlestick_ohlc class Visualizer: @@ -83,7 +84,7 @@ class Visualizer: return data def averageRuns(self, data, runs): - """Get the average of run 0 and run 1 for each key""" + """Get the average of all runs for each key""" newData = {} allTta = [] print("Getting the average of the runs...") @@ -207,3 +208,38 @@ class Visualizer: filename = os.path.join(histogramFolder, 'histogram.png') plt.savefig(filename) plt.clf() + + def plotHist(self, bandwidth): + """Plot Bandwidth Frequency Histogram""" + plt.hist(bandwidth, bins=5) + plt.xlabel('Bandwidth') + plt.ylabel('Frequency') + plt.title('Bandwidth Histogram') + + """Create the directory if it doesn't exist already""" + histogramFolder = self.folderPath + '/histogram' + if not os.path.exists(histogramFolder): + os.makedirs(histogramFolder) + filename = os.path.join(histogramFolder, 'histogram.png') + plt.savefig(filename) + plt.clf() + + def plotCandleStick(self, TX_prod, TX_avg, TX_max): + #x-axis corresponding to steps + steps = range(len(TX_prod)) + + #Plot the candlestick chart + ohlc = [] + for i in range(len(TX_prod)): + ohlc.append([steps[i], TX_prod[i], TX_max[i], TX_avg[i]]) + fig, ax = plt.subplots() + candlestick_ohlc(ax, ohlc, width=0.6, colorup='green', colordown='red') + + #Ticks, title and labels + plt.xticks(steps, ['run{}'.format(i) for i in steps], rotation=45) + plt.title('Candlestick Chart') + plt.xlabel('Step') + plt.ylabel('Price') + + #Test + plt.show() \ No newline at end of file diff --git a/config_example.py b/smallConf.py similarity index 79% rename from config_example.py rename to smallConf.py index 9e99c18..5711380 100644 --- a/config_example.py +++ b/smallConf.py @@ -19,6 +19,13 @@ import numpy as np from DAS.shape import Shape dumpXML = 1 + +# save progress vectors to XML +saveProgress = 1 + +# plot progress for each run to PNG +plotProgress = 1 + visualization = 1 logLevel = logging.INFO @@ -34,26 +41,26 @@ evenLineDistribution = True runs = range(3) # Number of validators -numberNodes = range(256, 313, 128) +numberNodes = range(128, 513, 128) # Percentage of block not released by producer -failureRates = range(10, 31, 40) +failureRates = range(40, 81, 20) # Block size in one dimension in segments. Block is blockSizes * blockSizes segments. -blockSizes = range(32,35,16) +blockSizes = range(64, 113, 128) # Per-topic mesh neighborhood size -netDegrees = range(6, 9, 2) +netDegrees = range(8, 9, 2) # number of rows and columns a validator is interested in -chis = range(2, 5, 2) +chis = range(2, 3, 2) # ratio of class1 nodes (see below for parameters per class) -class1ratios = [0.8, 0.9] +class1ratios = [0.8] # Number of validators per beacon node -validatorsPerNode1 = [1] -validatorsPerNode2 = [50] +validatorsPerNode1 = [2] +validatorsPerNode2 = [4] # Set uplink bandwidth. In segments (~560 bytes) per timestep (50ms?) # 1 Mbps ~= 1e6 / 20 / 8 / 560 ~= 11 @@ -67,6 +74,20 @@ deterministic = True # If your run is deterministic you can decide the random seed. This is ignore otherwise. randomSeed = "DAS" +saveProgress = 1 +saveRCdist = 1 + +# If True, print diagnostics when the block is not available +diagnostics = False + +# Number of steps without progress to stop simulation +steps4StopCondition = 7 + +saveGit = False + +successCondition = 0.9 +stepDuration = 50 + def nextShape(): for run, fr, class1ratio, chi, vpn1, vpn2, blockSize, nn, netDegree, bwUplinkProd, bwUplink1, bwUplink2 in itertools.product( runs, failureRates, class1ratios, chis, validatorsPerNode1, validatorsPerNode2, blockSizes, numberNodes, netDegrees, bwUplinksProd, bwUplinks1, bwUplinks2): From ffeac4608b3e353f2e581c21e7cd9f24f9f1b198 Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Fri, 21 Apr 2023 17:13:53 +0200 Subject: [PATCH 07/11] Update requirements --- DAS/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DAS/requirements.txt b/DAS/requirements.txt index da7dcc7..83eca18 100644 --- a/DAS/requirements.txt +++ b/DAS/requirements.txt @@ -1,7 +1,8 @@ bitarray==2.6.0 -DAS==0.29.0 +DAS==0.30.0 dicttoxml==1.7.16 matplotlib==3.6.2 +mplfinance==0.12.9b7 networkx==3.0 numpy==1.23.5 seaborn==0.12.2 From 6fe0fab6d083f2478b89beb58e83a3a7315afb98 Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Fri, 21 Apr 2023 17:14:55 +0200 Subject: [PATCH 08/11] Inverse heatmap --- DAS/visualizer.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/DAS/visualizer.py b/DAS/visualizer.py index b28016a..5d2f341 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -16,12 +16,13 @@ class Visualizer: self.folderPath = "results/"+self.execID self.parameters = ['run', 'blockSize', 'failureRate', 'numberNodes', 'netDegree', 'chi', 'vpn1', 'vpn2', 'class1ratio', 'bwUplinkProd', 'bwUplink1', 'bwUplink2'] self.minimumDataPoints = 2 - self.maxTTA = 999 + self.maxTTA = 99 def plottingData(self): """Store data with a unique key for each params combination""" data = {} bw = [] + print("Getting data from the folder...") """Loop over the xml files in the folder""" for filename in os.listdir(self.folderPath): """Loop over the xmls and store the data in variables""" @@ -41,9 +42,8 @@ class Visualizer: bwUplink1 = int(root.find('bwUplink1').text) bwUplink2 = int(root.find('bwUplink2').text) tta = int(root.find('tta').text) - - # if tta == -1: - # tta = self.maxTTA + if tta == -1: + tta = self.maxTTA """Store BW""" bw.append(bwUplinkProd) @@ -80,7 +80,6 @@ class Visualizer: else: data[key][otherParams[1]] = [selectedValues[otherIndices[1]]] data[key]['ttas'].append(tta) - print("Getting data from the folder...") return data def averageRuns(self, data, runs): @@ -116,7 +115,6 @@ class Visualizer: else: averages[subkey] = data[key][subkey] newData[newKey] = averages - self.maxTTA = max(allTta) + 10 return newData def similarKeys(self, data): @@ -171,7 +169,7 @@ class Visualizer: hist, xedges, yedges = np.histogram2d(data[key][labels[0]], data[key][labels[1]], bins=(len(xlabels), len(ylabels)), weights=data[key]['ttas'], normed=False) hist = hist.T fig, ax = plt.subplots(figsize=(10, 6)) - sns.heatmap(hist, xticklabels=xlabels, yticklabels=ylabels, cmap='Purples', cbar_kws={'label': 'Time to block availability'}, linecolor='black', linewidths=0.3, annot=True, fmt=".2f", ax=ax, vmin=vmin, vmax=vmax) + sns.heatmap(hist, xticklabels=xlabels, yticklabels=ylabels, cmap='hot_r', cbar_kws={'label': 'Time to block availability'}, linecolor='black', linewidths=0.3, annot=True, fmt=".2f", ax=ax, vmin=vmin, vmax=vmax) plt.xlabel(self.formatLabel(labels[0])) plt.ylabel(self.formatLabel(labels[1])) filename = "" @@ -242,4 +240,4 @@ class Visualizer: plt.ylabel('Price') #Test - plt.show() \ No newline at end of file + plt.show() From e7c2807acaaa7721bc223f56f012a38316a92aa6 Mon Sep 17 00:00:00 2001 From: HajarZaiz Date: Sun, 23 Apr 2023 14:55:31 +0000 Subject: [PATCH 09/11] Minor changes --- .gitignore | 1 - DAS/visualizer.py | 20 +++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 3304f8f..492044a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,3 @@ myenv doc/_build !results/plots.py Frontend/ -smallConf.py diff --git a/DAS/visualizer.py b/DAS/visualizer.py index 5d2f341..ca19d99 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -7,6 +7,8 @@ import numpy as np import seaborn as sns from itertools import combinations from mplfinance.original_flavor import candlestick_ohlc +import os + class Visualizer: @@ -42,8 +44,6 @@ class Visualizer: bwUplink1 = int(root.find('bwUplink1').text) bwUplink2 = int(root.find('bwUplink2').text) tta = int(root.find('tta').text) - if tta == -1: - tta = self.maxTTA """Store BW""" bw.append(bwUplinkProd) @@ -83,9 +83,11 @@ class Visualizer: return data def averageRuns(self, data, runs): + '''Debugging''' + if not os.path.exists('debug'): + os.makedirs('debug') """Get the average of all runs for each key""" newData = {} - allTta = [] print("Getting the average of the runs...") for key, value in data.items(): runExists = False @@ -101,13 +103,21 @@ class Visualizer: newKey = tuple([x for x in key if x != item]) """Average the similar key values""" total = [0] * len(data[key]['ttas']) + with open('debug/debug.txt', 'a') as f: + f.write('TTAs:\n') for i in range(runs): key0 = (f'run_{i}',) + newKey + with open('debug/debug.txt', 'a') as f: + f.write(str(data[key0]['ttas']) + '\n') for cnt, tta in enumerate(data[key0]['ttas']): total[cnt] += tta - allTta.append(tta) for i in range(len(total)): total[i] = total[i]/runs + if(total[i] == -1): + total[i] = self.maxTTA + with open('debug/debug.txt', 'a') as f: + f.write('Average:\n') + f.write(str(total)+ '\n') averages = {} for subkey in data[key].keys(): if subkey == 'ttas': @@ -166,7 +176,7 @@ class Visualizer: ylabels = np.sort(np.unique(data[key][labels[1]])) if len(xlabels) < self.minimumDataPoints or len(ylabels) < self.minimumDataPoints: continue - hist, xedges, yedges = np.histogram2d(data[key][labels[0]], data[key][labels[1]], bins=(len(xlabels), len(ylabels)), weights=data[key]['ttas'], normed=False) + hist, xedges, yedges = np.histogram2d(data[key][labels[0]], data[key][labels[1]], bins=(len(xlabels), len(ylabels)), weights=data[key]['ttas']) hist = hist.T fig, ax = plt.subplots(figsize=(10, 6)) sns.heatmap(hist, xticklabels=xlabels, yticklabels=ylabels, cmap='hot_r', cbar_kws={'label': 'Time to block availability'}, linecolor='black', linewidths=0.3, annot=True, fmt=".2f", ax=ax, vmin=vmin, vmax=vmax) From 3fbda15272f601194667f68f3edd771f2015b261 Mon Sep 17 00:00:00 2001 From: HajarZaiz Date: Tue, 25 Apr 2023 21:32:31 +0000 Subject: [PATCH 10/11] Avg changes --- DAS/visualizer.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/DAS/visualizer.py b/DAS/visualizer.py index ca19d99..4712687 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -83,9 +83,6 @@ class Visualizer: return data def averageRuns(self, data, runs): - '''Debugging''' - if not os.path.exists('debug'): - os.makedirs('debug') """Get the average of all runs for each key""" newData = {} print("Getting the average of the runs...") @@ -97,33 +94,37 @@ class Visualizer: runExists = True break if runExists: + ps = list(data[key].keys()) for item in key: """Create a new key with the other items in the tuple""" if item.startswith('run_'): newKey = tuple([x for x in key if x != item]) """Average the similar key values""" - total = [0] * len(data[key]['ttas']) - with open('debug/debug.txt', 'a') as f: - f.write('TTAs:\n') + tta_sums = {} + total = [] + p0 = [] + p1 = [] for i in range(runs): key0 = (f'run_{i}',) + newKey - with open('debug/debug.txt', 'a') as f: - f.write(str(data[key0]['ttas']) + '\n') - for cnt, tta in enumerate(data[key0]['ttas']): - total[cnt] += tta + #Create a dictionary to store the sums of ttas for each unique pair of values in subkeys + for i in range(len(data[key0][ps[0]])): + keyPair = (data[key0][ps[0]][i], data[key0][ps[1]][i]) + try: + tta_sums[keyPair] += data[key0]['ttas'][i] + except KeyError: + tta_sums[keyPair] = data[key0]['ttas'][i] + for k, tta in tta_sums.items(): + p0.append(k[0]) + p1.append(k[1]) + total.append(tta) for i in range(len(total)): total[i] = total[i]/runs if(total[i] == -1): total[i] = self.maxTTA - with open('debug/debug.txt', 'a') as f: - f.write('Average:\n') - f.write(str(total)+ '\n') averages = {} - for subkey in data[key].keys(): - if subkey == 'ttas': - averages[subkey] = total - else: - averages[subkey] = data[key][subkey] + averages[ps[0]] = p0 + averages[ps[1]] = p1 + averages['ttas'] = total newData[newKey] = averages return newData From eed410e4db53bc66761e7cdeb7ccb1948473599f Mon Sep 17 00:00:00 2001 From: Leonardo Bautista-Gomez Date: Wed, 26 Apr 2023 18:22:17 +0200 Subject: [PATCH 11/11] Do not count unavailable block on averages --- DAS/visualizer.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/DAS/visualizer.py b/DAS/visualizer.py index 4712687..621f579 100644 --- a/DAS/visualizer.py +++ b/DAS/visualizer.py @@ -18,7 +18,7 @@ class Visualizer: self.folderPath = "results/"+self.execID self.parameters = ['run', 'blockSize', 'failureRate', 'numberNodes', 'netDegree', 'chi', 'vpn1', 'vpn2', 'class1ratio', 'bwUplinkProd', 'bwUplink1', 'bwUplink2'] self.minimumDataPoints = 2 - self.maxTTA = 99 + self.maxTTA = 50 def plottingData(self): """Store data with a unique key for each params combination""" @@ -101,26 +101,46 @@ class Visualizer: newKey = tuple([x for x in key if x != item]) """Average the similar key values""" tta_sums = {} + nbRuns = {} + ttRuns = [] total = [] p0 = [] p1 = [] + p2 = [] + p3 = [] for i in range(runs): key0 = (f'run_{i}',) + newKey #Create a dictionary to store the sums of ttas for each unique pair of values in subkeys for i in range(len(data[key0][ps[0]])): keyPair = (data[key0][ps[0]][i], data[key0][ps[1]][i]) + if data[key0]["ttas"][i] == -1: + data[key0]["ttas"][i] = self.maxTTA try: tta_sums[keyPair] += data[key0]['ttas'][i] + if data[key0]["ttas"][i] != self.maxTTA: + nbRuns[keyPair] += 1 except KeyError: tta_sums[keyPair] = data[key0]['ttas'][i] + if data[key0]["ttas"][i] != self.maxTTA: + nbRuns[keyPair] = 1 + else: + nbRuns[keyPair] = 0 for k, tta in tta_sums.items(): p0.append(k[0]) p1.append(k[1]) total.append(tta) + for k, run in nbRuns.items(): + p2.append(k[0]) + p3.append(k[1]) + ttRuns.append(run) for i in range(len(total)): - total[i] = total[i]/runs - if(total[i] == -1): + if(ttRuns[i] == 0): # All tta = -1 total[i] = self.maxTTA + elif ttRuns[i] < runs: # Some tta = -1 + total[i] -= (runs-ttRuns[i]) * self.maxTTA + total[i] = total[i]/ttRuns[i] + else: # No tta = -1 + total[i] = total[i]/ttRuns[i] averages = {} averages[ps[0]] = p0 averages[ps[1]] = p1 @@ -162,7 +182,7 @@ class Visualizer: if(len(self.config.runs) > 1): data = self.averageRuns(data, len(self.config.runs)) filteredKeys = self.similarKeys(data) - vmin, vmax = 0, self.maxTTA + vmin, vmax = 0, self.maxTTA+10 print("Plotting heatmaps...") """Create the directory if it doesn't exist already""" @@ -189,7 +209,8 @@ class Visualizer: for param in self.parameters: if param != labels[0] and param != labels[1] and param != 'run': filename += f"{key[paramValueCnt]}" - formattedTitle = self.formatTitle(key[paramValueCnt]) + #formattedTitle = self.formatTitle(key[paramValueCnt]) + formattedTitle = "Time to block availability" title += formattedTitle paramValueCnt += 1 title_obj = plt.title(title)