diff options
-rwxr-xr-x | bin/dfatool | 2 | ||||
-rwxr-xr-x | bin/merge.py | 22 | ||||
-rwxr-xr-x | bin/mimplot | 27 | ||||
-rw-r--r-- | lib/Kratos/DFADriver.pm | 6 | ||||
-rw-r--r-- | lib/Kratos/DFADriver/Model.pm | 63 |
5 files changed, 117 insertions, 3 deletions
diff --git a/bin/dfatool b/bin/dfatool index cdaae5a..0c57b7c 100755 --- a/bin/dfatool +++ b/bin/dfatool @@ -29,6 +29,7 @@ GetOptions( trigger-pin=i trigger-port=s voltage=f + with-lut! offset=i zomg-fasta-nao } @@ -61,6 +62,7 @@ my $driver = Kratos::DFADriver->new( mimosa_voltage => $opt{voltage} // 3.60, trace_filter => $opt{'trace-filter'} // [], trace_revisit => $opt{'trace-revisit'} // 2, + with_lut => $opt{'with-lut'}, xml_file => $xml_file, ); diff --git a/bin/merge.py b/bin/merge.py index f7dbf90..6091ba1 100755 --- a/bin/merge.py +++ b/bin/merge.py @@ -288,6 +288,14 @@ def param_values(parameters, by_param): return paramvalues +def param_hash(values): + ret = {} + + for i, param in enumerate(parameters): + ret[param] = values[i] + + return ret + # Returns the values used for each function argument in the measurement, e.g. # { 'data': [], 'length' : [16, 31, 32] } # non-numeric values such as '' or 'long_test_string' are skipped @@ -547,11 +555,24 @@ def param_measures(name, paramdata, key, fun): def arg_measures(name, argdata, key, fun): return param_measures(name, argdata, key, fun) +def lookup_table(name, paramdata, key, fun, keyfun): + lut = [] + + for pkey, pval in paramdata.items(): + if pkey[0] == name: + lut.append({ + 'key': keyfun(pkey[1]), + 'value': fun(pval[key]), + }) + + return lut + def keydata(name, val, argdata, paramdata, tracedata, key): ret = { 'count' : len(val[key]), 'median' : np.median(val[key]), 'mean' : np.mean(val[key]), + 'median_by_param' : lookup_table(name, paramdata, key, np.median, param_hash), 'mean_goodness' : aggregate_measures(np.mean(val[key]), val[key]), 'median_goodness' : aggregate_measures(np.median(val[key]), val[key]), 'param_mean_goodness' : param_measures(name, paramdata, key, np.mean), @@ -567,6 +588,7 @@ def keydata(name, val, argdata, paramdata, tracedata, key): if val['isa'] == 'transition': ret['arg_mean_goodness'] = arg_measures(name, argdata, key, np.mean) ret['arg_median_goodness'] = arg_measures(name, argdata, key, np.median) + ret['median_by_arg'] = lookup_table(name, argdata, key, np.median, list) ret['std_arg'] = np.mean([np.std(argdata[x][key]) for x in argdata.keys() if x[0] == name]) ret['std_by_arg'] = {} ret['arg_fit_guess'] = {} diff --git a/bin/mimplot b/bin/mimplot new file mode 100755 index 0000000..1768da8 --- /dev/null +++ b/bin/mimplot @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 + +import csv +import numpy as np +import os +import struct +import sys +import tarfile +import matplotlib.pyplot as plt +from dfatool import running_mean, MIMOSA + +voltage = float(sys.argv[1]) +shunt = float(sys.argv[2]) +mimfile = sys.argv[3] + +mim = MIMOSA(voltage, shunt) + +charges, triggers = mim.load_data(mimfile) +charges = charges[:3000000] + +currents = running_mean(mim.charge_to_current_nocal(charges), 10) * 1e-6 +xr = np.arange(len(currents)) * 1e-5 +plt.plot( xr, currents, "r-") +plt.xlabel('Zeit [s]') +plt.ylabel('Strom [A]') +plt.grid(True) +plt.show() diff --git a/lib/Kratos/DFADriver.pm b/lib/Kratos/DFADriver.pm index 6acb686..046a013 100644 --- a/lib/Kratos/DFADriver.pm +++ b/lib/Kratos/DFADriver.pm @@ -615,6 +615,9 @@ sub update_model { @{ $state->{power}{function}{$fname}{params} } ); } + if ($self->{with_lut}) { + $self->model->set_state_lut( $name, 'power', $state->{power}{median_by_param} ); + } } for my $name (sort keys %{ $self->{log}{aggregate}{transition} }) { my $transition = $self->{log}{aggregate}{transition}{$name}; @@ -635,6 +638,9 @@ sub update_model { @{ $transition->{$key}{function}{$fname}{params} } ); } + if ($self->{with_lut}) { + $self->model->set_transition_lut( $name, $key, $transition->{$key}{median_by_param} ); + } } } diff --git a/lib/Kratos/DFADriver/Model.pm b/lib/Kratos/DFADriver/Model.pm index cb29f33..e6f8142 100644 --- a/lib/Kratos/DFADriver/Model.pm +++ b/lib/Kratos/DFADriver/Model.pm @@ -179,8 +179,8 @@ sub reset_property { my ($property_node) = $node->findnodes("./${name}"); if ($property_node) { - for my $static_node ($property_node->findnodes('./static')) { - $property_node->removeChild($static_node); + for my $attr_node ($property_node->findnodes('./static | ./lut')) { + $property_node->removeChild($attr_node); } for my $function_parent ($property_node->findnodes('./function')) { for my $function_node ($function_parent->childNodes) { @@ -218,11 +218,12 @@ sub set_state_power { my $state_node = $self->{states}{$state}{node}; $power = sprintf( '%.f', $power ); - $self->{states}{$state}{power}{static} = $power; printf( "state %-16s: adjust power %d -> %d µW\n", $state, $self->{states}{$state}{power}{static}, $power ); + $self->{states}{$state}{power}{static} = $power; + my ($static_parent) = $state_node->findnodes('./power'); if (not $static_parent) { $static_parent = XML::LibXML::Element->new('power'); @@ -275,6 +276,62 @@ sub set_transition_property { $static_parent->appendChild($static_node); } +sub set_state_lut { + my ($self, $state, $property, $lut) = @_; + my $state_node = $self->{states}{$state}{node}; + + if (not defined $lut) { + return; + } + + my ($lut_parent) = $state_node->findnodes("./${property}"); + for my $lut_node ( $lut_parent->findnodes('./lut') ) { + $lut_parent->removeChild($lut_node); + } + + my $lut_node = XML::LibXML::Element->new('lut'); + $lut_parent->appendChild($lut_node); + + for my $lut_entry (@{$lut}) { + my $entry_node = XML::LibXML::Element->new('entry'); + my $value_node = XML::LibXML::Text->new($lut_entry->{value}); + for my $param (sort keys %{$lut_entry->{key}}) { + $entry_node->setAttribute($param, $lut_entry->{key}{$param}); + } + $entry_node->appendChild($value_node); + $lut_node->appendChild($entry_node); + } +} + +sub set_transition_lut { + my ($self, $transition_name, $property, $lut) = @_; + + if (not defined $lut) { + return; + } + + my $transition = $self->get_transition_by_name($transition_name); + my $transition_node = $transition->{node}; + + my ($lut_parent) = $transition_node->findnodes("./${property}"); + for my $lut_node ( $lut_parent->findnodes('./lut') ) { + $lut_parent->removeChild($lut_node); + } + + my $lut_node = XML::LibXML::Element->new('lut'); + $lut_parent->appendChild($lut_node); + + for my $lut_entry (@{$lut}) { + my $entry_node = XML::LibXML::Element->new('entry'); + my $value_node = XML::LibXML::Text->new($lut_entry->{value}); + for my $param (sort keys %{$lut_entry->{key}}) { + $entry_node->setAttribute($param, $lut_entry->{key}{$param}); + } + $entry_node->appendChild($value_node); + $lut_node->appendChild($entry_node); + } +} + sub set_state_params { my ( $self, $state, $fun_name, $function, @params ) = @_; my $old_params = 'None'; |