-
Gabriel Fedel authored
Instead of define one (now it is now possible to define a new one)
Gabriel Fedel authoredInstead of define one (now it is now possible to define a new one)
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
testFilters.py 5.29 KiB
#!/usr/bin/env python3
import unittest
import time
from math import exp, cos, sin, pi, nan
from glob import glob
from os import system, popen, environ
from random import random, randint
BASE_BOARD="/dev/sis8300"
REG_NOTCH1="0x43f"
REG_NOTCH2="0x440"
REG_NOTCH3="0x441" # enable/disable
REG_LP1="0x442"
REG_LP2="0x443"
REG_LP3="0x444" # enable/disable
PV_NOTCH_FREQ=":NOTCHFIL-FREQ"
PV_NOTCH_BWIDTH=":NOTCHFIL-BWIDTH"
PV_NOTCH_EN=":NOTCHFIL-EN"
PV_LP_EN=":CAVLPFIL-EN"
PV_LP_CUTOFF=":CAVLPFIL-CUTOFF"
PV_F_SAMP=":F-SAMPLING"
PV_N=":IQSMPL-NEARIQN"
def getNumBoard(b):
"""Get then number of a board string"""
return int(b.split("-")[1])
def getBoard(n = 0):
"""Return the path to board on system"""
boards = (glob(BASE_BOARD + "*"))
boards.sort(key=getNumBoard)
return (boards[n])
def readReg(board, reg):
p = popen("sis8300drv_reg %s %s" % (board, reg))
ret = p.read().split("\n")[0]
p.close()
return ret
def float2Qmn(val, m, n, signed):
pow_2_frac_bits = float(0x1 << n)
pow_2_frac_bits_int_bits = float(0x1 << (m + n))
val_int64 = int(val * pow_2_frac_bits)
# Check if signed
if (signed):
if (val_int64 < 0):
val_int64 += int(pow_2_frac_bits_int_bits)
# check upper limit of signed int
elif (val_int64 > (pow_2_frac_bits_int_bits / 2.0 - 1.0)):
return nan
if (val_int64 >> m + n):
return nan
return val_int64
def getFSamp(pv):
p = popen("caget -t -f 12 %s" % (pv))
fsamp = p.read().split("\n")[0]
p.close()
return float(fsamp)
class TestLowPass(unittest.TestCase):
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
self.board = getBoard()
self.PV = environ.get("LLRF_IOC_NAME") + "1"
def calc_consts(self, cutoff, fsamp, n):
omg0 = 2*pi*cutoff
h = 1/(fsamp/n)
constA = round(-exp(-omg0*h), 12)
constB = round(1 - exp(-omg0*h), 12)
return [constA, constB]
def test_enable(self):
"""Test Low Pass filter enable/disable"""
system("caput %s %f > /dev/null" % (self.PV + PV_LP_EN, 1))
res = readReg(self.board, REG_LP3)
self.assertEqual(res, "0x1")
system("caput %s %f > /dev/null" % (self.PV + PV_LP_EN, 0))
res = readReg(self.board, REG_LP3)
self.assertEqual(res, "0x0")
def test_randValues(self):
"""Test Low Pass filter with random values"""
cutoff = random()*10
n = float(randint(1,10))
fsamp = getFSamp(self.PV + PV_F_SAMP)
system("caput %s %f > /dev/null" % (self.PV + PV_LP_CUTOFF, cutoff))
system("caput %s %f > /dev/null" % (self.PV + PV_N, n))
res = self.calc_consts(cutoff, fsamp, n)
a = float2Qmn(res[0], 1, 15, 1)
self.assertNotEqual(a, nan)
b = float2Qmn(res[1], 1, 15, 1)
self.assertNotEqual(b, nan)
a = hex(a)
b = hex(b)
reg1 = readReg(self.board, REG_LP1)
self.assertEqual(str(a), reg1)
reg2 = readReg(self.board, REG_LP2)
self.assertEqual(str(b), reg2)
class TestNotch(unittest.TestCase):
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
self.board = getBoard()
# TODO: after fix LLRF_IOC_NAME change this
self.PV = environ.get("LLRF_IOC_NAME") + "1"
# calculate and return constants from Notch
def calc_consts(self, bd, freq, fsamp, n):
h = 1/(fsamp/n);
omg0 = 2*pi*freq;
xi0 = bd/(2*freq);
areal = round(exp(-(xi0*omg0*h))*cos(omg0*h), 12)
aimag = round(exp(-(xi0*omg0*h))*sin(omg0*h), 12)
breal = round((1-exp(-(xi0*omg0*h)))*cos(omg0*h), 12)
bimag = round((1-exp(-(xi0*omg0*h)))*sin(omg0*h), 12)
return([areal, aimag, breal, bimag])
def test_randValues(self):
"""Test Notch filter with random values"""
freq = random()*10
bwidth = random()*10
n = float(randint(1,10))
fsamp = getFSamp(self.PV + PV_F_SAMP)
system("caput %s %f > /dev/null" % (self.PV + PV_NOTCH_FREQ, freq))
system("caput %s %f > /dev/null" % (self.PV + PV_NOTCH_BWIDTH, bwidth))
system("caput %s %f > /dev/null" % (self.PV + PV_N, n))
res = self.calc_consts(bwidth, freq, fsamp, n)
areal = float2Qmn(res[0], 1, 15, 1)
self.assertNotEqual(areal, nan)
aimag = float2Qmn(res[1], 1, 15, 1)
self.assertNotEqual(aimag, nan)
breal = float2Qmn(res[2], 1, 15, 1)
self.assertNotEqual(breal, nan)
bimag = float2Qmn(res[3], 1, 15, 1)
self.assertNotEqual(bimag, nan)
reg1exp = hex((areal << 16) | aimag)
reg2exp = hex((breal << 16) | bimag)
reg1 = readReg(self.board, REG_NOTCH1)
self.assertEqual(str(reg1exp), reg1)
reg2 = readReg(self.board, REG_NOTCH2)
self.assertEqual(str(reg2exp), reg2)
def test_enable(self):
"""Test Notch filter enable/disable"""
system("caput %s %f > /dev/null" % (self.PV + PV_NOTCH_EN, 1))
res = readReg(self.board, REG_NOTCH3)
self.assertEqual(res, "0x1")
system("caput %s %f > /dev/null" % (self.PV + PV_NOTCH_EN, 0))
res = readReg(self.board, REG_NOTCH3)
self.assertEqual(res, "0x0")
if __name__ == "__main__":
unittest.main(verbosity=2)