diff options
author | jaseg <git-bigdata-wsl-arch@jaseg.de> | 2020-03-04 17:10:31 +0100 |
---|---|---|
committer | jaseg <git-bigdata-wsl-arch@jaseg.de> | 2020-03-04 17:10:31 +0100 |
commit | d9b26d16c063aec32b70287ff861a1f23642a9f2 (patch) | |
tree | 6259bd8509ea2e442e21c4d68c61098cdf7ae19d | |
parent | 4d80111cad6891cd0e1d5da59e83222d39933e41 (diff) | |
download | master-thesis-d9b26d16c063aec32b70287ff861a1f23642a9f2.tar.gz master-thesis-d9b26d16c063aec32b70287ff861a1f23642a9f2.tar.bz2 master-thesis-d9b26d16c063aec32b70287ff861a1f23642a9f2.zip |
Fix frequency measurement simulation
22 files changed, 1211 insertions, 174 deletions
diff --git a/controller/fw/Makefile b/controller/fw/Makefile index a4b8a66..8dfcb1d 100644 --- a/controller/fw/Makefile +++ b/controller/fw/Makefile @@ -46,17 +46,17 @@ FMEAS_ADC_SAMPLING_RATE ?= 1000 FMEAS_ADC_MAX ?= 4096 FMEAS_FFT_LEN ?= 256 FMEAS_FFT_WINDOW ?= gaussian -FMEAS_FFT_WINDOW_SIGMA ?= 8.0 +FMEAS_FFT_WINDOW_SIGMA ?= 16.0 -CC ?= $(PREFIX)gcc -CXX ?= $(PREFIX)g++ -LD ?= $(PREFIX)gcc -AR ?= $(PREFIX)ar -AS ?= $(PREFIX)as -OBJCOPY ?= $(PREFIX)objcopy -OBJDUMP ?= $(PREFIX)objdump -GDB ?= $(PREFIX)gdb +CC := $(PREFIX)gcc +CXX := $(PREFIX)g++ +LD := $(PREFIX)gcc +AR := $(PREFIX)ar +AS := $(PREFIX)as +OBJCOPY := $(PREFIX)objcopy +OBJDUMP := $(PREFIX)objdump +GDB := $(PREFIX)gdb HOST_CC ?= $(HOST_PREFIX)gcc HOST_CXX ?= $(HOST_PREFIX)g++ @@ -75,9 +75,9 @@ LIBSODIUM_DIR_ABS := $(abspath $(LIBSODIUM_DIR)) TINYAES_DIR_ABS := $(abspath $(TINYAES_DIR)) MUSL_DIR_ABS := $(abspath $(MUSL_DIR)) -COMMON_CFLAGS += -I$(OPENCM3_DIR_ABS)/include -Imspdebug/util -Imspdebug/drivers +COMMON_CFLAGS += -I$(OPENCM3_DIR_ABS)/include -Imspdebug/util -Imspdebug/drivers -Ilevmarq COMMON_CFLAGS += -I$(CMSIS_DIR_ABS)/CMSIS/DSP/Include -I$(CMSIS_DIR_ABS)/CMSIS/Core/Include -COMMON_CFLAGS += -I$(abspath musl_include_shims) -Ilevmarq +CFLAGS += -I$(abspath musl_include_shims) COMMON_CFLAGS += -Os -std=gnu11 -g -DSTM32F4 CFLAGS += -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 @@ -91,7 +91,7 @@ COMMON_CFLAGS += -DFMEAS_FFT_WINDOW_SIGMA=$(FMEAS_FFT_WINDOW_SIGMA) # for musl CFLAGS += -Dhidden= -SIM_CFLAGS += -Isrc +SIM_CFLAGS += -Isrc -lm -DSIMULATION INT_CFLAGS += -Wall -Wextra -Wpedantic -Wshadow -Wimplicit-function-declaration -Wundef INT_CFLAGS += -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes @@ -112,7 +112,7 @@ LDFLAGS += -L$(OPENCM3_DIR_ABS)/lib -l$(OPENCM3_LIB) $(shell $(CC) -print-libg all: $(BUILDDIR)/$(BINARY) -tests: $(BUILDDIR)/tools/freq_meas_test.elf +tests: $(BUILDDIR)/tools/freq_meas_test OBJS := $(addprefix $(BUILDDIR)/,$(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)) @@ -127,7 +127,7 @@ ALL_OBJS += $(BUILDDIR)/generated/fmeas_fft_window.o $(BUILDDIR)/$(BINARY): $(ALL_OBJS) $(LD) -T$(LDSCRIPT) $(COMMON_LDFLAGS) $(LDFLAGS) -o $@ -Wl,-Map=$(BUILDDIR)/src/$*.map $^ -$(BUILDDIR)/tools/freq_meas_test.elf: tools/freq_meas_test.c src/freq_meas.c levmarq/levmarq.c $(BUILDDIR)/generated/fmeas_fft_window.c $(CMSIS_SOURCES) +$(BUILDDIR)/tools/freq_meas_test: tools/freq_meas_test.c src/freq_meas.c levmarq/levmarq.c $(BUILDDIR)/generated/fmeas_fft_window.c $(CMSIS_SOURCES) mkdir -p $(@D) $(HOST_CC) $(COMMON_CFLAGS) $(SIM_CFLAGS) -o $@ $^ @@ -177,6 +177,7 @@ clean: -rm -r $(BUILDDIR)/src -rm -r $(BUILDDIR)/generated -rm $(BUILDDIR)/$(BINARY) + -rm $(BUILDDIR)/tools/freq_meas_test mrproper: clean -rm -r build diff --git a/controller/fw/levmarq/levmarq.c b/controller/fw/levmarq/levmarq.c index bbf00c0..a3a77b5 100644 --- a/controller/fw/levmarq/levmarq.c +++ b/controller/fw/levmarq/levmarq.c @@ -20,6 +20,7 @@ #include <arm_math.h> #include "levmarq.h" +#include "simulation.h" #define TOL 1e-20f /* smallest value allowed in cholesky_decomp() */ @@ -28,18 +29,20 @@ /* set parameters required by levmarq() to default values */ void levmarq_init(LMstat *lmstat) { - lmstat->max_it = 10000; - lmstat->init_lambda = 0.0001f; - lmstat->up_factor = 10.0f; - lmstat->down_factor = 10.0f; - lmstat->target_derr = 1e-12f; + lmstat->max_it = 10000; + lmstat->init_lambda = 0.0001f; + lmstat->up_factor = 10.0f; + lmstat->down_factor = 10.0f; + lmstat->target_derr = 1e-12f; } +#ifndef SIMULATION float sqrtf(float arg) { float out=NAN; arm_sqrt_f32(arg, &out); return out; } +#endif /* perform least-squares minimization using the Levenberg-Marquardt algorithm. The arguments are as follows: @@ -49,140 +52,147 @@ float sqrtf(float arg) { ny number of measurements to be fit y array of measurements dysq array of error in measurements, squared - (set dysq=NULL for unweighted least-squares) + (set dysq=NULL for unweighted least-squares) func function to be fit grad gradient of "func" with respect to the input parameters fdata pointer to any additional data required by the function lmstat pointer to the "status" structure, where minimization parameters - are set and the final status is returned. + are set and the final status is returned. Before calling levmarq, several of the parameters in lmstat must be set. For default values, call levmarq_init(lmstat). - */ + */ int levmarq(int npar, float *par, int ny, float *y, float *dysq, - float (*func)(float *, int, void *), - void (*grad)(float *, float *, int, void *), - void *fdata, LMstat *lmstat) + float (*func)(float *, int, void *), + void (*grad)(float *, float *, int, void *), + void *fdata, LMstat *lmstat) { - int x,i,j,it,nit,ill; - float lambda,up,down,mult,weight,err,newerr,derr,target_derr; - float h[npar][npar],ch[npar][npar]; - float g[npar],d[npar],delta[npar],newpar[npar]; - - nit = lmstat->max_it; - lambda = lmstat->init_lambda; - up = lmstat->up_factor; - down = 1/lmstat->down_factor; - target_derr = lmstat->target_derr; - weight = 1; - derr = newerr = 0; /* to avoid compiler warnings */ - - /* calculate the initial error ("chi-squared") */ - err = error_func(par, ny, y, dysq, func, fdata); - - /* main iteration */ - for (it=0; it<nit; it++) { - - /* calculate the approximation to the Hessian and the "derivative" d */ - for (i=0; i<npar; i++) { - d[i] = 0; - for (j=0; j<=i; j++) - h[i][j] = 0; - } - for (x=0; x<ny; x++) { - if (dysq) weight = 1/dysq[x]; /* for weighted least-squares */ - grad(g, par, x, fdata); - for (i=0; i<npar; i++) { - d[i] += (y[x] - func(par, x, fdata))*g[i]*weight; - for (j=0; j<=i; j++) - h[i][j] += g[i]*g[j]*weight; - } - } - - /* make a step "delta." If the step is rejected, increase - lambda and try again */ - mult = 1 + lambda; - ill = 1; /* ill-conditioned? */ - while (ill && (it<nit)) { - for (i=0; i<npar; i++) - h[i][i] = h[i][i]*mult; - - ill = cholesky_decomp(npar, ch, h); - - if (!ill) { - solve_axb_cholesky(npar, ch, delta, d); - for (i=0; i<npar; i++) - newpar[i] = par[i] + delta[i]; - newerr = error_func(newpar, ny, y, dysq, func, fdata); - derr = newerr - err; - ill = (derr > 0); - } - if (ill) { - mult = (1 + lambda*up)/(1 + lambda); - lambda *= up; - it++; - } + int x,i,j,it,nit,ill; + float lambda,up,down,mult,weight,err,newerr,derr,target_derr; + float h[npar][npar],ch[npar][npar]; + float g[npar],d[npar],delta[npar],newpar[npar]; + + nit = lmstat->max_it; + lambda = lmstat->init_lambda; + up = lmstat->up_factor; + down = 1/lmstat->down_factor; + target_derr = lmstat->target_derr; + weight = 1; + derr = newerr = 0; /* to avoid compiler warnings */ + + /* calculate the initial error ("chi-squared") */ + err = error_func(par, ny, y, dysq, func, fdata); + + /* main iteration */ + for (it=0; it<nit; it++) { + //DEBUG_PRINT("iteration %d", it); + + /* calculate the approximation to the Hessian and the "derivative" d */ + for (i=0; i<npar; i++) { + d[i] = 0; + for (j=0; j<=i; j++) + h[i][j] = 0; + } + + for (x=0; x<ny; x++) { + if (dysq) weight = 1/dysq[x]; /* for weighted least-squares */ + grad(g, par, x, fdata); + for (i=0; i<npar; i++) { + d[i] += (y[x] - func(par, x, fdata))*g[i]*weight; + for (j=0; j<=i; j++) + h[i][j] += g[i]*g[j]*weight; + } + } + + /* make a step "delta." If the step is rejected, increase + lambda and try again */ + mult = 1 + lambda; + ill = 1; /* ill-conditioned? */ + while (ill && (it<nit)) { + for (i=0; i<npar; i++) + h[i][i] = h[i][i]*mult; + + ill = cholesky_decomp(npar, ch, h); + + if (!ill) { + solve_axb_cholesky(npar, ch, delta, d); + for (i=0; i<npar; i++) + newpar[i] = par[i] + delta[i]; + newerr = error_func(newpar, ny, y, dysq, func, fdata); + derr = newerr - err; + ill = (derr > 0); + } + if (ill) { + mult = (1 + lambda*up)/(1 + lambda); + lambda *= up; + it++; + } + } + for (i=0; i<npar; i++) + par[i] = newpar[i]; + err = newerr; + lambda *= down; + + if ((!ill)&&(-derr<target_derr)) break; } - for (i=0; i<npar; i++) - par[i] = newpar[i]; - err = newerr; - lambda *= down; - if ((!ill)&&(-derr<target_derr)) break; - } + lmstat->final_it = it; + lmstat->final_err = err; + lmstat->final_derr = derr; - lmstat->final_it = it; - lmstat->final_err = err; - lmstat->final_derr = derr; + if (it == nit) { + DEBUG_PRINT("did not converge"); + return -1; + } - return (it==nit); + return it; } /* calculate the error function (chi-squared) */ float error_func(float *par, int ny, float *y, float *dysq, - float (*func)(float *, int, void *), void *fdata) + float (*func)(float *, int, void *), void *fdata) { - int x; - float res,e=0; - - for (x=0; x<ny; x++) { - res = func(par, x, fdata) - y[x]; - if (dysq) /* weighted least-squares */ - e += res*res/dysq[x]; - else - e += res*res; - } - return e; + int x; + float res,e=0; + + for (x=0; x<ny; x++) { + res = func(par, x, fdata) - y[x]; + if (dysq) /* weighted least-squares */ + e += res*res/dysq[x]; + else + e += res*res; + } + return e; } /* solve the equation Ax=b for a symmetric positive-definite matrix A, using the Cholesky decomposition A=LL^T. The matrix L is passed in "l". Elements above the diagonal are ignored. -*/ + */ void solve_axb_cholesky(int n, float l[n][n], float x[n], float b[n]) { - int i,j; - float sum; - - /* solve L*y = b for y (where x[] is used to store y) */ - - for (i=0; i<n; i++) { - sum = 0; - for (j=0; j<i; j++) - sum += l[i][j] * x[j]; - x[i] = (b[i] - sum)/l[i][i]; - } - - /* solve L^T*x = y for x (where x[] is used to store both y and x) */ - - for (i=n-1; i>=0; i--) { - sum = 0; - for (j=i+1; j<n; j++) - sum += l[j][i] * x[j]; - x[i] = (x[i] - sum)/l[i][i]; - } + int i,j; + float sum; + + /* solve L*y = b for y (where x[] is used to store y) */ + + for (i=0; i<n; i++) { + sum = 0; + for (j=0; j<i; j++) + sum += l[i][j] * x[j]; + x[i] = (b[i] - sum)/l[i][i]; + } + + /* solve L^T*x = y for x (where x[] is used to store both y and x) */ + + for (i=n-1; i>=0; i--) { + sum = 0; + for (j=i+1; j<n; j++) + sum += l[j][i] * x[j]; + x[i] = (x[i] - sum)/l[i][i]; + } } @@ -190,26 +200,26 @@ void solve_axb_cholesky(int n, float l[n][n], float x[n], float b[n]) its (lower-triangular) Cholesky factor in "l". Elements above the diagonal are neither used nor modified. The same array may be passed as both l and a, in which case the decomposition is performed in place. -*/ + */ int cholesky_decomp(int n, float l[n][n], float a[n][n]) { - int i,j,k; - float sum; - - for (i=0; i<n; i++) { - for (j=0; j<i; j++) { - sum = 0; - for (k=0; k<j; k++) - sum += l[i][k] * l[j][k]; - l[i][j] = (a[i][j] - sum)/l[j][j]; + int i,j,k; + float sum; + + for (i=0; i<n; i++) { + for (j=0; j<i; j++) { + sum = 0; + for (k=0; k<j; k++) + sum += l[i][k] * l[j][k]; + l[i][j] = (a[i][j] - sum)/l[j][j]; + } + + sum = 0; + for (k=0; k<i; k++) + sum += l[i][k] * l[i][k]; + sum = a[i][i] - sum; + if (sum<TOL) return 1; /* not positive-definite */ + l[i][i] = sqrtf(sum); } - - sum = 0; - for (k=0; k<i; k++) - sum += l[i][k] * l[i][k]; - sum = a[i][i] - sum; - if (sum<TOL) return 1; /* not positive-definite */ - l[i][i] = sqrtf(sum); - } - return 0; + return 0; } diff --git a/controller/fw/src/freq_meas.c b/controller/fw/src/freq_meas.c index 627af34..ba7801e 100644 --- a/controller/fw/src/freq_meas.c +++ b/controller/fw/src/freq_meas.c @@ -7,6 +7,7 @@ #include "freq_meas.h" #include "sr_global.h" +#include "simulation.h" /* FTT window lookup table defined in generated/fmeas_fft_window.c */ @@ -29,17 +30,33 @@ extern arm_status arm_rfft_4096_fast_init_f32(arm_rfft_fast_instance_f32 * S); void func_gauss_grad(float *out, float *params, int x, void *userdata); float func_gauss(float *params, int x, void *userdata); -int adc_buf_measure_freq(uint16_t adc_buf[FMEAS_FFT_LEN], float *out) { +int adc_buf_measure_freq(int16_t adc_buf[FMEAS_FFT_LEN], float *out) { int rc; float in_buf[FMEAS_FFT_LEN]; float out_buf[FMEAS_FFT_LEN]; + /* + DEBUG_PRINTN(" [emulated adc buf] "); + for (size_t i=0; i<FMEAS_FFT_LEN; i++) + DEBUG_PRINTN("%5d, ", adc_buf[i]); + DEBUG_PRINTN("\n"); + */ + //DEBUG_PRINT("Applying window function"); for (size_t i=0; i<FMEAS_FFT_LEN; i++) in_buf[i] = (float)adc_buf[i] / (float)FMEAS_ADC_MAX * fmeas_fft_window_table[i]; + //DEBUG_PRINT("Running FFT"); arm_rfft_fast_instance_f32 fft_inst; - if ((rc = arm_rfft_init_name(FMEAS_FFT_LEN)(&fft_inst)) != ARM_MATH_SUCCESS) + if ((rc = arm_rfft_init_name(FMEAS_FFT_LEN)(&fft_inst)) != ARM_MATH_SUCCESS) { + *out = NAN; return rc; + } + /* + DEBUG_PRINTN(" [input] "); + for (size_t i=0; i<FMEAS_FFT_LEN; i++) + DEBUG_PRINTN("%010f, ", in_buf[i]); + DEBUG_PRINTN("\n"); + */ arm_rfft_fast_f32(&fft_inst, in_buf, out_buf, 0); #define FMEAS_FFT_WINDOW_MIN_F_HZ 30.0f @@ -49,10 +66,24 @@ int adc_buf_measure_freq(uint16_t adc_buf[FMEAS_FFT_LEN], float *out) { const size_t last_bin = (int)(FMEAS_FFT_WINDOW_MAX_F_HZ / binsize_hz + 0.5f); const size_t nbins = last_bin - first_bin + 1; + DEBUG_PRINT("binsize_hz=%f first_bin=%zd last_bin=%zd nbins=%zd", binsize_hz, first_bin, last_bin, nbins); + DEBUG_PRINTN(" [bins real] "); + for (size_t i=0; i<FMEAS_FFT_LEN/2; i+=2) + DEBUG_PRINTN("%010f, ", out_buf[i]); + DEBUG_PRINTN("\n [bins imag] "); + for (size_t i=1; i<FMEAS_FFT_LEN/2; i+=2) + DEBUG_PRINTN("%010f, ", out_buf[i]); + DEBUG_PRINT("\n"); + + DEBUG_PRINT("Repacking FFT results"); /* Copy real values of target data to front of output buffer */ - for (size_t i=0; i<nbins; i++) - out_buf[i] = out_buf[2 * (first_bin + i)]; + for (size_t i=0; i<nbins; i++) { + float real = out_buf[2 * (first_bin + i)]; + float imag = out_buf[2 * (first_bin + i) + 1]; + out_buf[i] = sqrtf(real*real + imag*imag); + } + DEBUG_PRINT("Running Levenberg-Marquardt"); LMstat lmstat; levmarq_init(&lmstat); @@ -68,27 +99,37 @@ int adc_buf_measure_freq(uint16_t adc_buf[FMEAS_FFT_LEN], float *out) { float par[3] = { a_max, i_max, 1.0f }; + DEBUG_PRINT(" par_pre={%010f, %010f, %010f}", par[0], par[1], par[2]); - if (levmarq(3, par, nbins, out_buf, NULL, func_gauss, func_gauss_grad, NULL, &lmstat)) + if (levmarq(3, par, nbins, out_buf, NULL, func_gauss, func_gauss_grad, NULL, &lmstat) < 0) { + *out = NAN; return -1; + } - *out = (par[1] + first_bin) * binsize_hz; + DEBUG_PRINT(" par_post={%010f, %010f, %010f}", par[0], par[1], par[2]); + DEBUG_PRINT("done."); + *out = (par[1] + first_bin) * binsize_hz; return 0; } float func_gauss(float *params, int x, void *userdata) { UNUSED(userdata); - float a = params[0]; - float mu = params[1]; - float sigma = params[2]; - return a*expf(-powf((x-mu), 2.0f/(2.0f*(sigma*sigma)))); + float a = params[0], b = params[1], c = params[2]; + float n = x-b; + return a*expf(-n*n / (2.0f* c*c)); } void func_gauss_grad(float *out, float *params, int x, void *userdata) { UNUSED(userdata); - float a = params[0]; - float mu = params[1]; - float sigma = params[2]; - *out = -(x-mu) / ( sigma*sigma*sigma * 2.5066282746310002f) * a*expf(-powf((x-mu), 2.0f/(2.0f*(sigma*sigma)))); + float a = params[0], b = params[1], c = params[2]; + float n = x-b; + float e = expf(-n*n / (2.0f * c*c)); + + /* d/da */ + out[0] = e; + /* d/db */ + out[1] = a*n/(c*c) * e; + /* d/dc */ + out[2] = a*n*n/(c*c*c) * e; } diff --git a/controller/fw/src/freq_meas.h b/controller/fw/src/freq_meas.h index 1c083f8..4786c0e 100644 --- a/controller/fw/src/freq_meas.h +++ b/controller/fw/src/freq_meas.h @@ -2,6 +2,6 @@ #ifndef __FREQ_MEAS_H__ #define __FREQ_MEAS_H__ -int adc_buf_measure_freq(uint16_t adc_buf[FMEAS_FFT_LEN], float *out); +int adc_buf_measure_freq(int16_t adc_buf[FMEAS_FFT_LEN], float *out); #endif /* __FREQ_MEAS_H__ */ diff --git a/controller/fw/src/simulation.h b/controller/fw/src/simulation.h new file mode 100644 index 0000000..e813de7 --- /dev/null +++ b/controller/fw/src/simulation.h @@ -0,0 +1,14 @@ +#ifndef __SIMULATION_H__ +#define __SIMULATION_H__ + +#ifdef SIMULATION +#include <stdio.h> +#define DEBUG_PRINTN(...) fprintf(stderr, __VA_ARGS__) +#define DEBUG_PRINTNF(fmt, ...) DEBUG_PRINTN("%s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__) +#define DEBUG_PRINT(fmt, ...) DEBUG_PRINTNF(fmt "\n", ##__VA_ARGS__) +#else +#define DEBUG_PRINT(...) ((void)0) +#define DEBUG_PRINTN(...) ((void)0) +#endif + +#endif /* __SIMULATION_H__ */ diff --git a/controller/fw/tools/freq_meas_test.c b/controller/fw/tools/freq_meas_test.c index 01b4963..df3e39d 100644 --- a/controller/fw/tools/freq_meas_test.c +++ b/controller/fw/tools/freq_meas_test.c @@ -1,4 +1,6 @@ +#include <stdint.h> +#include <math.h> #include <unistd.h> #include <stdio.h> #include <string.h> @@ -13,7 +15,7 @@ void print_usage(void); void print_usage() { - fprintf(stderr, "Usage: freq_meas_test [test_data.bin]"); + fprintf(stderr, "Usage: freq_meas_test [test_data.bin]\n"); } int main(int argc, char **argv) { @@ -46,6 +48,7 @@ int main(int argc, char **argv) { return 2; } + fprintf(stderr, "Reading %zd samples test data...", st.st_size/sizeof(float)); size_t nread = 0; while (nread < st.st_size) { ssize_t rc = read(fd, buf, st.st_size - nread); @@ -54,41 +57,48 @@ int main(int argc, char **argv) { continue; if (rc < 0) { - fprintf(stderr, "Error reading test data: %s\n", strerror(errno)); + fprintf(stderr, "\nError reading test data: %s\n", strerror(errno)); return 2; } if (rc == 0) { - fprintf(stderr, "Error reading test data: Unexpected end of file\n"); + fprintf(stderr, "\nError reading test data: Unexpected end of file\n"); return 2; } nread += rc; } + fprintf(stderr, " done.\n"); size_t n_samples = st.st_size / sizeof(float); float *buf_f = (float *)buf; - uint16_t *sim_adc_buf = calloc(sizeof(uint16_t), n_samples); + int16_t *sim_adc_buf = calloc(sizeof(int16_t), n_samples); if (!sim_adc_buf) { fprintf(stderr, "Error allocating memory\n"); return 2; } + fprintf(stderr, "Converting and truncating test data..."); for (size_t i=0; i<n_samples; i++) - sim_adc_buf[i] = 2048 + buf_f[i] * 2047; + /* Note on scaling: We can't simply scale by 0x8000 (1/2 full range) here. Our test data is nominally 1Vp-p but + * certain tests such as the interharmonics one can have some samples exceeding that range. */ + sim_adc_buf[i] = buf_f[i] * (0x4000-1); + fprintf(stderr, " done.\n"); - for (size_t i=0; i<n_samples; i+=FMEAS_FFT_LEN) { + fprintf(stderr, "Starting simulation.\n"); - float out; - int rc = adc_buf_measure_freq(sim_adc_buf + i, &out); - if (rc) { - fprintf(stderr, "Simulation error in iteration %zd at position %zd: %d\n", i/FMEAS_FFT_LEN, i, rc); - return 3; - } + size_t iterations = (n_samples-FMEAS_FFT_LEN)/(FMEAS_FFT_LEN/2); + for (size_t i=0; i<iterations; i++) { - printf("%09zd %015f\n", i, out); - } + fprintf(stderr, "Iteration %zd/%zd\n", i, iterations); + float res = NAN; + int rc = adc_buf_measure_freq(sim_adc_buf + i*(FMEAS_FFT_LEN/2), &res); + if (rc) + printf("ERROR: Simulation error in iteration %zd at position %zd: %d\n", i, i*(FMEAS_FFT_LEN/2), rc); + printf("%09zd %12f\n", i, res); + } + return 0; } diff --git a/controller/fw/tools/freq_meas_test_runner.py b/controller/fw/tools/freq_meas_test_runner.py new file mode 100644 index 0000000..779922a --- /dev/null +++ b/controller/fw/tools/freq_meas_test_runner.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +import os +from os import path +import subprocess +import json + +import numpy as np +np.set_printoptions(linewidth=240) + + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument(metavar='test_data_directory', dest='dir', help='Directory with test data .bin files') + default_binary = path.abspath(path.join(path.dirname(__file__), '../build/tools/freq_meas_test')) + parser.add_argument(metavar='test_binary', dest='binary', nargs='?', default=default_binary) + parser.add_argument('-d', '--dump', help='Write raw measurements to JSON file') + args = parser.parse_args() + + bin_files = [ path.join(args.dir, d) for d in os.listdir(args.dir) if d.lower().endswith('.bin') ] + + savedata = {} + for p in bin_files: + output = subprocess.check_output([args.binary, p], stderr=subprocess.DEVNULL) + measurements = np.array([ float(value) for _offset, value in [ line.split() for line in output.splitlines() ] ]) + savedata[p] = list(measurements) + + # Cut off first and last sample for mean and RMS calculations as these show boundary effects. + measurements = measurements[1:-1] + mean = np.mean(measurements) + rms = np.sqrt(np.mean(np.square(measurements - mean))) + + print(f'{path.basename(p):<60}: mean={mean:<8.4f}Hz rms={rms*1000:.3f}mHz') + + if args.dump: + with open(args.dump, 'w') as f: + json.dump(savedata, f) + diff --git a/lab-windows/Phase Measurement Prototype.ipynb b/lab-windows/Phase Measurement Prototype.ipynb new file mode 100644 index 0000000..11f6226 --- /dev/null +++ b/lab-windows/Phase Measurement Prototype.ipynb @@ -0,0 +1,396 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "import struct\n", + "\n", + "import numpy as np\n", + "from scipy import signal, optimize\n", + "from matplotlib import pyplot as plt\n", + "\n", + "import rocof_test_data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib widget" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "fs = 1000 # Hz\n", + "ff = 50 # Hz\n", + "duration = 60 # seconds\n", + "# test_data = rocof_test_data.sample_waveform(rocof_test_data.test_close_interharmonics_and_flicker(),\n", + "# duration=20,\n", + "# sampling_rate=fs,\n", + "# frequency=ff)[0]\n", + "# test_data = rocof_test_data.sample_waveform(rocof_test_data.gen_noise(fmin=10, amplitude=1),\n", + "# duration=20,\n", + "# sampling_rate=fs,\n", + "# frequency=ff)[0]\n", + "\n", + "\n", + "#gen = rocof_test_data.gen_noise(fmin=10, amplitude=1)\n", + "# gen = rocof_test_data.gen_noise(fmin=60, amplitude=0.2)\n", + "# gen = rocof_test_data.test_harmonics()\n", + "# gen = rocof_test_data.gen_interharmonic(*rocof_test_data.test_interharmonics)\n", + "# gen = rocof_test_data.test_amplitude_steps()\n", + "# gen = rocof_test_data.test_amplitude_and_phase_steps()\n", + "test_data = []\n", + "test_labels = [ fun.__name__.replace('test_', '') for fun in rocof_test_data.all_tests ]\n", + "for gen in rocof_test_data.all_tests:\n", + " test_data.append(rocof_test_data.sample_waveform(gen(),\n", + " duration=duration,\n", + " sampling_rate=fs,\n", + " frequency=ff)[0])\n", + "# d = 10 # seconds\n", + "# test_data = np.sin(2*np.pi * ff * np.linspace(0, d, int(d*fs)))" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "spr_fmt = f'{fs}Hz' if fs<1000 else f'{fs/1e3:f}'.rstrip('.0') + 'kHz'\n", + "for label, data in zip(test_labels, test_data):\n", + " with open(f'rocof_test_data/rocof_test_{label}_{spr_fmt}.bin', 'wb') as f:\n", + " for sample in data:\n", + " f.write(struct.pack('<f', sample))" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [], + "source": [ + "analysis_periods = 10\n", + "window_len = 256 # fs * analysis_periods/ff\n", + "nfft_factor = 1\n", + "sigma = window_len/8 # samples\n", + "quantization_bits = 14\n", + "\n", + "ffts = []\n", + "for item in test_data:\n", + " f, t, Zxx = signal.stft((item * (2**(quantization_bits-1) - 1)).round().astype(np.int16).astype(float),\n", + " fs = fs,\n", + " window=('gaussian', sigma),\n", + " nperseg = window_len,\n", + " nfft = window_len * nfft_factor)\n", + " #boundary = 'zeros')\n", + " ffts.append((f, t, Zxx))" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(129, 470)" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Zxx.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.90625" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1000/256" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "<ipython-input-61-530955947ba4>:1: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n", + " fig, ax = plt.subplots(len(test_data), figsize=(8, 20), sharex=True)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "30b7e529e3f94c1b8241c6b6760b7e69", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(len(test_data), figsize=(8, 20), sharex=True)\n", + "fig.tight_layout(pad=2, h_pad=0.1)\n", + "\n", + "for fft, ax, label in zip(test_data, ax.flatten(), test_labels):\n", + " ax.plot((item * (2**(quantization_bits-1) - 1)).round())\n", + " \n", + " ax.set_title(label, pad=-20, color='white', bbox=dict(boxstyle=\"square\", ec=(0,0,0,0), fc=(0,0,0,0.8)))\n", + " ax.grid()\n", + " ax.set_ylabel('f [Hz]')\n", + "ax.set_xlabel('simulation time t [s]')\n", + "ax.set_xlim([5000, 5200])\n", + "None" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "<ipython-input-76-31c82486a777>:1: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n", + " fig, ax = plt.subplots(len(test_data), figsize=(8, 20), sharex=True)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9e0976ade81c4990a10fd1182f0f20d5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(len(test_data), figsize=(8, 20), sharex=True)\n", + "fig.tight_layout(pad=2, h_pad=0.1)\n", + "\n", + "for fft, ax, label in zip(ffts, ax.flatten(), test_labels):\n", + " f, t, Zxx = fft\n", + " ax.pcolormesh(t[1:], f[:250], np.abs(Zxx[:250,1:]))\n", + " ax.set_title(label, pad=-20, color='white')\n", + " ax.grid()\n", + " ax.set_ylabel('f [Hz]')\n", + " ax.set_ylim([30, 75]) # Hz\n", + "ax.set_xlabel('simulation time t [s]')\n", + "None" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0. , 3.90625, 7.8125 , 11.71875, 15.625 , 19.53125,\n", + " 23.4375 , 27.34375, 31.25 , 35.15625, 39.0625 , 42.96875,\n", + " 46.875 , 50.78125, 54.6875 , 58.59375, 62.5 , 66.40625,\n", + " 70.3125 , 74.21875, 78.125 , 82.03125, 85.9375 , 89.84375,\n", + " 93.75 , 97.65625, 101.5625 , 105.46875, 109.375 , 113.28125,\n", + " 117.1875 , 121.09375, 125. , 128.90625, 132.8125 , 136.71875,\n", + " 140.625 , 144.53125, 148.4375 , 152.34375, 156.25 , 160.15625,\n", + " 164.0625 , 167.96875, 171.875 , 175.78125, 179.6875 , 183.59375,\n", + " 187.5 , 191.40625, 195.3125 , 199.21875, 203.125 , 207.03125,\n", + " 210.9375 , 214.84375, 218.75 , 222.65625, 226.5625 , 230.46875,\n", + " 234.375 , 238.28125, 242.1875 , 246.09375, 250. , 253.90625,\n", + " 257.8125 , 261.71875, 265.625 , 269.53125, 273.4375 , 277.34375,\n", + " 281.25 , 285.15625, 289.0625 , 292.96875, 296.875 , 300.78125,\n", + " 304.6875 , 308.59375, 312.5 , 316.40625, 320.3125 , 324.21875,\n", + " 328.125 , 332.03125, 335.9375 , 339.84375, 343.75 , 347.65625,\n", + " 351.5625 , 355.46875, 359.375 , 363.28125, 367.1875 , 371.09375,\n", + " 375. , 378.90625, 382.8125 , 386.71875, 390.625 , 394.53125,\n", + " 398.4375 , 402.34375, 406.25 , 410.15625, 414.0625 , 417.96875,\n", + " 421.875 , 425.78125, 429.6875 , 433.59375, 437.5 , 441.40625,\n", + " 445.3125 , 449.21875, 453.125 , 457.03125, 460.9375 , 464.84375,\n", + " 468.75 , 472.65625, 476.5625 , 480.46875, 484.375 , 488.28125,\n", + " 492.1875 , 496.09375, 500. ])" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "f" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "<ipython-input-63-888d30b0f7d6>:1: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n", + " fig, axs = plt.subplots(len(test_data), figsize=(8, 20), sharex=True)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "cef58f5753084c54a648418e134775d8", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axs = plt.subplots(len(test_data), figsize=(8, 20), sharex=True)\n", + "fig.tight_layout(pad=2.2, h_pad=0, w_pad=1)\n", + "\n", + "for fft, ax, label in zip(ffts, axs.flatten(), test_labels):\n", + " f, f_t, Zxx = fft\n", + " \n", + " n_f, n_t = Zxx.shape\n", + " # start, stop = 180, 220\n", + " # start, stop = 90, 110\n", + " # start, stop = 15, 35\n", + " # bounds_f = slice(start // 4 * nfft_factor, stop // 4 * nfft_factor)\n", + " f_min, f_max = 30, 70 # Hz\n", + " bounds_f = slice(np.argmax(f > f_min), np.argmin(f < f_max))\n", + " \n", + "\n", + " f_mean = np.zeros(Zxx.shape[1])\n", + " for t in range(1, Zxx.shape[1] - 1):\n", + " frame_f = f[bounds_f]\n", + " frame_step = frame_f[1] - frame_f[0]\n", + " time_step = f_t[1] - f_t[0]\n", + " #if t == 10:\n", + " # axs[-1].plot(frame_f, frame_Z)\n", + " frame_Z = np.abs(Zxx[bounds_f, t])\n", + " # frame_f = f[180:220]\n", + " # frame_Z = np.abs(Zxx[180:220, 40])\n", + " # frame_f = f[15:35]\n", + " # frame_Z = np.abs(Zxx[15:35, 40])\n", + " # plt.plot(frame_f, frame_Z)\n", + "\n", + " # peak_f = frame_f[np.argmax(frame)]\n", + " # plt.axvline(peak_f, color='red')\n", + "\n", + "# def gauss(x, *p):\n", + "# A, mu, sigma, o = p\n", + "# return A*np.exp(-(x-mu)**2/(2.*sigma**2)) + o\n", + " \n", + " def gauss(x, *p):\n", + " A, mu, sigma = p\n", + " return A*np.exp(-(x-mu)**2/(2.*sigma**2))\n", + " \n", + " f_start = frame_f[np.argmax(frame_Z)]\n", + " A_start = np.max(frame_Z)\n", + " p0 = [A_start, f_start, 1.]\n", + " try:\n", + " coeff, var = optimize.curve_fit(gauss, frame_f, frame_Z, p0=p0)\n", + " # plt.plot(frame_f, gauss(frame_f, *coeff))\n", + " #print(coeff)\n", + " A, mu, sigma, *_ = coeff\n", + " f_mean[t] = mu\n", + " except RuntimeError:\n", + " f_mean[t] = np.nan\n", + " ax.plot(f_t[1:-1], f_mean[1:-1])\n", + " \n", + "# b, a = signal.butter(3,\n", + "# 1/5, # Hz\n", + "# btype='lowpass',\n", + "# fs=1/time_step)\n", + "# filtered = signal.lfilter(b, a, f_mean[1:-1], axis=0)\n", + "# ax.plot(f_t[1:-1], filtered)\n", + " \n", + " ax.set_title(label, pad=-20)\n", + " ax.set_ylabel('f [Hz]')\n", + " ax.grid()\n", + " if not label in ['off_frequency', 'sweep_phase_steps']:\n", + " ax.set_ylim([49.90, 50.10])\n", + " var = np.var(f_mean[1:-1])\n", + " ax.text(0.5, 0.1, f'σ²={var * 1e3:.3g} mHz²', transform=ax.transAxes, ha='center')\n", + " ax.text(0.5, 0.25, f'σ={np.sqrt(var) * 1e3:.3g} mHz', transform=ax.transAxes, ha='center')\n", + "# ax.text(0.5, 0.2, f'filt. σ²={np.var(filtered) * 1e3:.3g} mHz', transform=ax.transAxes, ha='center')\n", + " else:\n", + " f_min, f_max = min(f_mean[1:-1]), max(f_mean[1:-1])\n", + " delta = f_max - f_min\n", + " ax.set_ylim(f_min - delta * 0.1, f_max + delta * 0.3)\n", + " \n", + "ax.set_xlabel('simulation time t [s]')\n", + "None" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "labenv", + "language": "python", + "name": "labenv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/lab-windows/gauss_derivations.ipynb b/lab-windows/gauss_derivations.ipynb new file mode 100644 index 0000000..6e0dcd8 --- /dev/null +++ b/lab-windows/gauss_derivations.ipynb @@ -0,0 +1,184 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "\\[\\tag{${\\it \\%o}_{2}$}f\\left(a , \\mu , \\sigma , x\\right):=a\\,\\exp \\left(\\frac{-\\left(x-\\mu\\right)^2}{2\\,\\sigma^2}\\right)\\]" + ], + "text/plain": [ + " 2\n", + " - (x - mu)\n", + "(%o2) f(a, mu, sigma, x) := a exp(-----------)\n", + " 2\n", + " 2 sigma" + ], + "text/x-maxima": [ + "f(a,mu,sigma,x):=a*exp((-(x-mu)^2)/(2*sigma^2))" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "f(a, mu, sigma, x) := a*exp(-(x-mu)^2/(2*sigma^2));" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "\\[\\tag{${\\it \\%o}_{11}$}-\\frac{a\\,\\left(x-\\mu\\right)\\,e^ {- \\frac{\\left(x-\\mu\\right)^2}{2\\,\\sigma^2} }}{\\sigma^2}\\]" + ], + "text/plain": [ + " 2\n", + " (x - mu)\n", + " - ---------\n", + " 2\n", + " 2 sigma\n", + " a (x - mu) %e\n", + "(%o11) - ------------------------\n", + " 2\n", + " sigma" + ], + "text/x-maxima": [ + "-(a*(x-mu)*%e^-((x-mu)^2/(2*sigma^2)))/sigma^2" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diff(f(a, mu, sigma, x), x);" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "\\[\\tag{${\\it \\%o}_{12}$}e^ {- \\frac{\\left(x-\\mu\\right)^2}{2\\,\\sigma^2} }\\]" + ], + "text/plain": [ + " 2\n", + " (x - mu)\n", + " - ---------\n", + " 2\n", + " 2 sigma\n", + "(%o12) %e" + ], + "text/x-maxima": [ + "%e^-((x-mu)^2/(2*sigma^2))" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diff(f(a, mu, sigma, x), a);" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "\\[\\tag{${\\it \\%o}_{13}$}\\frac{a\\,\\left(x-\\mu\\right)\\,e^ {- \\frac{\\left(x-\\mu\\right)^2}{2\\,\\sigma^2} }}{\\sigma^2}\\]" + ], + "text/plain": [ + " 2\n", + " (x - mu)\n", + " - ---------\n", + " 2\n", + " 2 sigma\n", + " a (x - mu) %e\n", + "(%o13) ------------------------\n", + " 2\n", + " sigma" + ], + "text/x-maxima": [ + "(a*(x-mu)*%e^-((x-mu)^2/(2*sigma^2)))/sigma^2" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diff(f(a, mu, sigma, x), mu);" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "\\[\\tag{${\\it \\%o}_{14}$}\\frac{a\\,\\left(x-\\mu\\right)^2\\,e^ {- \\frac{\\left(x-\\mu\\right)^2}{2\\,\\sigma^2} }}{\\sigma^3}\\]" + ], + "text/plain": [ + " 2\n", + " (x - mu)\n", + " - ---------\n", + " 2\n", + " 2 2 sigma\n", + " a (x - mu) %e\n", + "(%o14) -------------------------\n", + " 3\n", + " sigma" + ], + "text/x-maxima": [ + "(a*(x-mu)^2*%e^-((x-mu)^2/(2*sigma^2)))/sigma^3" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diff(f(a, mu, sigma, x), sigma);" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Maxima", + "language": "maxima", + "name": "maxima" + }, + "language_info": { + "codemirror_mode": "maxima", + "file_extension": ".mac", + "mimetype": "text/x-maxima", + "name": "maxima", + "pygments_lexer": "maxima", + "version": "5.43.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/lab-windows/impl_test_out.json b/lab-windows/impl_test_out.json new file mode 100644 index 0000000..c25eba8 --- /dev/null +++ b/lab-windows/impl_test_out.json @@ -0,0 +1 @@ +{"../../lab-windows/rocof_test_data/rocof_test_amplitude_and_phase_steps_1kHz.bin": [50.000801, 50.000832, 50.000851, 50.000809, 50.000824, 50.000805, 50.00082, 50.000874, 50.00087, 50.000778, 49.939713, 50.000847, 50.000835, 50.51796, 50.000908, 49.937092, 50.000824, 50.000847, 50.000858, 50.000748, 50.000748, 50.000816, 50.000854, 50.000793, 50.000782, 50.000832, 50.000813, 50.000778, 50.000778, 50.000824, 50.000771, 50.000813, 50.000824, 50.000759, 50.000885, 50.000786, 50.000866, 50.000866, 50.000809, 50.059319, 50.000862, 50.000778, 50.000805, 50.000843, 50.000885, 50.000843, 50.000839, 50.000759, 50.000839, 50.000854, 50.000729, 50.000809, 50.000763, 50.003353, 50.000763, 50.000862, 50.000858, 50.000885, 50.000832, 50.000809, 50.000862, 50.000782, 50.000778, 50.000736, 50.000786, 50.00087, 50.115303, 50.00087, 50.00087, 50.000847, 50.000832, 50.000893, 50.00082, 50.00087, 50.000816, 50.000824, 50.000847, 50.000771, 50.000847, 50.000809, 50.000786, 50.00087, 50.000839, 50.000778, 50.000862, 50.000839, 50.729588, 50.000786, 50.000832, 50.000854, 50.00087, 50.000847, 50.000816, 50.000832, 50.000832, 50.000851, 50.000809, 50.000816, 50.000832, 50.000854, 50.000965, 50.000839, 50.00087, 50.000854, 50.000793, 50.000854, 50.000816, 50.000847, 50.000824, 50.000813, 50.000839, 50.000801, 50.000816, 50.000851, 50.000862, 50.000835, 50.000885, 50.000828, 50.000839, 50.000816, 50.000816, 50.000847, 50.000854, 50.00087, 50.000877, 50.000824, 50.000839, 50.000885, 50.000797, 50.00087, 50.000893, 50.000885, 50.000839, 50.000816, 50.000877, 50.000832, 50.01186, 50.000877, 50.002335, 50.000832, 50.000851, 50.0014, 49.521694, 50.000874, 50.000839, 50.000809, 50.000828, 50.000771, 50.000816, 50.000786, 50.000832, 50.000874, 50.000843, 50.000847, 50.000862, 50.000809, 50.000809, 50.000828, 50.000778, 50.000862, 50.000862, 50.00082, 50.000755, 50.000839, 50.000832, 50.00087, 50.000347, 50.000839, 50.135723, 50.000854, 50.000835, 50.000809, 50.000832, 50.000801, 50.000885, 50.00087, 49.998692, 50.000778, 50.000828, 50.000847, 50.000816, 50.00087, 50.000832, 50.000893, 50.000767, 50.000832, 50.000828, 50.000488, 50.000816, 50.000938, 50.000763, 50.000843, 50.000854, 50.000809, 50.000847, 50.000771, 50.000839, 50.000854, 50.000778, 50.000908, 50.00079, 50.000839, 50.000896, 50.000797, 50.000828, 50.000751, 50.000893, 50.000824, 50.000839, 50.000874, 50.00074, 50.000862, 50.000839, 50.000786, 50.000881, 50.000786, 50.000832, 50.000793, 50.000824, 50.000854, 50.000843, 50.000858, 50.188171, 50.00082, 50.000854, 50.000801, 50.000816, 50.00082, 50.000816, 50.000824, 50.000881, 50.000801, 50.000839, 50.000839, 50.000786, 50.000851, 50.00082, 50.000828, 50.000824, 50.000877, 50.000832, 50.000824, 50.000908, 50.000854, 50.000847, 50.000793, 50.000854, 50.000778, 50.000874, 50.000809, 50.000839, 50.000813, 50.000801, 50.000839, 50.000751, 50.000816, 50.000839, 50.000851, 50.000858, 50.000813, 50.000912, 50.000748, 49.865589, 50.000816, 50.000832, 50.000832, 50.000854, 50.000908, 50.000854, 50.000786, 50.000839, 50.00079, 50.000755, 50.000877, 50.000824, 50.000755, 50.000793, 50.000835, 50.000877, 50.000854, 50.000816, 50.000893, 50.000862, 50.000793, 50.000755, 50.000816, 50.0009, 50.000889, 50.000763, 50.108665, 50.000854, 50.000809, 50.201954, 50.000839, 50.000801, 50.000832, 50.000839, 50.000835, 50.00082, 50.257782, 50.000877, 50.000843, 50.000847, 50.00082, 50.000839, 50.000877, 50.000809, 50.000862, 50.000862, 50.000809, 50.000786, 50.000835, 50.000801, 50.000843, 50.000832, 50.000885, 50.000793, 50.000847, 50.710655, 50.000893, 50.000893, 50.000832, 50.00087, 50.00079, 50.000809, 50.000771, 50.000778, 50.000706, 50.000847, 50.000824, 50.141777, 50.000832, 50.000851, 50.000824, 50.000847, 50.000854, 50.000832, 50.000851, 50.000786, 50.000828, 50.000862, 50.00087, 50.000847, 50.000793, 50.000862, 50.000874, 50.000832, 50.000854, 50.000839, 50.000839, 50.000862, 50.000847, 50.000786, 50.000839, 50.000889, 50.000893, 50.000847, 50.000801, 50.000847, 50.040829, 50.000843, 50.00087, 50.000847, 50.00087, 50.000839, 50.000877, 50.000874, 50.000729, 50.000877, 49.83836, 50.000866, 50.000771, 50.000885, 50.000847, 50.000965, 50.000874, 50.0009, 50.000843, 50.00087, 50.000813, 50.000736, 50.000877, 50.000824, 50.000801, 50.000809, 50.00079, 50.000824, 50.000824, 49.987125, 50.000793, 50.000893, 50.000896, 50.000774, 50.000801, 50.000847, 50.000801, 50.000908, 50.000805, 50.000877, 50.000832, 50.000854, 50.000847, 50.000786, 50.000786, 50.000778, 50.000835, 50.514965, 50.000835, 50.000828, 50.000828, 50.000759, 50.000832, 50.000854, 50.000786, 50.000839, 50.00082, 50.000793, 49.630627, 50.000832, 50.000816, 50.000824, 50.000839, 50.000755, 50.000881, 50.000862, 50.000832, 50.000908, 50.000763, 50.00087, 50.000778, 50.000793, 50.00087, 50.0009, 50.000816, 50.000866, 50.000854, 50.000797, 50.00082, 50.00087, 49.999416, 50.000889, 50.000847, 50.000832, 50.000881, 50.000835, 50.000847, 50.000824, 50.00087, 49.948402, 50.000862, 50.028568, 50.000885, 50.000824, 50.000854, 50.000763, 50.000851, 50.000824, 50.000916, 50.000862, 50.0009, 50.000828, 50.000854, 50.000778, 50.000793, 50.000862, 50.000935], "../../lab-windows/rocof_test_data/rocof_test_amplitude_steps_1kHz.bin": [50.000801, 50.000832, 50.000851, 50.000809, 50.000824, 50.016724, 50.000809, 50.000885, 50.000824, 50.000832, 50.000862, 50.000866, 50.000813, 50.000816, 50.000809, 50.000805, 50.000854, 50.000824, 50.000862, 50.000885, 50.000832, 50.000854, 50.000824, 50.000839, 50.000809, 50.000832, 50.000854, 50.000824, 50.155529, 50.000847, 50.000824, 50.000854, 50.000801, 50.000816, 50.000774, 50.000824, 50.00082, 50.000862, 50.000809, 50.000854, 50.000816, 50.000858, 50.000793, 50.000847, 50.000763, 50.000793, 50.000847, 50.000824, 50.000793, 50.00079, 50.000843, 50.000763, 50.000813, 50.000767, 50.000862, 50.000854, 50.000782, 50.00087, 50.00082, 50.000839, 50.000893, 50.000854, 50.000839, 50.000847, 50.000858, 50.000851, 50.000816, 50.000824, 50.000805, 50.000854, 50.000854, 50.000854, 50.000832, 50.000843, 50.000839, 50.000816, 50.000832, 50.000774, 50.00087, 50.000843, 50.000793, 50.000862, 50.000851, 50.000839, 50.00087, 50.00087, 50.000877, 50.000847, 50.0009, 50.000877, 50.000847, 50.000847, 50.000923, 49.99987, 50.000835, 50.000893, 50.000847, 50.00082, 50.000832, 50.000843, 50.000809, 50.000908, 50.000858, 50.000755, 50.000809, 50.000866, 50.000763, 50.000885, 50.000843, 50.000793, 50.000866, 50.000885, 50.000786, 50.000843, 50.000877, 50.000854, 50.000854, 50.000706, 50.00087, 50.000828, 50.00082, 50.000771, 50.000832, 50.000893, 50.000874, 50.000755, 50.000824, 50.000862, 50.000858, 50.000832, 50.000786, 50.000847, 50.00087, 50.000824, 50.000889, 50.000828, 50.000801, 50.000763, 50.000828, 50.000847, 50.000824, 50.000832, 50.000832, 50.000816, 50.000713, 50.000877, 50.000832, 50.000912, 50.000824, 50.000885, 50.000797, 50.000786, 50.000824, 50.000824, 50.000854, 50.00087, 50.00087, 50.000874, 50.000824, 50.000908, 50.000843, 50.000786, 50.000824, 50.000839, 50.000744, 50.000839, 50.000786, 50.000835, 50.000809, 50.000866, 50.000816, 50.000877, 50.000866, 50.000847, 50.000885, 50.000832, 50.000832, 50.000847, 50.000843, 50.000858, 50.000744, 50.000847, 50.000763, 50.000847, 50.000778, 50.000786, 50.000851, 50.000786, 50.000771, 50.00082, 50.000797, 50.000854, 50.000809, 50.000866, 50.000881, 50.000839, 50.0009, 50.000862, 50.00082, 50.000763, 50.000839, 50.000782, 50.000843, 50.000832, 50.000824, 50.000885, 50.000854, 50.000816, 50.000835, 50.000832, 50.000744, 50.000858, 50.000854, 50.000862, 50.000881, 50.000877, 50.000839, 50.000755, 50.000877, 50.000843, 50.000835, 50.000877, 50.000816, 50.000813, 50.000801, 50.000874, 50.000824, 50.000751, 50.000786, 50.00087, 50.0009, 50.00087, 50.000778, 50.000778, 50.000896, 50.000912, 50.000824, 50.000809, 50.000843, 50.000847, 50.000862, 50.000786, 50.000847, 50.000889, 50.00087, 50.000824, 50.000797, 50.000851, 50.000813, 50.000839, 50.000885, 50.000889, 50.000813, 50.000843, 50.000854, 50.000744, 50.00087, 50.000877, 50.000851, 50.000835, 50.000832, 50.000816, 50.000816, 50.000828, 50.00087, 50.000839, 50.00082, 50.000854, 50.000828, 50.000885, 50.000801, 50.000763, 50.000839, 50.000816, 50.000816, 50.000881, 50.000828, 50.00087, 50.000877, 50.000805, 50.000908, 50.000778, 50.000877, 50.000824, 50.000862, 50.000847, 50.000854, 50.00087, 50.000771, 50.000885, 50.000839, 50.000786, 50.000858, 50.000824, 50.000816, 50.00079, 50.000877, 50.000813, 50.000854, 50.000885, 50.000824, 50.0009, 50.00087, 50.000893, 50.000824, 50.000854, 50.000828, 50.000816, 50.000809, 50.000832, 50.000755, 50.000816, 50.000797, 50.000851, 50.000824, 50.000893, 50.000813, 50.000877, 50.000809, 50.000839, 50.000748, 50.000847, 50.000885, 50.000885, 50.000893, 50.000854, 50.000854, 50.000778, 50.000854, 50.000801, 50.000885, 50.000816, 50.000858, 50.000778, 50.00082, 50.000771, 50.000832, 50.000843, 50.000824, 50.000816, 50.00087, 50.000813, 50.0009, 50.000832, 50.000816, 50.000908, 50.000809, 50.000839, 50.000832, 50.000835, 50.000885, 50.000786, 50.000786, 50.000847, 50.000809, 50.000824, 50.000832, 50.000809, 50.000874, 50.000847, 50.000771, 50.000877, 50.000851, 50.000835, 50.000874, 50.000751, 50.000801, 50.00087, 50.000854, 50.000793, 50.000832, 50.000858, 50.000824, 50.0009, 50.0009, 50.000771, 50.000797, 50.000885, 50.000874, 50.000828, 50.000832, 50.000832, 50.000832, 50.000786, 50.03508, 50.000877, 50.000893, 50.000862, 50.000847, 50.000881, 50.000793, 50.00087, 50.000828, 50.000816, 50.000847, 50.000854, 50.000824, 50.000893, 50.000854, 50.000839, 50.000854, 50.000797, 50.000816, 50.000816, 50.000786, 50.000786, 50.000847, 50.0009, 50.000809, 50.000847, 50.000763, 50.000835, 50.000813, 50.000816, 50.000854, 50.000824, 50.000835, 50.000774, 50.000839, 50.000839, 50.000801, 50.000759, 50.000847, 50.000832, 50.000854, 50.000786, 50.000893, 50.000862, 50.000824, 50.00082, 50.000778, 50.000809, 50.000832, 49.996906, 50.000824, 50.00087, 50.000885, 50.000809, 50.000885, 50.000801, 50.000816, 50.00087, 50.000893, 50.000729, 50.000832, 50.000877, 50.000805, 50.000748, 50.000938, 50.000816, 50.000824, 50.000801, 50.000847, 50.000816, 50.000809, 50.000839, 50.000851, 50.00082, 50.000854, 50.012714, 50.00079, 50.000854, 50.000847, 50.000862, 50.000828, 50.000778], "../../lab-windows/rocof_test_data/rocof_test_close_interharmonics_and_flicker_1kHz.bin": [50.027557, 50.004166, 49.978928, 49.966015, 49.972816, 49.99535, 50.020954, 50.034328, 50.018772, 49.979389, 50.009258, 49.995995, 50.010704, 49.991077, 49.996254, 50.002254, 50.002865, 50.000443, 49.997631, 50.000156, 50.002708, 49.999229, 50.001823, 50.000877, 50.000095, 50.000324, 50.000542, 50.000526, 50.000614, 50.000782, 50.000881, 50.00071, 50.000786, 50.000809, 50.000832, 50.000816, 50.000786, 50.000763, 50.000763, 50.000801, 50.000908, 50.000835, 50.000862, 50.000816, 50.000809, 50.000809, 50.000801, 50.000763, 50.000923, 50.000763, 50.000847, 50.000797, 50.000736, 50.000809, 50.000809, 50.000847, 50.000862, 50.000843, 50.000843, 50.000771, 50.000778, 50.000877, 50.000935, 50.000877, 50.000839, 50.000809, 50.000813, 50.000919, 50.00087, 50.000759, 50.000908, 50.000793, 50.000847, 50.000793, 50.000801, 50.000877, 50.00087, 50.000786, 50.000801, 50.000889, 50.000885, 50.000858, 50.000698, 50.000778, 50.000912, 50.003159, 50.000832, 50.000744, 50.000854, 50.000843, 50.000832, 50.000854, 50.000793, 50.000828, 50.000862, 50.000858, 50.000896, 50.000896, 50.000698, 50.000778, 50.000889, 50.000839, 50.0009, 50.000877, 50.0009, 50.000824, 50.000847, 50.000847, 50.000893, 50.000771, 50.000816, 50.000797, 50.000828, 50.000809, 50.000748, 50.000816, 50.000832, 50.00079, 50.000778, 50.000866, 50.000782, 50.000912, 50.000862, 50.000835, 50.000935, 50.000858, 50.00082, 50.000847, 50.000786, 50.000885, 50.000877, 50.000782, 50.000816, 50.000843, 50.000854, 50.000816, 50.000801, 50.000847, 50.000862, 50.000729, 50.000839, 50.0009, 50.000599, 50.000488, 50.000462, 50.000317, 50.000153, 50.001442, 50.001301, 49.999802, 50.001621, 50.002285, 49.997673, 49.996803, 49.997204, 49.995014, 49.992256, 50.002369, 50.011665, 49.984825, 50.019547, 49.992756, 49.975502, 50.021854, 50.014832, 50.022587, 49.981628, 50.015041, 49.987457, 50.009319, 50.007225, 49.999653, 49.998173, 49.999989, 50.003376, 50.003052, 49.998657, 50.002281, 49.999573, 50.00177, 50.001152, 50.000454, 50.000362, 50.000565, 50.000828, 50.001049, 50.000736, 50.000862, 50.000839, 50.000851, 50.000748, 50.000858, 50.000839, 50.000874, 50.000851, 50.00082, 50.000824, 50.000797, 50.00082, 50.000824, 50.0009, 50.000843, 50.00079, 50.000778, 50.000858, 50.000847, 50.000847, 50.000816, 50.000885, 50.000858, 50.000858, 50.000786, 50.000847, 50.000832, 50.000809, 50.000904, 50.000763, 50.000854, 50.000843, 50.000778, 50.000877, 50.000843, 50.000877, 50.000847, 50.000809, 50.000885, 50.000824, 50.000816, 50.000858, 50.00079, 50.00087, 50.00087, 50.000824, 50.000835, 50.000801, 50.000809, 50.000816, 50.000832, 50.000793, 50.000816, 50.000801, 49.996128, 50.000801, 50.000786, 50.000778, 50.000858, 50.000931, 50.000816, 50.000839, 50.000851, 50.000786, 50.000778, 50.000839, 50.000797, 50.000805, 50.000877, 50.000885, 50.000824, 50.000896, 50.000801, 50.000809, 50.000946, 50.000828, 50.000828, 50.000854, 50.000748, 50.000809, 50.000885, 50.00082, 50.000839, 50.000839, 50.000839, 50.000866, 50.000851, 50.000862, 50.000839, 50.000816, 50.000816, 50.000809, 50.000835, 50.000801, 50.000866, 50.000793, 50.000851, 50.000843, 50.000824, 50.000843, 50.000866, 50.000755, 50.000854, 50.000942, 50.000805, 50.000748, 50.000816, 50.0009, 50.000759, 50.000999, 50.000729, 50.000668, 50.000912, 50.001087, 50.001076, 50.000519, 49.999958, 50.001675, 50.000511, 50.001671, 49.998425, 50.002827, 50.005093, 50.004879, 50.006302, 50.009258, 50.002934, 49.988308, 50.015408, 49.983158, 50.02351, 50.000748, 49.968437, 49.969837, 50.00037, 50.019958, 49.983173, 50.01487, 49.995682, 49.992935, 50.001614, 50.0042, 50.002926, 49.999477, 49.997791, 50.002308, 50.000683, 50.001064, 49.999924, 50.001534, 50.001369, 50.001064, 50.001003, 50.001141, 50.000957, 50.000675, 50.000805, 50.000793, 50.00087, 50.000843, 50.000748, 50.000801, 50.000793, 50.000809, 50.000843, 50.000816, 50.000885, 50.000877, 50.000832, 50.000809, 50.000881, 50.000816, 50.000793, 50.000874, 50.000885, 50.000755, 50.000809, 50.000931, 50.000835, 50.000847, 50.000797, 50.000809, 50.000778, 50.000877, 50.00087, 50.000847, 50.000786, 50.000935, 50.000801, 50.000767, 50.000866, 50.000778, 50.00082, 50.00087, 50.000896, 50.00087, 50.000862, 50.000786, 50.00087, 50.000763, 50.000706, 50.000843, 50.000854, 50.000832, 50.000957, 50.000763, 50.000874, 50.000843, 50.000896, 50.000847, 50.000877, 50.000832, 50.000862, 50.000782, 50.000801, 50.000809, 50.000771, 50.000801, 50.000908, 50.000813, 50.000786, 50.000721, 50.000778, 50.000874, 50.000828, 50.000778, 50.000935, 50.000763, 50.000862, 50.00087, 50.000935, 50.000885, 50.000854, 50.00087, 50.000771, 50.000916, 50.000866, 50.000847, 50.000748, 50.00087, 50.000916, 50.000862, 50.000912, 50.00079, 50.000797, 50.000813, 50.000797, 50.000832, 50.000832, 50.000801, 50.000877, 50.000774, 50.000854, 50.000843, 50.000809, 50.000778, 50.000847, 50.000877, 50.000801, 50.000793, 50.00087, 50.000816, 50.000774, 50.0009, 50.000786, 50.000957, 50.000687, 50.000862, 50.001137, 50.00119, 50.001331, 50.001457, 50.000809, 49.999729, 50.002274, 49.999058, 50.003315, 50.000408, 49.996815], "../../lab-windows/rocof_test_data/rocof_test_harmonics_1kHz.bin": [50.000473, 50.000961, 50.00098, 50.000473, 50.001339, 50.000458, 50.000957, 50.00098, 50.000488, 50.00124, 50.000465, 50.000919, 50.001038, 50.000481, 50.001293, 50.000408, 50.001022, 50.00103, 50.000519, 50.001255, 50.000488, 50.000969, 50.001019, 50.00045, 50.001301, 50.000557, 50.000919, 50.000969, 50.000515, 50.00127, 50.000523, 50.000942, 50.000969, 50.000427, 50.00127, 50.000427, 50.001003, 50.000973, 50.000435, 50.001198, 50.000557, 50.001045, 50.000938, 50.000484, 50.001274, 50.000427, 50.001064, 50.0009, 50.000515, 50.001263, 50.000443, 50.001026, 50.000927, 50.000473, 50.001278, 50.000496, 50.00098, 50.001049, 50.000481, 50.001278, 50.000443, 50.001003, 50.000954, 50.000454, 50.001286, 50.000435, 50.000946, 50.000988, 50.000496, 50.001232, 50.000435, 50.001049, 50.000893, 50.000473, 50.001339, 50.000473, 50.001026, 50.000942, 50.000481, 50.00124, 50.000473, 50.00098, 50.000957, 50.000416, 50.00124, 50.000427, 50.001041, 50.000893, 50.000465, 50.001263, 50.000431, 50.001026, 50.000942, 50.000465, 50.001278, 50.000427, 50.001026, 50.000927, 50.000423, 50.001263, 50.000473, 50.001011, 50.000935, 50.000416, 50.001255, 50.000416, 50.000984, 50.000957, 50.000523, 50.001228, 50.000504, 50.001019, 50.000931, 50.000469, 50.001324, 50.000427, 50.001041, 50.000965, 50.000462, 50.00127, 50.000362, 50.001041, 50.000896, 50.000435, 50.00127, 50.000469, 50.001015, 50.000881, 50.000549, 50.001183, 50.000381, 50.000977, 50.000965, 50.000462, 50.001324, 50.000408, 50.00098, 50.000885, 50.000488, 50.001305, 50.000458, 50.000988, 50.000916, 50.000458, 50.001312, 50.000465, 50.001019, 50.000957, 50.000523, 50.001308, 50.000504, 50.000973, 50.000973, 50.000511, 50.001255, 50.000458, 50.001038, 50.000919, 50.000572, 50.001228, 50.000427, 50.000988, 50.000988, 50.000465, 50.001232, 50.000435, 50.000988, 50.000912, 50.000477, 50.001316, 50.000477, 50.001057, 50.000927, 50.000526, 50.00127, 50.000393, 50.00108, 50.000935, 50.000507, 50.00124, 50.000423, 50.001064, 50.000908, 50.000496, 50.001278, 50.000504, 50.001011, 50.000885, 50.00045, 50.001293, 50.000435, 50.00095, 50.000919, 50.00045, 50.001247, 50.000401, 50.001087, 50.000908, 50.000435, 50.001225, 50.000427, 50.001057, 50.000862, 50.000542, 50.001324, 50.00042, 50.001049, 50.000935, 50.000507, 50.001297, 50.000458, 50.001129, 50.0009, 50.000465, 50.001244, 50.000458, 50.001064, 50.000908, 50.000607, 50.001263, 50.000359, 50.00098, 50.000923, 50.000473, 50.00127, 50.000427, 50.000992, 50.000908, 50.000526, 50.001297, 50.000481, 50.001038, 50.000973, 50.000511, 50.001293, 50.00042, 50.001106, 50.000881, 50.000526, 50.001278, 50.000458, 50.00106, 50.000851, 50.000488, 50.001293, 50.000416, 50.00108, 50.000957, 50.000534, 50.001232, 50.000332, 50.001064, 50.00087, 50.000526, 50.00127, 50.000393, 50.001019, 50.000919, 50.000526, 50.001305, 50.000393, 50.000961, 50.000919, 50.000526, 50.001259, 50.000427, 50.001064, 50.000874, 50.000561, 50.00135, 50.000435, 50.001064, 50.0009, 50.000526, 50.001354, 50.000416, 50.001099, 50.000843, 50.000507, 50.001308, 50.000473, 50.001019, 50.00087, 50.000549, 50.001232, 50.000393, 50.000988, 50.000877, 50.000587, 50.001255, 50.000469, 50.001068, 50.00095, 50.000542, 50.001228, 50.000435, 50.001064, 50.000824, 50.000557, 50.001331, 50.000465, 50.001083, 50.000927, 50.000587, 50.001289, 50.000408, 50.001076, 50.000877, 50.000542, 50.001255, 50.000431, 50.001041, 50.00087, 50.000519, 50.001247, 50.000393, 50.001057, 50.000927, 50.000504, 50.001274, 50.000477, 50.001068, 50.000858, 50.000538, 50.00124, 50.000408, 50.001064, 50.000893, 50.000526, 50.001225, 50.000423, 50.001041, 50.000858, 50.000473, 50.001293, 50.000378, 50.001057, 50.000999, 50.000607, 50.001316, 50.000443, 50.001057, 50.000877, 50.00053, 50.001263, 50.000423, 50.001057, 50.00095, 50.000523, 50.001308, 50.000393, 50.001011, 50.000877, 50.000481, 50.001293, 50.000416, 50.001034, 50.000843, 50.000553, 50.001259, 50.000347, 50.001068, 50.00087, 50.000622, 50.001308, 50.000401, 50.001091, 50.000839, 50.000523, 50.001286, 50.000408, 50.001049, 50.000935, 50.0005, 50.001255, 50.000458, 50.001144, 50.000839, 50.000481, 50.001263, 50.000385, 50.001041, 50.00087, 50.000576, 50.001289, 50.000481, 50.001064, 50.00087, 50.000629, 50.001221, 50.000378, 50.001049, 50.000816, 50.000587, 50.001225, 50.000423, 50.001076, 50.000778, 50.000572, 50.00124, 50.000408, 50.00106, 50.000832, 50.000534, 50.001255, 50.000496, 50.001099, 50.000893, 50.000469, 50.001221, 50.000397, 50.00116, 50.000858, 50.000496, 50.001266, 50.000401, 50.001076, 50.000793, 50.000607, 50.001263, 50.000401, 50.001083, 50.000793, 50.000599, 50.001308, 50.000439, 50.001102, 50.000824, 50.000534, 50.00127, 50.000416, 50.001087, 50.000904, 50.000519, 50.001251, 50.000446, 50.001049, 50.00087, 50.000599, 50.001213, 50.00037, 50.001076, 50.000835, 50.000519, 50.001286, 50.000378, 50.001083, 50.000839, 50.000591, 50.001232, 50.000359, 50.001076, 50.000908, 50.000584, 50.001316, 50.00037, 50.001118, 50.000854, 50.000553, 50.001247, 50.000408, 50.001068, 50.000854, 50.00053, 50.00127, 50.00037], "../../lab-windows/rocof_test_data/rocof_test_interharmonics_1kHz.bin": [50.000782, 50.000854, 50.000809, 50.000839, 50.000824, 50.000839, 50.000824, 50.000847, 50.000801, 50.000786, 50.0009, 50.000771, 50.000843, 50.000809, 50.0009, 50.000874, 50.000854, 50.000813, 50.000908, 50.00087, 50.000816, 50.000813, 50.000805, 50.000832, 50.000786, 50.000805, 50.000839, 50.000843, 50.000793, 50.000874, 50.000824, 50.000851, 50.000801, 50.0009, 50.000748, 50.000748, 50.000828, 50.000813, 50.000832, 50.000778, 50.000816, 50.00087, 50.000816, 50.000942, 50.000893, 50.000832, 50.000847, 50.00087, 50.000793, 50.00082, 50.000839, 50.000866, 50.000862, 50.00087, 50.000824, 50.0009, 50.000797, 50.000816, 50.000748, 50.000835, 50.000854, 50.000824, 50.000816, 50.000854, 50.000763, 50.000854, 50.000877, 50.000801, 50.000862, 50.00082, 50.000881, 50.00082, 50.000847, 50.000885, 50.000801, 50.000858, 50.000912, 50.000896, 50.000816, 50.000778, 50.000832, 50.000854, 50.000816, 50.000824, 50.000801, 50.000854, 50.000771, 50.00087, 50.000835, 50.000824, 50.000778, 50.000755, 50.00087, 50.000916, 50.000801, 50.000854, 50.000858, 50.000877, 50.000809, 50.000839, 50.000824, 50.000801, 50.000839, 50.000885, 50.000847, 50.000809, 50.000755, 50.00079, 50.000847, 50.00087, 50.000862, 50.000885, 50.000778, 50.000839, 50.000858, 50.000809, 50.000862, 50.000778, 50.000813, 50.000809, 50.000832, 50.000813, 50.000824, 50.000866, 50.000885, 50.000885, 50.000778, 50.000801, 50.000889, 50.000858, 50.000893, 50.000801, 50.000801, 50.000778, 50.000847, 50.000797, 50.000832, 50.000847, 50.000877, 50.000847, 50.000778, 50.000793, 50.000908, 50.000816, 50.000832, 50.000843, 50.000877, 50.000793, 50.000763, 50.000889, 50.000816, 50.00087, 50.000824, 50.000778, 50.000824, 50.000847, 50.000793, 50.00087, 50.000824, 50.000778, 50.000832, 50.000767, 50.000877, 50.000839, 50.00087, 50.000786, 50.000778, 50.000813, 50.000862, 50.000801, 50.000809, 50.000824, 50.000839, 50.000828, 50.000809, 50.000854, 50.000778, 50.000839, 50.000885, 50.00087, 50.000832, 50.000816, 50.000771, 50.000824, 50.000793, 50.000912, 50.000816, 50.00087, 50.000786, 50.000843, 50.00087, 50.00087, 50.000854, 50.000839, 50.00087, 50.000847, 50.000839, 50.000847, 50.000862, 50.000824, 50.000816, 50.000885, 50.000843, 50.000771, 50.000778, 50.000778, 50.000885, 50.000862, 50.000832, 50.000816, 50.000813, 50.000771, 50.000854, 50.00087, 50.00087, 50.000771, 50.000816, 50.00087, 50.000832, 50.000835, 50.000832, 50.000832, 50.000816, 50.000839, 50.000881, 50.000862, 50.000816, 50.000809, 50.000828, 50.000877, 50.000908, 50.000744, 50.00087, 50.000851, 50.000763, 50.000912, 50.000801, 50.000893, 50.000832, 50.000809, 50.000748, 50.000877, 50.000801, 50.000824, 50.000816, 50.000771, 50.000744, 50.000843, 50.000885, 50.00087, 50.000832, 50.000862, 50.000816, 50.000854, 50.000851, 50.000793, 50.000755, 50.000862, 50.000832, 50.000816, 50.000893, 50.000809, 50.000771, 50.000927, 50.000809, 50.000778, 50.000778, 50.000748, 50.000862, 50.000885, 50.000839, 50.000805, 50.000832, 50.000828, 50.000782, 50.000832, 50.000793, 50.000824, 50.00087, 50.000828, 50.000832, 50.000835, 50.00087, 50.000862, 50.000839, 50.000771, 50.000839, 50.000809, 50.000809, 50.00082, 50.000809, 50.000782, 50.000912, 50.000885, 50.000908, 50.000923, 50.000919, 50.000832, 50.000778, 50.000832, 50.000893, 50.000908, 50.000839, 50.000763, 50.000843, 50.000816, 50.000839, 50.000748, 50.000839, 50.000813, 50.000771, 50.000809, 50.000755, 50.000877, 50.000813, 50.000816, 50.000813, 50.000832, 50.000801, 50.000801, 50.000835, 50.00082, 50.000763, 50.000828, 50.000778, 50.000847, 50.000832, 50.000877, 50.00087, 50.000885, 50.000839, 50.000839, 50.00087, 50.000889, 50.000919, 50.000839, 50.000832, 50.000874, 50.000832, 50.000824, 50.000824, 50.000854, 50.000847, 50.000851, 50.000858, 50.000877, 50.0009, 50.000877, 50.000824, 50.000809, 50.000805, 50.000839, 50.00082, 50.000862, 50.000771, 50.000832, 50.000805, 50.000839, 50.000801, 50.000835, 50.000862, 50.000816, 50.000832, 50.000809, 50.000881, 50.000824, 50.000847, 50.000801, 50.000877, 50.000839, 50.000809, 50.000786, 50.000824, 50.000832, 50.000763, 50.000771, 50.000805, 50.000767, 50.000854, 50.000809, 50.000904, 50.000847, 50.0009, 50.000893, 50.000927, 50.000771, 50.000893, 50.000862, 50.000828, 50.000847, 50.000832, 50.000858, 50.000885, 50.000824, 50.000786, 50.000839, 50.000809, 50.000786, 50.000813, 50.00082, 50.000854, 50.000881, 50.000824, 50.000786, 50.000809, 50.000832, 50.000854, 50.000824, 50.000809, 50.000797, 50.00079, 50.00082, 50.000832, 50.000854, 50.000885, 50.000801, 50.000862, 50.000832, 50.000809, 50.000816, 50.000824, 50.000839, 50.000782, 50.000912, 50.00087, 50.000839, 50.000797, 50.000809, 50.000851, 50.000809, 50.000778, 50.00082, 50.000793, 50.000763, 50.000912, 50.000839, 50.000854, 50.00087, 50.000771, 50.000748, 50.000824, 50.000763, 50.000854, 50.000801, 50.000843, 50.000832, 50.000866, 50.000862, 50.000839, 50.000763, 50.000824, 50.000874, 50.000816, 50.000828, 50.000801, 50.000786, 50.000839, 50.000824, 50.000813, 50.000763, 50.000828, 50.000935, 50.000748, 50.000832, 50.000877, 50.00079], "../../lab-windows/rocof_test_data/rocof_test_noise_1kHz.bin": [50.009163, 49.95969, 50.012573, 50.0191, 50.009937, 49.955059, 49.955971, 50.032398, 50.007336, 50.012947, 49.999924, 49.978771, 50.026817, 50.019897, 49.992374, 50.004333, 49.968102, 49.977436, 50.037025, 50.043186, 49.990314, 49.987942, 50.013042, 50.01469, 49.996082, 50.023354, 50.074497, 50.073296, 50.017872, 50.007744, 49.981949, 50.020733, 50.010151, 50.010334, 50.034035, 49.990162, 50.009121, 50.029747, 50.023048, 49.993118, 49.926266, 50.026215, 49.99572, 49.99469, 50.020554, 49.982838, 50.042706, 49.986282, 50.006306, 49.990356, 50.040916, 50.063332, 50.018822, 50.03027, 50.017326, 49.987778, 50.017521, 50.006813, 50.027687, 49.994759, 50.031506, 50.0196, 49.991955, 50.001911, 49.990154, 49.970284, 50.033115, 50.003201, 49.964333, 50.018795, 49.969128, 49.998699, 50.026134, 49.992893, 49.971134, 49.9925, 49.958263, 49.99144, 50.024963, 49.952896, 49.998508, 50.003639, 50.005749, 49.989426, 49.989395, 50.01474, 49.976913, 49.991398, 50.00116, 49.987995, 50.011879, 50.020351, 50.007484, 49.973938, 50.051868, 49.990952, 50.033955, 49.982227, 50.024212, 49.972645, 50.066257, 49.982971, 50.031799, 50.011276, 50.008045, 50.010586, 49.994675, 49.980667, 49.999245, 49.989624, 50.051666, 50.013813, 50.009357, 50.021782, 50.049431, 50.036362, 50.007069, 49.994705, 49.987083, 50.009987, 49.986595, 49.99403, 49.984303, 50.002628, 49.988625, 49.983047, 50.006866, 49.947021, 50.021774, 49.986217, 49.972855, 49.948929, 50.010994, 50.037651, 50.001698, 50.030182, 49.962467, 49.995811, 49.938698, 49.975857, 49.972862, 49.992859, 49.957001, 49.998604, 49.996899, 50.018585, 49.953796, 50.050625, 49.99052, 50.000366, 50.016636, 50.005676, 50.007164, 50.002865, 50.051712, 49.961029, 50.019066, 50.015087, 49.990425, 50.045128, 49.981213, 50.058464, 50.017738, 49.988003, 49.968033, 50.063148, 49.973747, 49.997898, 49.936501, 50.005302, 49.994568, 49.995491, 50.013275, 49.979412, 49.984745, 50.035404, 50.028557, 49.968407, 49.998531, 49.986614, 50.001568, 49.994156, 50.000706, 49.99025, 50.050354, 50.010216, 50.005932, 50.021194, 49.987255, 49.995071, 50.033531, 50.003605, 50.008392, 49.993546, 49.979591, 50.049374, 50.018787, 49.988621, 49.968468, 49.969677, 49.984657, 49.994736, 49.958466, 50.018757, 50.000511, 49.98848, 49.990913, 49.990677, 50.020527, 50.049175, 49.985447, 50.033264, 49.9893, 50.018578, 50.016655, 50.01931, 50.001629, 50.015816, 49.997154, 50.011433, 50.021404, 49.967758, 49.975136, 50.015572, 50.035671, 49.999081, 50.012058, 49.996258, 50.014198, 49.99884, 50.025414, 49.977497, 50.016857, 49.999634, 50.029694, 49.978851, 50.017857, 50.011456, 49.943207, 49.986443, 50.028343, 49.994377, 49.991394, 50.035931, 49.995312, 49.979309, 50.05098, 50.013527, 50.04546, 50.029755, 49.978333, 49.986439, 49.979469, 50.013481, 50.012192, 50.01247, 49.998463, 50.022781, 49.984417, 49.980492, 49.961048, 49.991032, 49.97818, 50.017036, 50.000591, 50.001926, 50.033123, 50.041065, 49.964573, 50.046883, 50.057056, 49.987206, 50.004879, 49.991234, 50.00787, 50.041451, 49.988747, 50.027687, 49.987534, 49.956348, 49.981728, 49.990742, 50.026825, 49.984489, 49.963264, 50.008694, 49.986088, 50.01125, 50.011929, 50.010948, 50.008579, 50.043045, 49.99435, 49.992332, 50.011086, 50.023247, 49.95924, 50.024929, 49.992622, 49.996952, 50.050819, 49.995586, 50.011723, 50.079906, 50.011894, 50.031193, 50.051102, 49.967579, 50.026802, 49.990021, 50.025558, 49.961872, 50.007122, 49.996422, 50.015961, 49.986702, 50.02079, 49.967213, 49.981434, 49.996368, 50.055027, 50.023392, 50.003262, 50.054184, 50.021461, 50.018826, 50.024902, 50.007114, 50.009094, 50.032177, 50.002403, 49.965046, 50.043587, 49.998604, 49.976742, 50.003147, 50.021935, 50.01226, 50.0326, 50.005398, 49.983952, 50.043926, 50.06596, 49.988052, 50.026424, 49.987938, 50.063583, 49.94981, 50.010948, 49.961098, 49.960327, 50.041565, 49.999603, 50.060123, 50.020836, 50.017315, 50.027859, 50.020584, 50.013546, 49.980255, 49.995071, 49.967579, 49.973564, 49.975597, 50.013447, 50.006512, 50.005787, 50.02351, 50.005642, 50.027039, 49.961281, 49.983025, 49.987011, 49.953545, 50.019424, 50.004131, 50.007946, 49.990818, 49.993664, 50.005554, 49.982716, 49.977966, 49.981777, 49.994312, 49.965721, 50.005661, 50.001823, 50.002701, 49.952782, 50.007198, 49.994579, 49.951492, 50.013504, 49.998127, 49.98637, 50.02301, 50.000237, 50.036125, 49.956078, 50.014748, 50.01289, 49.993668, 49.934376, 50.016953, 50.004631, 49.999702, 49.974709, 50.00671, 50.008743, 50.01907, 50.002842, 49.987526, 50.042645, 50.012665, 50.004055, 49.991669, 49.95916, 50.020882, 49.997448, 50.010002, 50.003319, 49.971691, 49.981106, 50.042133, 49.989994, 50.037304, 50.015411, 49.977249, 50.055889, 50.000317, 50.011314, 49.965752, 49.966209, 50.003613, 49.970543, 50.01759, 50.013252, 49.990452, 50.019241, 49.99963, 49.986935, 50.017609, 50.00631, 50.006271, 49.991627, 49.965313, 50.03886, 50.015015, 49.984535, 50.012253, 49.955563, 49.975834, 49.97179, 50.032215, 49.988731, 49.991646, 50.033916, 49.975266, 50.039707, 49.988804, 50.020187, 49.985275, 49.95715, 50.023586, 49.989475, 50.011909], "../../lab-windows/rocof_test_data/rocof_test_noise_loud_1kHz.bin": [46.933208, 49.813229, 52.30492, 52.318615, 48.8255, 48.14735, 51.047943, 49.142696, 50.223026, 49.646637, 48.668324, 50.953522, 50.075775, 48.848549, 50.948292, 50.438263, 50.679314, 49.646961, 50.040108, 47.891384, 53.575142, 48.323029, 49.809288, 51.517204, 49.958626, 51.756554, 48.915909, 48.644669, 51.510246, 49.273411, 49.909046, 52.153393, 49.109749, 50.168903, 50.347225, 49.657028, 50.907574, 49.468456, 49.066624, 49.844585, 50.219193, 49.205627, 50.628304, 50.408577, 50.372082, 51.597954, 51.402443, 50.247082, 51.711582, 49.563274, 49.796329, 49.424725, 49.275547, 50.358826, 51.437733, 51.061176, 49.053528, 49.336487, 50.531082, 50.03167, 48.982605, 49.095036, 49.125607, 51.305519, 51.203804, 51.309181, 52.298962, 51.639809, 48.832485, 49.355961, 50.030582, 49.57798, 49.88591, 50.678745, 50.436573, 48.171165, 50.769234, 52.772778, 49.879341, 50.346405, 50.212204, 50.985119, 50.731384, 49.888424, 49.223286, 50.780521, 49.661949, 52.318748, 50.735352, 49.264168, 51.175377, 48.738247, 49.40004, 49.859203, 50.231434, 51.399113, 50.068768, 51.145351, 49.002201, 47.073475, 48.111198, 49.177959, 49.206715, 50.888607, 52.849846, 50.682426, 50.162937, 50.429596, 49.717861, 51.505569, 51.13966, 50.200542, 52.036732, 49.858444, 48.738136, 48.64016, 50.478477, 49.312584, 50.731289, 52.220901, 49.509785, 50.093761, 50.043427, 51.529163, 49.201286, 48.904663, 49.493984, 51.224815, 50.992592, 50.608307, 51.12022, 50.836166, 51.996803, 51.049999, 49.955658, 50.163422, 50.307125, 48.269936, 49.627251, 50.800739, 49.842876, 50.871906, 47.98127, 48.80579, 50.417126, 50.339668, 50.132156, 51.832958, 49.461128, 48.454838, 50.484764, 50.667847, 49.824619, 47.327431, 48.76791, 51.254959, 52.121933, 49.482159, 49.79348, 49.983704, 49.056873, 49.051464, 51.079102, 50.739838, 49.886929, 48.820213, 48.85524, 49.955566, 52.142715, 49.381756, 48.276691, 48.412735, 48.334053, 50.224514, 49.050838, 50.633976, 48.351318, 50.887367, 47.945881, 50.706001, 52.26416, 50.589008, 49.764679, 49.971058, 51.105469, 50.024208, 50.530464, 52.588287, 50.889305, 50.805473, 50.796108, 48.108303, 47.308998, 51.120461, 50.544716, 48.394291, 49.044968, 50.024956, 50.151146, 49.985931, 49.639946, 49.324581, 50.427242, 51.315105, 47.415161, 52.76516, 48.238216, 50.224194, 47.275604, 49.800159, 49.888428, 49.992031, 48.684902, 50.62809, 49.590172, 49.293007, 51.069321, 50.50087, 51.11488, 49.824566, 50.52895, 48.362366, 51.52599, 49.520546, 50.779194, 50.866947, 49.663513, 50.280014, 50.449604, 52.934246, 48.876904, 49.555561, 48.350922, 49.877144, 48.961563, 49.169575, 48.766708, 53.037136, 50.311665, 49.37468, 48.389263, 51.992027, 49.675018, 50.412868, 46.899002, 49.225758, 49.50983, 50.789017, 50.973587, 49.90546, 49.513489, 52.101574, 50.029003, 49.406441, 50.56638, 49.670017, 50.563812, 51.96806, 49.863422, 50.207333, 51.097885, 50.280411, 51.509689, 50.436691, 48.165806, 49.688847, 52.187832, 48.644974, 47.606018, 50.025394, 49.74807, 49.989479, 49.911297, 49.454613, 49.949627, 51.354107, 50.678379, 49.692059, 49.213177, 49.927742, 49.032856, 49.397724, 52.518696, 49.757927, 50.017593, 50.154587, 50.603977, 49.762493, 49.443638, 52.435188, 49.258919, 49.942875, 50.084927, 49.929783, 49.641579, 48.253265, 49.70298, 49.06337, 48.665062, 48.605221, 49.11396, 51.001904, 52.127666, 50.891354, 50.560364, 50.184967, 49.714439, 51.369759, 51.033165, 46.571575, 48.314663, 48.91222, 48.241749, 50.689774, 47.76685, 48.997013, 48.406734, 51.419655, 49.28854, 49.50988, 50.615822, 50.725876, 51.317974, 48.130539, 50.114254, 49.258614, 51.216415, 50.853619, 51.079063, 48.675209, 50.037125, 50.783726, 50.263977, 49.737038, 50.733089, 51.635532, 49.090862, 51.488304, 48.123264, 49.635174, 49.114994, 51.520267, 50.913162, 50.671471, 49.715809, 48.315025, 48.616028, 49.43441, 50.711369, 50.806412, 48.558159, 49.54739, 49.176254, 50.041241, 50.861958, 50.030464, 50.878204, 49.369881, 48.657379, 51.300549, 50.714836, 48.869934, 49.547749, 51.067989, 48.461563, 53.183331, 50.513775, 50.147762, 50.071507, 50.033928, 49.818768, 49.357792, 48.732922, 50.192085, 50.337605, 49.858105, 51.598141, 49.965389, 49.232407, 47.966801, 49.889896, 50.158485, 50.776009, 49.41, 50.418026, 49.238071, 51.277218, 51.346527, 49.10643, 51.168392, 48.204906, 51.624001, 48.733913, 50.539742, 48.977974, 49.273952, 49.919704, 50.063759, 49.560787, 49.750679, 49.517998, 48.675938, 51.026688, 49.079376, 52.29155, 49.480736, 48.68539, 49.39542, 50.601921, 52.516861, 50.116486, 50.856857, 49.476406, 51.01186, 49.037418, 49.743626, 50.961811, 49.333504, 52.005672, 49.830479, 52.377796, 48.853119, 49.172947, 49.085445, 50.973602, 47.308868, 51.182629, 49.535141, 51.791496, 48.872452, 52.665688, 48.177017, 50.253963, 50.755348, 51.350185, 50.785019, 53.021065, 48.561378, 49.763798, 51.27705, 50.413906, 51.514187, 50.720119, 51.230137, 50.829243, 49.297638, 46.736481, 48.626549, 49.212753, 47.558292, 50.348591, 47.89888, 50.496334, 51.335781, 50.080643, 50.813206, 49.165787, 50.154888, 50.332779, 47.933216, 50.32021, 49.946068, 49.417385, 50.72525, 49.048508, 49.403996], "../../lab-windows/rocof_test_data/rocof_test_off_frequency_1kHz.bin": [48.000839, 48.000778, 48.000816, 48.000805, 48.000858, 48.000813, 48.00082, 48.011509, 48.065632, 48.116783, 48.168037, 48.219189, 48.270451, 48.321648, 48.372833, 48.424103, 48.475323, 48.526447, 48.577778, 48.628922, 48.680164, 48.731339, 48.7826, 48.833763, 48.885002, 48.936172, 48.987434, 49.038578, 49.08984, 49.141121, 49.192268, 49.243404, 49.294727, 49.345875, 49.397079, 49.448296, 49.499451, 49.550667, 49.601944, 49.653164, 49.704361, 49.755596, 49.806744, 49.85804, 49.909184, 49.960388, 50.011589, 50.062836, 50.113987, 50.165253, 50.21645, 50.267628, 50.318798, 50.37014, 50.421284, 50.472431, 50.523781, 50.574905, 50.62616, 50.677296, 50.728546, 50.779709, 50.830967, 50.882206, 50.933422, 50.984562, 51.035786, 51.086948, 51.138168, 51.189476, 51.240608, 51.291897, 51.343151, 51.394276, 51.445538, 51.496758, 51.547989, 51.599117, 51.650322, 51.7015, 51.752644, 51.803959, 51.855167, 51.906357, 51.957649, 50.661987, 51.950829, 51.899612, 51.848366, 51.797085, 51.745899, 51.694736, 51.643482, 51.592289, 51.541122, 51.489933, 51.438686, 51.387405, 51.33622, 51.285, 51.233837, 51.182621, 51.131435, 51.080181, 51.028931, 50.977795, 50.926544, 50.87542, 50.824135, 50.773014, 50.721779, 50.670509, 50.619282, 50.568134, 50.516918, 50.465748, 50.414547, 50.363319, 50.312084, 50.260895, 50.209656, 50.158398, 50.107258, 50.055996, 50.004814, 49.95359, 49.902344, 49.851147, 49.799957, 49.748802, 49.697517, 49.64637, 49.595116, 49.543926, 49.492687, 49.441494, 49.390289, 49.339088, 49.287884, 49.236713, 49.18541, 49.134254, 49.083008, 49.031837, 48.980572, 48.929363, 48.878155, 48.826962, 48.775726, 48.724609, 48.673309, 48.622124, 48.570961, 48.519657, 48.468582, 48.417328, 48.366093, 48.314857, 48.263615, 48.212543, 48.161304, 48.110069, 48.058788, 46.71962, 48.052788, 48.104046, 48.155277, 48.20647, 48.25761, 48.308945, 48.360065, 48.411293, 48.462479, 48.513691, 48.564911, 48.61615, 48.66737, 48.718533, 48.769741, 48.821014, 48.872147, 48.923382, 48.974625, 49.025803, 49.077042, 49.128193, 49.179413, 49.23061, 49.281799, 49.33305, 49.384327, 49.435482, 49.486736, 49.537968, 49.589111, 49.640312, 49.691528, 49.742767, 49.793938, 49.845196, 49.896389, 49.947552, 49.998798, 50.049938, 50.101212, 50.152473, 50.203621, 50.25486, 50.306095, 50.357292, 50.408501, 50.459736, 50.510838, 50.562149, 50.613255, 50.664513, 50.715775, 50.76696, 50.818092, 50.869377, 50.920574, 50.971767, 51.022999, 51.074223, 51.125423, 51.176659, 51.22784, 51.279083, 51.330223, 51.381432, 51.432655, 51.483875, 51.53513, 51.586262, 51.637581, 51.688747, 51.739986, 51.791187, 51.8424, 51.893646, 51.944786, 51.756561, 51.963551, 51.912426, 51.861122, 51.809994, 51.758713, 51.707474, 51.656387, 51.605122, 51.553928, 51.502693, 51.451504, 51.400311, 51.349094, 51.297874, 51.246666, 51.19537, 51.144203, 51.093086, 51.041821, 50.990536, 50.939426, 50.888222, 50.836937, 50.785667, 50.734615, 50.683372, 50.632168, 50.580948, 50.529743, 50.478458, 50.427204, 50.376068, 50.324856, 50.273651, 50.222397, 50.171307, 50.120003, 50.06889, 50.017567, 49.966385, 49.915211, 49.863895, 49.812725, 49.761559, 49.710354, 49.659096, 49.607903, 49.556652, 49.505508, 49.454338, 49.403046, 49.351894, 49.300697, 49.249413, 49.198242, 49.146992, 49.095898, 49.044598, 48.993435, 48.942142, 48.890965, 48.839813, 48.788559, 48.737251, 48.686153, 48.634926, 48.583679, 48.532494, 48.481197, 48.430092, 48.378899, 48.327648, 48.276447, 48.225224, 48.174004, 48.12278, 48.071594, 48.017143, 48.039989, 48.091236, 48.142387, 48.193588, 48.244843, 48.296074, 48.34729, 48.398403, 48.449619, 48.500977, 48.552193, 48.603271, 48.654503, 48.705715, 48.756897, 48.808136, 48.859379, 48.91058, 48.961758, 49.012985, 49.064205, 49.115433, 49.166679, 49.21788, 49.269108, 49.320366, 49.371471, 49.42271, 49.473835, 49.525009, 49.576294, 49.627537, 49.678761, 49.729885, 49.781158, 49.832325, 49.883553, 49.93475, 49.986042, 50.03722, 50.088467, 50.13953, 50.190914, 50.24205, 50.293255, 50.34444, 50.395676, 50.446877, 50.498119, 50.549236, 50.600563, 50.651775, 50.702946, 50.754181, 50.805443, 50.856556, 50.907784, 50.959042, 51.010208, 51.061382, 51.112652, 51.163876, 51.215069, 51.266273, 51.317482, 51.368675, 51.41993, 51.471165, 51.522278, 51.573521, 51.624672, 51.675938, 51.727119, 51.778324, 51.829517, 51.880756, 51.931961, 51.983147, 51.976414, 51.925125, 51.87394, 51.822731, 51.771603, 51.720379, 51.669052, 51.61792, 51.566723, 51.515438, 51.464214, 51.41312, 51.361897, 51.31065, 51.259426, 51.208256, 51.157032, 51.105732, 51.054661, 51.003464, 50.952194, 50.900921, 50.849781, 50.798592, 50.747318, 50.696125, 50.644882, 50.593735, 50.542522, 50.491344, 50.440098, 50.388935, 50.337654, 50.286495, 50.235287, 50.183968, 50.132847, 50.081589, 50.030388, 49.979187, 49.927956, 49.876804, 49.825588, 49.774357, 49.723148, 49.671898, 49.620762, 49.569599, 49.518288, 49.466984, 49.415924, 49.364613, 49.313396, 49.262249, 49.211113, 49.159836, 49.108608, 49.057438, 49.006248, 48.954998, 48.903786, 48.852547, 48.801319, 48.750156, 48.698948, 48.647686, 48.596519, 48.545319], "../../lab-windows/rocof_test_data/rocof_test_phase_steps_1kHz.bin": [50.000801, 50.000832, 50.000851, 50.000809, 50.000824, 50.000805, 50.00082, 50.000874, 50.00087, 50.000778, 50.000851, 50.000854, 50.000862, 50.000893, 50.000877, 50.000847, 50.000847, 49.999641, 50.000805, 50.000675, 50.0009, 50.000839, 50.000771, 50.000832, 50.000854, 50.000862, 50.000912, 50.000912, 50.000908, 50.000847, 50.000816, 50.000824, 50.000816, 50.000813, 50.000877, 50.000832, 50.000824, 50.000851, 50.000854, 50.000854, 50.000771, 50.000832, 50.000862, 50.0009, 50.000797, 50.000782, 50.000744, 49.891621, 50.000828, 50.000881, 50.000809, 50.000744, 50.000763, 50.411057, 50.000771, 50.000843, 50.000793, 50.000885, 50.000908, 50.000839, 50.000774, 50.000824, 50.000824, 50.000816, 50.000721, 50.000748, 50.000809, 50.000839, 50.000847, 50.000805, 50.000881, 50.000877, 50.000828, 50.000847, 50.000828, 50.000828, 50.0009, 50.000866, 50.000885, 50.000908, 50.000847, 50.000832, 50.000813, 50.000816, 50.000854, 50.000839, 50.000824, 50.000809, 50.000858, 50.000854, 50.000862, 50.000832, 50.000801, 50.000771, 50.000713, 49.955101, 50.000763, 50.030434, 50.000824, 50.00082, 50.000778, 50.000851, 50.000877, 50.000843, 50.000854, 50.000862, 50.000771, 50.000843, 50.001087, 50.000912, 50.0009, 50.000839, 50.000862, 50.000824, 50.000771, 50.193302, 50.000919, 50.000904, 50.000877, 50.015175, 50.000763, 50.000843, 50.000919, 50.000847, 50.000797, 50.000793, 50.000805, 50.000839, 50.000854, 50.00082, 50.000763, 50.00087, 50.000896, 50.000824, 50.000858, 49.794735, 50.000824, 50.000854, 50.0009, 50.000877, 50.00087, 50.000778, 50.000771, 49.972088, 50.000862, 50.000797, 50.000801, 50.000809, 50.000805, 49.971989, 50.000786, 50.000744, 50.000805, 50.000816, 50.320198, 50.000874, 50.000809, 50.000881, 50.00087, 50.00087, 50.000763, 50.000786, 50.000877, 50.000839, 50.000893, 50.000771, 50.000862, 50.000767, 50.000874, 50.000771, 50.000786, 50.00087, 50.000854, 50.00082, 50.000763, 50.000862, 50.000839, 50.000813, 50.000893, 50.000771, 50.000858, 50.000809, 50.000744, 50.000748, 50.000793, 50.000801, 50.000778, 50.000801, 50.000774, 50.000832, 50.000805, 50.000866, 50.000885, 50.000851, 50.000748, 50.000774, 50.000805, 50.000755, 50.000816, 50.000839, 50.000839, 50.000858, 50.000816, 50.000862, 50.000839, 50.000809, 50.000854, 50.00079, 50.000793, 50.000713, 50.000736, 50.000763, 50.358772, 50.000809, 50.000854, 50.000801, 50.000835, 50.000832, 50.000862, 50.002918, 50.00079, 50.00079, 50.000816, 50.000885, 50.000862, 50.00087, 50.000851, 50.000843, 50.000839, 50.000813, 50.000862, 50.000885, 50.00087, 50.000839, 50.000862, 50.211372, 50.000854, 50.000809, 50.000843, 50.000797, 50.000885, 50.000877, 50.000771, 50.000824, 50.000824, 50.000797, 50.000881, 50.000889, 49.999897, 50.000824, 50.000893, 50.000877, 50.000801, 50.000801, 50.00082, 50.000858, 50.000839, 50.000854, 50.00079, 50.000801, 50.000847, 50.000835, 50.000877, 50.000839, 50.000782, 50.000809, 50.000839, 50.000904, 50.000874, 50.000771, 50.00087, 50.000847, 50.000805, 50.0009, 50.000854, 50.000793, 50.000809, 50.00087, 50.000854, 50.000786, 50.000854, 50.000824, 50.000793, 50.000801, 50.000866, 50.00087, 50.000862, 50.000839, 50.00071, 50.000847, 50.000854, 50.000809, 50.000912, 50.00079, 49.956604, 50.000813, 50.000816, 50.000793, 49.934437, 50.00087, 50.000877, 50.000866, 50.000797, 50.115368, 50.000828, 50.000889, 50.00087, 50.000908, 50.000481, 50.000782, 50.000885, 50.000847, 50.000877, 50.0009, 50.000778, 50.00079, 50.000813, 50.000774, 50.000832, 50.000771, 50.000793, 50.000839, 50.000942, 50.000599, 50.000721, 50.005375, 50.000908, 50.000862, 50.000309, 50.000847, 50.000832, 50.000782, 50.000851, 50.00618, 50.000839, 50.000862, 50.00087, 50.000896, 50.000885, 50.000839, 50.000816, 49.970081, 50.00082, 50.00087, 50.000851, 50.000744, 50.000729, 50.000721, 50.000862, 50.000862, 50.000847, 50.000748, 50.000862, 50.000866, 50.000877, 50.000862, 50.000835, 50.000816, 50.000824, 50.000782, 50.000782, 50.000828, 50.000828, 50.0009, 50.002129, 50.000751, 50.000771, 50.000824, 50.00087, 50.000896, 50.000854, 50.00087, 50.000809, 50.000801, 50.000843, 50.00087, 50.000908, 50.000908, 50.00087, 50.000908, 50.000877, 50.00087, 50.000793, 50.000763, 50.000832, 50.000874, 50.000904, 50.000851, 50.00087, 50.000877, 50.000908, 50.000793, 50.000786, 50.000771, 50.000801, 50.000801, 50.000828, 50.000843, 50.000828, 50.000778, 50.000832, 50.000797, 50.00087, 50.000767, 50.000885, 50.000908, 50.000809, 50.000793, 50.000751, 50.000862, 50.000912, 50.0009, 50.000854, 50.000751, 50.000801, 50.0009, 50.000866, 50.000927, 50.000816, 50.000824, 50.000801, 50.000862, 50.000885, 50.000843, 50.000858, 50.051487, 50.000832, 50.000847, 50.000854, 50.000778, 50.000839, 50.000763, 50.000786, 50.000916, 50.00087, 50.000801, 50.000912, 50.000854, 50.000816, 50.000736, 50.000908, 49.146847, 50.000816, 50.000854, 50.00082, 50.000828, 50.000675, 50.000793, 50.000832, 49.987789, 50.000847, 50.000824, 50.000828, 49.998066, 50.000877, 50.000858, 50.000778, 50.000816, 50.000854, 50.000839, 50.000824, 50.000877, 50.000763, 49.95137, 50.000839, 49.983971], "../../lab-windows/rocof_test_data/rocof_test_sweep_phase_steps_1kHz.bin": [48.000839, 48.000778, 48.000816, 48.000805, 48.000858, 48.000813, 48.00082, 48.011509, 48.065632, 50.824547, 48.168018, 48.21925, 48.270374, 48.321663, 48.372814, 48.424133, 48.47533, 48.526527, 48.577698, 48.628925, 48.680191, 48.731365, 48.782547, 48.833771, 48.884979, 48.936237, 48.987415, 49.038567, 49.089745, 49.141083, 49.192211, 49.243484, 49.294659, 49.345821, 49.39711, 49.448257, 49.499573, 49.550659, 49.601864, 49.653114, 49.7043, 49.755543, 49.806767, 49.85796, 49.909191, 49.960373, 50.011662, 50.062881, 50.113991, 50.165226, 50.216408, 50.267593, 50.318832, 50.37006, 50.42123, 50.472492, 50.523727, 50.574898, 50.626205, 50.677292, 50.728523, 50.779678, 50.830921, 50.882156, 50.933414, 50.984585, 51.035805, 51.086987, 51.138229, 51.189461, 51.240627, 51.29192, 51.343033, 51.394306, 51.445435, 51.496681, 51.547943, 51.59911, 51.650383, 51.701523, 51.752762, 51.803917, 51.85516, 51.906372, 51.9576, 50.49263, 51.95089, 51.899555, 51.848301, 51.7971, 51.745945, 51.694736, 51.643513, 51.592255, 51.541183, 51.489918, 51.438667, 51.387512, 51.336296, 51.285053, 51.233921, 51.182621, 51.131439, 51.08025, 51.029003, 50.977764, 50.92659, 50.875404, 50.824196, 50.773018, 50.721775, 50.670563, 50.61927, 50.568172, 50.516861, 50.465683, 50.414474, 50.363308, 50.312023, 50.260769, 50.209625, 50.158428, 50.107246, 50.056011, 50.004803, 49.95364, 49.902378, 49.851185, 49.799999, 49.748718, 49.697525, 49.646317, 49.595074, 49.543854, 49.49268, 49.441467, 49.390213, 49.339008, 49.287884, 49.236702, 49.185402, 49.134247, 49.082973, 49.031788, 48.980621, 48.92944, 48.878185, 48.827015, 48.775768, 48.724571, 48.673378, 48.622108, 48.570953, 48.519691, 48.468494, 48.417252, 48.366108, 48.314899, 48.263638, 48.21244, 48.161194, 48.109985, 48.05883, 46.785252, 48.052856, 48.103989, 48.155197, 48.206409, 48.257652, 48.308929, 48.360081, 48.411217, 48.46244, 48.513672, 48.564919, 48.616066, 48.667343, 48.718555, 48.769699, 48.820904, 48.872177, 48.923344, 48.974621, 49.025852, 49.077095, 49.12822, 49.179459, 49.230644, 49.28183, 49.333183, 49.384266, 49.435444, 49.486671, 49.537941, 49.58913, 49.64035, 49.691536, 49.742714, 49.793934, 49.845131, 49.896404, 49.947536, 49.998848, 50.050014, 50.101212, 50.152443, 50.203732, 50.254871, 50.306084, 50.357311, 50.408474, 50.459625, 50.510937, 50.562069, 50.613232, 50.664566, 50.715767, 50.766994, 50.818176, 50.869431, 50.920593, 50.971859, 51.022964, 51.074287, 51.125355, 51.176601, 51.227848, 51.278999, 51.33028, 51.381512, 51.432697, 51.483906, 51.535122, 51.586292, 51.637547, 51.688683, 51.739883, 51.791176, 51.842392, 51.893589, 51.944859, 51.821701, 51.963505, 51.912422, 51.861176, 51.809963, 51.758789, 51.7075, 51.656326, 51.605206, 51.553814, 51.502659, 51.451496, 51.400215, 51.349052, 51.297852, 51.246616, 51.195404, 51.144226, 51.093044, 51.041798, 50.990635, 50.939396, 50.888199, 50.836956, 50.785744, 50.734558, 50.68327, 50.632118, 50.580914, 50.529667, 50.478458, 50.427319, 50.37603, 50.324841, 50.273643, 50.222466, 50.171211, 50.120079, 50.068829, 50.017574, 49.966446, 49.915157, 49.863903, 49.812706, 49.761585, 49.710293, 49.659111, 49.607975, 49.556671, 49.505486, 49.454269, 49.403088, 49.351929, 49.300617, 49.249424, 49.198261, 49.14695, 49.095829, 49.044651, 48.993389, 48.942142, 48.890945, 48.839756, 48.78857, 48.737293, 48.686081, 48.634937, 48.583733, 48.532486, 48.481316, 48.43013, 48.378891, 48.327587, 48.276501, 48.225254, 48.174042, 48.122803, 48.071564, 48.01952, 48.039982, 48.091217, 48.142471, 48.193665, 48.2449, 48.296028, 48.347256, 48.398556, 48.449722, 48.500919, 48.552116, 48.603291, 48.654461, 48.705734, 48.756966, 48.808186, 48.859329, 48.910603, 48.961754, 49.013016, 49.06422, 49.115456, 49.166698, 49.217876, 49.269051, 49.320175, 49.371483, 49.422821, 49.473873, 49.525143, 49.576321, 49.627594, 49.67873, 49.72995, 49.781136, 49.832371, 49.883614, 49.934834, 49.985966, 50.037151, 50.088375, 50.13958, 50.1908, 50.242088, 50.293194, 50.344391, 50.395729, 50.446957, 50.498032, 50.549335, 50.600517, 50.651749, 50.70293, 50.754147, 50.805283, 50.856434, 50.907787, 50.958984, 51.01017, 51.061371, 51.112667, 51.163868, 51.215069, 51.266258, 51.317425, 51.36866, 51.419868, 51.471077, 51.522278, 51.573586, 51.624603, 51.675903, 51.727169, 51.778332, 51.82959, 51.880749, 51.931953, 51.983257, 51.976391, 51.925114, 51.874062, 51.822739, 51.771564, 51.720375, 51.669128, 51.617966, 51.566772, 51.515503, 51.464344, 51.413139, 51.361881, 51.310654, 51.259361, 51.208271, 51.157005, 51.105743, 51.054623, 51.00338, 50.952152, 50.900982, 50.8498, 50.798588, 50.747372, 50.696201, 50.644978, 50.593719, 50.542637, 50.49128, 50.440056, 50.388844, 50.337658, 50.286469, 50.235287, 50.184059, 50.132763, 50.081642, 50.030399, 49.979111, 49.927948, 49.876793, 49.825623, 49.774303, 49.723148, 49.671974, 49.620781, 49.569546, 49.518299, 49.467094, 49.415871, 49.364613, 49.313499, 49.262257, 49.211071, 49.159912, 49.10865, 49.057335, 49.006126, 48.954994, 48.903816, 48.8526, 48.801334, 48.750191, 48.698936, 48.647728, 48.596481, 48.545357]}
\ No newline at end of file diff --git a/lab-windows/rocof_test_data.py b/lab-windows/rocof_test_data.py new file mode 100644 index 0000000..ccb19a0 --- /dev/null +++ b/lab-windows/rocof_test_data.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python +# coding: utf-8 + +# # ROCOF test waveform library +# +# This is a re-implementation of the ROCOF test waveforms described in https://zenodo.org/record/3559798 +# +# **This file is exported as a python module and loaded from other notebooks here, so please make sure to re-export when changing it.** + +# In[ ]: + + +import math +import itertools + +import numpy as np +from scipy import signal +from matplotlib import pyplot as plt + + +# In[ ]: + + +def sample_waveform(generator, duration:"s"=10, sampling_rate:"sp/s"=10000, frequency:"Hz"=50): + samples = int(duration*sampling_rate) + phases = np.linspace(0, 2*np.pi, 6, endpoint=False) + omega_t = np.linspace(phases, phases + 2*np.pi*duration*frequency, samples) + fundamental = np.sin(omega_t) + return generator(omega_t, fundamental, sampling_rate=sampling_rate, duration=duration, frequency=frequency).swapaxes(0, 1) + + +# In[ ]: + + +def gen_harmonics(amplitudes, phases=[]): + return lambda omega_t, fundamental, **_: fundamental + np.sum([ + a*np.sin((p if p else 0) + i*omega_t) + for i, (a, p) in enumerate(itertools.zip_longest(amplitudes, phases), start=2) + ], axis=0) + +def test_harmonics(): + return gen_harmonics([0.02, 0.05, 0.01, 0.06, 0.005, 0.05, 0.005, 0.015, 0.005, 0.035, 0.005, 0.003]) + + +# In[ ]: + + +def gen_interharmonic(amplitudes, ih=[], ih_phase=[]): + def gen(omega_t, fundamental, **_): + return fundamental + np.sum([ + a*np.sin(omega_t * ih + (p if p else 0)) + for a, ih, p in itertools.zip_longest(amplitudes, ih, ih_phase) + ], axis=0) + return gen + +def test_interharmonics(): + return gen_interharmonic([0.1], [15.01401], [np.pi]) + + +# In[ ]: + + +def gen_noise(amplitude=0.2, fmax:'Hz'=4.9e3, fmin:'Hz'=100, filter_order=6): + def gen(omega_t, fundamental, sampling_rate, **_): + noise = np.random.normal(0, amplitude, fundamental.shape) + b, a = signal.butter(filter_order, + [fmin, min(fmax, sampling_rate//2-1)], + btype='bandpass', + fs=sampling_rate) + return fundamental + signal.lfilter(b, a, noise, axis=0) + return gen + +def test_noise(): + return gen_noise() + +def test_noise_loud(): + return gen_noise(amplitude=0.5, fmin=10) + + +# In[406]: + + +def gen_steps(size_amplitude=0.1, size_phase=0.1*np.pi, steps_per_sec=1): + def gen(omega_t, fundamental, duration, **_): + n = int(steps_per_sec * duration) + indices = np.random.randint(0, len(omega_t), n) + amplitudes = np.random.normal(1, size_amplitude, (n, 6)) + phases = np.random.normal(0, size_phase, (n, 6)) + amplitude = np.ones(omega_t.shape) + for start, end, a, p in zip(indices, indices[1:], amplitudes, phases): + omega_t[start:end] += p + amplitude[start:end] = a + return amplitude*np.sin(omega_t) + return gen + +def test_amplitude_steps(): + return gen_steps(size_amplitude=0.4, size_phase=0) + +def test_phase_steps(): + return gen_steps(size_amplitude=0, size_phase=0.1) + +def test_amplitude_and_phase_steps(): + return gen_steps(size_amplitude=0.2, size_phase=0.07) + + +# In[418]: + + +def step_gen(shape, stdev, duration, steps_per_sec=1.0, mean=0.0): + samples, channels = shape + n = int(steps_per_sec * duration) + indices = np.random.randint(0, samples, n) + phases = np.random.normal(mean, stdev, (n, 6)) + amplitude = np.ones((samples, channels)) + out = np.zeros(shape) + for start, end, a in zip(indices, indices[1:], amplitude): + out[start:end] = a + return out + +def gen_chirp(fmin, fmax, period, dwell_time=1.0, amplitude=None, phase_steps=None): + def gen(omega_t, fundamental, sampling_rate, duration, **_): + samples = int(duration*sampling_rate) + phases = np.linspace(0, 2*np.pi, 6, endpoint=False) + + c = (fmax-fmin)/period + t = np.linspace(0, duration, samples) + + x = np.repeat(np.reshape(2*np.pi*fmin*t, (-1,1)), 6, axis=1) + data = (phases + x)[:int(sampling_rate*dwell_time)] + current_phase = 2*np.pi*fmin*dwell_time + direction = 'up' + + for idx in range(int(dwell_time*sampling_rate), samples, int(2*period*sampling_rate)): + t1 = np.linspace(0, period, int(period*sampling_rate)) + t2 = np.linspace(0, period, int(period*sampling_rate)) + chirp_phase = np.hstack(( + 2*np.pi*(c/2 * t1**2 + fmin * t1), + 2*np.pi*(-c/2 * t2**2 + fmax * t2 - (c/2 * period**2 + fmin * period)) + )) + chirp_phase = np.repeat(np.reshape(chirp_phase, (-1, 1)), 6, axis=1) + new = phases + chirp_phase + current_phase + current_phase = chirp_phase[-1] + data = np.vstack((data, new)) + + data = data[:len(fundamental)] + + if phase_steps: + (step_amplitude, steps_per_sec) = phase_steps + steps = step_gen(data.shape, step_amplitude, duration, steps_per_sec) + data += steps + + if amplitude is None: + return np.sin(data) + else: + return fundamental + amplitude*np.sin(data) + return gen + +def test_close_interharmonics_and_flicker(): + return gen_chirp(90.0, 150.0, 10, 1, amplitude=0.1) + +def test_off_frequency(): +# return gen_chirp(48.0, 52.0, 0.25, 1) + return gen_chirp(48.0, 52.0, 10, 1) + +def test_sweep_phase_steps(): + return gen_chirp(48.0, 52.0, 10, 1, phase_steps=(0.1, 1)) +# return gen_chirp(48.0, 52.0, 0.25, 1, phase_steps=(0.1, 1)) + + +# In[ ]: + + +all_tests = [test_harmonics, test_interharmonics, test_noise, test_noise_loud, test_amplitude_steps, test_phase_steps, test_amplitude_and_phase_steps, test_close_interharmonics_and_flicker, test_off_frequency, test_sweep_phase_steps] + diff --git a/lab-windows/rocof_test_data/rocof_test_amplitude_and_phase_steps_1kHz.bin b/lab-windows/rocof_test_data/rocof_test_amplitude_and_phase_steps_1kHz.bin Binary files differnew file mode 100644 index 0000000..008a752 --- /dev/null +++ b/lab-windows/rocof_test_data/rocof_test_amplitude_and_phase_steps_1kHz.bin diff --git a/lab-windows/rocof_test_data/rocof_test_amplitude_steps_1kHz.bin b/lab-windows/rocof_test_data/rocof_test_amplitude_steps_1kHz.bin Binary files differnew file mode 100644 index 0000000..0240e23 --- /dev/null +++ b/lab-windows/rocof_test_data/rocof_test_amplitude_steps_1kHz.bin diff --git a/lab-windows/rocof_test_data/rocof_test_close_interharmonics_and_flicker_1kHz.bin b/lab-windows/rocof_test_data/rocof_test_close_interharmonics_and_flicker_1kHz.bin Binary files differnew file mode 100644 index 0000000..6633639 --- /dev/null +++ b/lab-windows/rocof_test_data/rocof_test_close_interharmonics_and_flicker_1kHz.bin diff --git a/lab-windows/rocof_test_data/rocof_test_harmonics_1kHz.bin b/lab-windows/rocof_test_data/rocof_test_harmonics_1kHz.bin Binary files differnew file mode 100644 index 0000000..c57fc34 --- /dev/null +++ b/lab-windows/rocof_test_data/rocof_test_harmonics_1kHz.bin diff --git a/lab-windows/rocof_test_data/rocof_test_interharmonics_1kHz.bin b/lab-windows/rocof_test_data/rocof_test_interharmonics_1kHz.bin Binary files differnew file mode 100644 index 0000000..ab0b9e2 --- /dev/null +++ b/lab-windows/rocof_test_data/rocof_test_interharmonics_1kHz.bin diff --git a/lab-windows/rocof_test_data/rocof_test_noise_1kHz.bin b/lab-windows/rocof_test_data/rocof_test_noise_1kHz.bin Binary files differnew file mode 100644 index 0000000..c59cf96 --- /dev/null +++ b/lab-windows/rocof_test_data/rocof_test_noise_1kHz.bin diff --git a/lab-windows/rocof_test_data/rocof_test_noise_loud_1kHz.bin b/lab-windows/rocof_test_data/rocof_test_noise_loud_1kHz.bin Binary files differnew file mode 100644 index 0000000..58ab5b6 --- /dev/null +++ b/lab-windows/rocof_test_data/rocof_test_noise_loud_1kHz.bin diff --git a/lab-windows/rocof_test_data/rocof_test_off_frequency_1kHz.bin b/lab-windows/rocof_test_data/rocof_test_off_frequency_1kHz.bin Binary files differnew file mode 100644 index 0000000..a4f128e --- /dev/null +++ b/lab-windows/rocof_test_data/rocof_test_off_frequency_1kHz.bin diff --git a/lab-windows/rocof_test_data/rocof_test_phase_steps_1kHz.bin b/lab-windows/rocof_test_data/rocof_test_phase_steps_1kHz.bin Binary files differnew file mode 100644 index 0000000..2faebce --- /dev/null +++ b/lab-windows/rocof_test_data/rocof_test_phase_steps_1kHz.bin diff --git a/lab-windows/rocof_test_data/rocof_test_sweep_phase_steps_1kHz.bin b/lab-windows/rocof_test_data/rocof_test_sweep_phase_steps_1kHz.bin Binary files differnew file mode 100644 index 0000000..6c73b99 --- /dev/null +++ b/lab-windows/rocof_test_data/rocof_test_sweep_phase_steps_1kHz.bin diff --git a/lab-windows/scratch.ipynb b/lab-windows/scratch.ipynb new file mode 100644 index 0000000..b35c76d --- /dev/null +++ b/lab-windows/scratch.ipynb @@ -0,0 +1,167 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "\n", + "import numpy as np\n", + "from matplotlib import pyplot as plt\n", + "import matplotlib" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib widget" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "712481c28d9d4e1d874a66d31c3e8bff", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "(0, 64)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "a = np.array([-00.000732, -00.000352, -00.000666, -00.000202, -00.000706, -00.000006, -00.000597, -00.002039, 000.050663, -00.644566, 004.456614, -16.817095, 034.654587, -39.021217, 024.007816, -08.070650, 001.478795, -00.150260, 000.006110, -00.002328, -00.002322, -00.002426, -00.002177, -00.002452, -00.002333, -00.002438, -00.002342, -00.002396, -00.001979, -00.003049, -00.001720, -00.002686, -00.002168, -00.002507, -00.001868, -00.002899, -00.002017, -00.001952, -00.003255, -00.001080, -00.003335, -00.001575, -00.002704, -00.001872, -00.002735, -00.001983, -00.002191, -00.002478, -00.002155, -00.002203, -00.002328, -00.002206, -00.002443, -00.001770, -00.002718, -00.002004, -00.002378, -00.002112, -00.002122, -00.002691, -00.001679, -00.002690, -00.001946, -00.002232])\n", + "b = np.array([-00.002734, -00.001325, -00.002220, -00.003693, -00.004907, -00.006454, -00.007737, 000.004823, -00.363143, 004.688968, -33.795303, 130.992630, -274.092651, 309.377991, -188.427826, 061.912941, -10.974002, 001.053608, -00.048927, 000.007710, 000.007010, 000.006493, 000.007234, 000.006725, 000.006938, 000.006694, 000.006356, 000.006173, 000.006333, 000.005684, 000.005697, 000.005575, 000.005101, 000.005693, 000.004319, 000.005344, 000.004673, 000.003566, 000.006213, 000.002719, 000.004850, 000.003755, 000.004243, 000.003419, 000.003960, 000.003498, 000.003297, 000.003877, 000.002836, 000.003487, 000.003144, 000.002824, 000.003355, 000.002528, 000.002975, 000.003012, 000.002137, 000.003112, 000.002416, 000.002512, 000.002084, 000.003008, 000.001837, 000.002351])\n", + "ax.plot([3.906250*i for i in range(len(a))], np.sqrt(a**2 + b**2))\n", + "a2 = ax.twiny()\n", + "a2.set_xlim([0, len(a)])" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d4024377df494eac935fd487026edc8b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x7f2eb410f280>]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "d = [50.000839,50.000839,50.000832,50.000824,50.000839,50.000832,50.000839,50.000824,50.000847,50.000824,50.000824,50.000839,50.000832,50.000839,50.000824,50.000824,50.000839,50.000824,50.000824,50.000835,50.000816,50.000832,50.000847,50.000832,50.000835,50.000824,50.000824,50.000832,50.000832,50.000843,50.000824,50.000832,50.000832,50.000832,50.000828,50.000832,50.000832,50.000824,50.000816,50.000835,50.000843,50.000824,50.000824,50.000832,50.000832,50.000847,50.000824,50.000824,50.000824,50.000835,50.000835,50.000851,50.000824,50.000824,50.000832,50.000828,50.000828,50.000824,50.000832,50.000835,50.000835,50.000832,50.000847,50.000824,50.000832,50.000839,50.000839,50.000824,50.000832,50.000832,50.000832,50.000835,50.000816,50.000820,50.000824,50.000832,50.000824,50.000832,50.000835,50.000832,50.000816,50.000820,50.000839,50.000839,50.000824,50.000839,50.000820,50.000820,50.000839,50.000832,50.000835,50.000828,50.000824,50.000839,50.000839,50.000839,50.000816,50.000832,50.000824,50.000832,50.000832,50.000839,50.000824,50.000832,50.000828,50.000832,50.000828,50.000835,50.000832,50.000843,50.000839,50.000820,50.000832,50.000835,50.000824,50.000824,50.000828,50.000820,50.000820,50.000828,50.000832,50.000832,50.000828,50.000835,50.000839,50.000820,50.000832,50.000832,50.000824,50.000832,50.000832,50.000839,50.000839,50.000816,50.000828,50.000832,50.000839,50.000824,50.000824,50.000824,50.000835,50.000824,50.000832,50.000839,50.000835,50.000832,50.000828,50.000835,50.000828,50.000828,50.000824,50.000824,50.000839,50.000832,50.000824,50.000832,50.000832,50.000820,50.000851,50.000824,50.000824,50.000839,50.000824,50.000839,50.000832,50.000835,50.000820,50.000832,50.000839,50.000832,50.000832,50.000824,50.000832,50.000824,50.000832,50.000839,50.000839,50.000832,50.000816,50.000835,50.000854,50.000824,50.000816,50.000832,50.000832,50.000835,50.000816,50.000832,50.000824,50.000832,50.000832,50.000832,50.000824,50.000832,50.000824,50.000835,50.000832,50.000835,50.000832,50.000832,50.000828,50.000839,50.000824,50.000839,50.000824,50.000824,50.000839,50.000816,50.000839,50.000816,50.000832,50.000839,50.000839,50.000832,50.000824,50.000832,50.000820,50.000824,50.000835,50.000824,50.000835,50.000832,50.000824,50.000824,50.000820,50.000839,50.000816,50.000832,50.000832,50.000832,50.000824,50.000847,50.000824,50.000839]\n", + "\n", + "ax.plot(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "with open('impl_test_out.json') as f:\n", + " impl_measurements = json.load(f)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "dd23cf23221e4e14aaafdd58bb9416d9", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axs = plt.subplots(len(impl_measurements), figsize=(8, 20), sharex=True)\n", + "fig.tight_layout()\n", + "axs = axs.flatten()\n", + "\n", + "for (label, data), ax in zip(impl_measurements.items(), axs):\n", + " ax.set_title(label)\n", + " ax.plot(data[1:-1])\n", + " mean = np.mean(data[1:-1])\n", + " rms = np.sqrt(np.mean(np.square(data[1:-1] - mean)))\n", + " ax.text(0.2, 0.2, f'mean={mean:.3}Hz, rms={rms*1e3:.3}mHz', ha='center', va='center', transform=ax.transAxes,\n", + " bbox=dict(boxstyle=\"square\", ec=(0,0,0,0), fc=(1,1,1,0.8)))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "labenv", + "language": "python", + "name": "labenv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} |