diff options
Diffstat (limited to 'bin/mimosa-etv')
-rwxr-xr-x | bin/mimosa-etv | 163 |
1 files changed, 105 insertions, 58 deletions
diff --git a/bin/mimosa-etv b/bin/mimosa-etv index e23b46c..431e275 100755 --- a/bin/mimosa-etv +++ b/bin/mimosa-etv @@ -8,13 +8,16 @@ import numpy as np import os import re import sys -from dfatool.dfatool import aggregate_measures, MIMOSA +from dfatool.dfatool import MIMOSA +from dfatool.model import aggregate_measures from dfatool.utils import running_mean opt = dict() + def show_help(): - print('''mimosa-etv - MIMOSA Analyzer and Visualizer + print( + """mimosa-etv - MIMOSA Analyzer and Visualizer USAGE @@ -41,7 +44,9 @@ OPTIONS Show power/time plot --stat Show mean voltage, current, and power as well as total energy consumption. - ''') + """ + ) + def peak_search(data, lower, upper, direction_function): while upper - lower > 1e-6: @@ -58,6 +63,7 @@ def peak_search(data, lower, upper, direction_function): upper = bs_test return None + def peak_search2(data, lower, upper, check_function): for power in np.arange(lower, upper, 1e-6): peakcount = itertools.groupby(data, lambda x: x >= power) @@ -67,38 +73,39 @@ def peak_search2(data, lower, upper, check_function): return power return None -if __name__ == '__main__': + +if __name__ == "__main__": try: - optspec = ('help skip= threshold= threshold-peakcount= plot stat') - raw_opts, args = getopt.getopt(sys.argv[1:], "", optspec.split(' ')) + optspec = "help skip= threshold= threshold-peakcount= plot stat" + raw_opts, args = getopt.getopt(sys.argv[1:], "", optspec.split(" ")) for option, parameter in raw_opts: - optname = re.sub(r'^--', '', option) + optname = re.sub(r"^--", "", option) opt[optname] = parameter - if 'help' in opt: + if "help" in opt: show_help() sys.exit(0) - if 'skip' in opt: - opt['skip'] = int(opt['skip']) + if "skip" in opt: + opt["skip"] = int(opt["skip"]) else: - opt['skip'] = 0 + opt["skip"] = 0 - if 'threshold' in opt and opt['threshold'] != 'mean': - opt['threshold'] = float(opt['threshold']) + if "threshold" in opt and opt["threshold"] != "mean": + opt["threshold"] = float(opt["threshold"]) - if 'threshold-peakcount' in opt: - opt['threshold-peakcount'] = int(opt['threshold-peakcount']) + if "threshold-peakcount" in opt: + opt["threshold-peakcount"] = int(opt["threshold-peakcount"]) except getopt.GetoptError as err: print(err) sys.exit(2) except IndexError: - print('Usage: mimosa-etv <duration>') + print("Usage: mimosa-etv <duration>") sys.exit(2) except ValueError: - print('Error: duration or skip is not a number') + print("Error: duration or skip is not a number") sys.exit(2) voltage, shunt, inputfile = args @@ -110,7 +117,7 @@ if __name__ == '__main__': currents = mim.charge_to_current_nocal(charges) * 1e-6 powers = currents * voltage - if 'threshold-peakcount' in opt: + if "threshold-peakcount" in opt: bs_mean = np.mean(powers) # Finding the correct threshold is tricky. If #peaks < peakcont, our @@ -126,42 +133,59 @@ if __name__ == '__main__': # #peaks != peakcount and threshold >= mean, we go down. # If that doesn't work, we fall back to a linear search in 1 µW steps def direction_function(peakcount, power): - if peakcount == opt['threshold-peakcount']: + if peakcount == opt["threshold-peakcount"]: return 0 if power < bs_mean: return 1 return -1 + threshold = peak_search(power, np.min(power), np.max(power), direction_function) if threshold == None: - threshold = peak_search2(power, np.min(power), np.max(power), direction_function) + threshold = peak_search2( + power, np.min(power), np.max(power), direction_function + ) if threshold != None: - print('Threshold set to {:.0f} µW : {:.9f}'.format(threshold * 1e6, threshold)) - opt['threshold'] = threshold + print( + "Threshold set to {:.0f} µW : {:.9f}".format( + threshold * 1e6, threshold + ) + ) + opt["threshold"] = threshold else: - print('Found no working threshold') + print("Found no working threshold") - if 'threshold' in opt: - if opt['threshold'] == 'mean': - opt['threshold'] = np.mean(powers) - print('Threshold set to {:.0f} µW : {:.9f}'.format(opt['threshold'] * 1e6, opt['threshold'])) + if "threshold" in opt: + if opt["threshold"] == "mean": + opt["threshold"] = np.mean(powers) + print( + "Threshold set to {:.0f} µW : {:.9f}".format( + opt["threshold"] * 1e6, opt["threshold"] + ) + ) baseline_mean = 0 - if np.any(powers < opt['threshold']): - baseline_mean = np.mean(powers[powers < opt['threshold']]) - print('Baseline mean: {:.0f} µW : {:.9f}'.format( - baseline_mean * 1e6, baseline_mean)) - if np.any(powers >= opt['threshold']): - print('Peak mean: {:.0f} µW : {:.9f}'.format( - np.mean(powers[powers >= opt['threshold']]) * 1e6, - np.mean(powers[powers >= opt['threshold']]))) + if np.any(powers < opt["threshold"]): + baseline_mean = np.mean(powers[powers < opt["threshold"]]) + print( + "Baseline mean: {:.0f} µW : {:.9f}".format( + baseline_mean * 1e6, baseline_mean + ) + ) + if np.any(powers >= opt["threshold"]): + print( + "Peak mean: {:.0f} µW : {:.9f}".format( + np.mean(powers[powers >= opt["threshold"]]) * 1e6, + np.mean(powers[powers >= opt["threshold"]]), + ) + ) peaks = [] peak_start = -1 for i, dp in enumerate(powers): - if dp >= opt['threshold'] and peak_start == -1: + if dp >= opt["threshold"] and peak_start == -1: peak_start = i - elif dp < opt['threshold'] and peak_start != -1: + elif dp < opt["threshold"] and peak_start != -1: peaks.append((peak_start, i)) peak_start = -1 @@ -170,32 +194,55 @@ if __name__ == '__main__': for peak in peaks: duration = (peak[1] - peak[0]) * 1e-5 total_energy += np.mean(powers[peak[0] : peak[1]]) * duration - delta_energy += (np.mean(powers[peak[0] : peak[1]]) - baseline_mean) * duration + delta_energy += ( + np.mean(powers[peak[0] : peak[1]]) - baseline_mean + ) * duration delta_powers = powers[peak[0] : peak[1]] - baseline_mean - print('{:.2f}ms peak ({:f} -> {:f})'.format(duration * 1000, - peak[0], peak[1])) - print(' {:f} µJ / mean {:f} µW'.format( - np.mean(powers[peak[0] : peak[1]]) * duration * 1e6, - np.mean(powers[peak[0] : peak[1]]) * 1e6 )) + print( + "{:.2f}ms peak ({:f} -> {:f})".format(duration * 1000, peak[0], peak[1]) + ) + print( + " {:f} µJ / mean {:f} µW".format( + np.mean(powers[peak[0] : peak[1]]) * duration * 1e6, + np.mean(powers[peak[0] : peak[1]]) * 1e6, + ) + ) measures = aggregate_measures(np.mean(delta_powers), delta_powers) - print(' {:f} µW delta mean = {:0.1f}% / {:f} µW error'.format(np.mean(delta_powers) * 1e6, measures['smape'], measures['rmsd'] * 1e6 )) - print('Peak energy mean: {:.0f} µJ : {:.9f}'.format( - total_energy * 1e6 / len(peaks), total_energy / len(peaks))) - print('Average per-peak energy (delta over baseline): {:.0f} µJ : {:.9f}'.format( - delta_energy * 1e6 / len(peaks), delta_energy / len(peaks))) - - - if 'stat' in opt: + print( + " {:f} µW delta mean = {:0.1f}% / {:f} µW error".format( + np.mean(delta_powers) * 1e6, + measures["smape"], + measures["rmsd"] * 1e6, + ) + ) + print( + "Peak energy mean: {:.0f} µJ : {:.9f}".format( + total_energy * 1e6 / len(peaks), total_energy / len(peaks) + ) + ) + print( + "Average per-peak energy (delta over baseline): {:.0f} µJ : {:.9f}".format( + delta_energy * 1e6 / len(peaks), delta_energy / len(peaks) + ) + ) + + if "stat" in opt: mean_current = np.mean(currents) mean_power = np.mean(powers) - print('Mean current: {:.0f} µA : {:.9f}'.format(mean_current * 1e6, mean_current)) - print('Mean power: {:.0f} µW : {:.9f}'.format(mean_power * 1e6, mean_power)) - - if 'plot' in opt: + print( + "Mean current: {:.0f} µA : {:.9f}".format( + mean_current * 1e6, mean_current + ) + ) + print( + "Mean power: {:.0f} µW : {:.9f}".format(mean_power * 1e6, mean_power) + ) + + if "plot" in opt: timestamps = np.arange(len(powers)) * 1e-5 - pwrhandle, = plt.plot(timestamps, powers, 'b-', label='U*I', markersize=1) + (pwrhandle,) = plt.plot(timestamps, powers, "b-", label="U*I", markersize=1) plt.legend(handles=[pwrhandle]) - plt.xlabel('Time [s]') - plt.ylabel('Power [W]') + plt.xlabel("Time [s]") + plt.ylabel("Power [W]") plt.grid(True) plt.show() |