def test_debug(self): m = Monitor("test/test_py-monitor-simple.pl", 'x') # check callback invocation class Callback(object): def __init__(self): self.called = False def callback(self, itoms, outputs, error, failed): self.called = True c = Callback() m.set_debug_callback(c.callback) m.monitor(self.__itoms2) self.assertTrue(c.called) # check variables we get for debugging def clbk(itoms, outputs, error, failed): self.assertEqual(self.__itoms2, itoms) self.assertEqual(len(outputs), 3) self.assertEqual(len(error), 3) # error for each substitution self.assertEqual(sum(error), 0) # no error m.set_debug_callback(clbk) m.monitor(self.__itoms2)
def test_monitor(self): m = Monitor("test/test_py-monitor-simple.pl", 'x') failed = m.monitor(self.__itoms1) self.assertEqual(len(m.substitutions), 6) self.assertTrue(failed in m.substitutions) self.assertTrue('d1' in [v.name for v in failed.vin]) # interval itoms # recollect substitutions failed = m.monitor(self.__itoms2) self.assertEqual(len(m.substitutions), 3) self.assertEqual(failed, None) # erroneous failed = m.monitor(self.__itoms2_err) self.assertTrue('d1' in [v.name for v in failed.vin])
def __init__(self, model, variable, uncertainty=None, buffer_size=1): # hard-coded path to prolog shsa library -> use docker image! self.__monitor = SHSAMonitor( model, variable, librarypaths=["/python_ws/shsa-prolog/model"], recollect=False, uncertainty=uncertainty, buffer_size=buffer_size) self.__monitor.set_debug_callback(self.__debug_callback)
def test_time_uncertainty(self): m = Monitor("test/test_py-monitor-simple.pl", 'x') # itoms with uncertainties in time iok = Itoms([ Itom('x1', interval([9, 11]), timestamp=interval([0.1, 0.2]), variable='x'), Itom('a1', interval([5, 6]), timestamp=interval([0.15, 0.25]), variable='a'), Itom('b1', interval([4, 8]), timestamp=interval([0.1, 0.3]), variable='b'), ]) failed = m.monitor(iok) self.assertEqual(failed, None) # some itoms timestamps do not overlap ilate = Itoms([ Itom('x1', interval([9, 11]), timestamp=interval([0.0, 0.09]), variable='x'), Itom('a1', interval([5, 6]), timestamp=interval([0.15, 0.25]), variable='a'), Itom('b1', interval([4, 8]), timestamp=interval([0.1, 0.3]), variable='b'), ]) failed = m.monitor(ilate) self.assertEqual(failed, None)
def test_init_monitor(self): # minimal initialization m = Monitor("test/test_py-monitor-simple.pl", 'x') self.assertTrue("function(x, r1, [a])." in m.model) self.assertEqual(m.domain, 'x') self.assertEqual(m.substitutions, None) # update model and domain m.update("test/test_py-implementation-multiline.pl", 'a') self.assertTrue("function(a, r1, [b])." in m.model) self.assertEqual(m.domain, 'a') # init with itoms m = Monitor("test/test_py-monitor-simple.pl", 'x', itoms=self.__itoms1) self.assertNotEqual(m.substitutions, None) self.assertEqual(len(m.substitutions), 6) # static availability (itomsOf are part of the model) m = Monitor("test/test_py-monitor-static.pl", 'x') self.assertNotEqual(m.substitutions, None) self.assertEqual(len(m.substitutions), 3)
def test_monitor_filter(self): # trigger error after the second error in succession m = Monitor("test/test_py-monitor-simple.pl", 'x', median_filter_window_size=3) failed = m.monitor(self.__itoms2) self.assertEqual(failed, None) failed = m.monitor(self.__itoms2) self.assertEqual(failed, None) failed = m.monitor(self.__itoms2_err) self.assertEqual(failed, None) failed = m.monitor(self.__itoms2_err) self.assertNotEqual(failed, None)
def test_timestamp_model(self): m = Monitor("test/test_py-monitor-timestamp-simple.pl", 'c') self.assertEqual(m.buffer_size, 1) a1 = Itom('a1', 1, interval([0.11, 0.21]), variable='a') b1 = Itom('b1', 2, interval([0.12, 0.22]), variable='b') c1 = Itom('c1', 3, interval([0.05, 0.15]), variable='c') c2 = Itom('c2', 3, interval([0.14, 0.24]), variable='c') failed = m.monitor(Itoms([a1, b1, c1, c2])) self.assertEqual(failed, None) # wrong value, however time stamp do not overlap -> won't be used for comparison c1_late = Itom('c1', 0, interval([0.0, 0.04]), variable='c') failed = m.monitor(Itoms([a1, b1, c1_late, c2])) self.assertEqual(failed, None) # monitor shall compensate late itoms -> increase buffer size m = Monitor("test/test_py-monitor-timestamp-simple.pl", 'c', buffer_size=2) self.assertEqual(m.buffer_size, 2) failed = m.monitor(Itoms([c1, c2])) failed = m.monitor(Itoms([c1_late, c2])) # another late value but wrong itom arrives c2_wrong = Itom('c2', 1, interval([0.0, 0.03]), variable='c') failed = m.monitor(Itoms([c1, c2_wrong])) self.assertNotEqual(failed, None)
class Emulator(object): """Emulates monitor_node.py""" def __init__(self, model, variable, uncertainty=None, buffer_size=1): # hard-coded path to prolog shsa library -> use docker image! self.__monitor = SHSAMonitor( model, variable, librarypaths=["/python_ws/shsa-prolog/model"], recollect=False, uncertainty=uncertainty, buffer_size=buffer_size) self.__monitor.set_debug_callback(self.__debug_callback) @property def monitor(self): """Returns the monitor.""" return self.__monitor def collect_inputs(self, itoms, period, t_start=0): """Collects itoms for monitor steps with given period (in same unit as timestamps of the itoms, e.g., nsec). Simulates the reception of itoms between two monitor steps. """ # collect itoms per period inputs = [] # all steps to execute step = [] # itoms for current monitor step for n, (tr, itom) in enumerate(itoms): # period over -> start next monitor step if tr > t_start + (len(inputs) + 1) * period: inputs.append((t_start + (len(inputs) + 1) * period, step)) # reset for next step step = [] step.append(itom) print "[run] number of steps: {}".format(len(inputs)) return inputs def __debug_callback(self, inputs, outputs, error, failed): self.__debug = { 'inputs': inputs, 'outputs': [{ 'sidx': sidx, 't': o.t, 'v': o.v } for sidx, o in outputs], 'error': error, } def __step(self, itoms): """Execute a monitor step.""" failed = self.__monitor.monitor(itoms) # failed substitution to index try: failed_idx = self.__monitor.substitutions.index(failed) except ValueError as e: failed_idx = -1 # add to debug output self.__debug['failed_idx'] = failed_idx return self.__debug def run(self, data): inputs = data['inputs'] # run monitor for each Itoms in inputs outputs = [] print "[run] ..." for n, (t, itoms) in enumerate(inputs): # execute monitor output = self.__step(itoms) output['tm'] = t outputs.append(output) print "[run] done." return outputs
def main(argv): args = [ 'width=', 'height=', 'screen=', 'dist=', 'xtiles=', 'ytiles=', 'indir=', 'outdir=', 'file=', 'hertz=', 'sfdegree=', 'sfcutoff=', 'dfdegree=', 'dfwidth=', 'vt=', 'baselineT=', 'endT=', 'smooth=', 'proximity=' ] try: opts, args = getopt.getopt(argv, '', args) except getopt.GetoptError as e: print(e, file=sys.stderr) usage() return exit(1) # initialize vars to None width = height = screen = dist = xtiles = ytiles = indir = outdir = file = hertz = sfdegree = sfcutoff = dfdegree = dfwidth = vt = baseline_t = end_t = smooth = proximity = None # parse args into vars for opt, arg in opts: opt = opt.lower() if opt != '--file': arg = arg.lower() if opt == '--width': width = arg elif opt == '--height': height = arg elif opt == '--screen': screen = float(arg) elif opt == '--dist': dist = float(arg) elif opt == '--xtiles': xtiles = int(arg) elif opt == '--ytiles': ytiles = int(arg) elif opt == '--indir': indir = arg elif opt == '--outdir': outdir = arg elif opt == '--file': file = arg elif opt == '--hertz': hertz = float(arg) elif opt == '--sfdegree': sfdegree = float(arg) elif opt == '--sfcutoff': sfcutoff = float(arg) elif opt == '--dfdegree': dfdegree = float(arg) elif opt == '--dfwidth': dfwidth = float(arg) elif opt == '--vt': vt = float(arg) elif opt == '--baselinet': baseline_t = float(arg) elif opt == '--endt': end_t = float(arg) elif opt == '--smooth': if arg == 'true': smooth = True elif arg.lower() == 'false': smooth = False else: raise Exception("Invalid arg for --smooth.") elif opt == '--proximity': if arg == 'true': proximity = True elif arg.lower() == 'false': proximity = False else: raise Exception("Invalid arg for --proximity") # (default) differentiation (SG) filter parameters: width, degree, order if dfwidth is None and dfdegree is None: if smooth: dfwidth = 3 dfdegree = 2 else: dfwidth = 5 dfdegree = 3 dfo = 1 # (default) smoothing (Butterworth) filter parameters: degree, cutoff if sfdegree is None: sfdegree = 3 if sfcutoff is None and hertz is not None: sfcutoff = 1.0 / hertz # must be 0 < Wn < 1 if None in [ width, height, screen, dist, xtiles, ytiles, indir, outdir, hertz, sfdegree, sfcutoff, dfdegree, dfwidth, vt, baseline_t, end_t, smooth, proximity ]: print("Some args are not initialized", file=sys.stderr) return exit(1) # get .csv input files to process if os.path.isdir(indir): files = glob.glob('%s/*.csv' % indir) else: files = [] # if user specified --file="..." then we use that as the only one to process if file is not None: file = indir + file if os.path.isfile(file): files = [file] print("overriding files with: ", files) # declare monitor monitor = Monitor(int(width), int(height), screen, dist) # model loop, we iterate over .csv files for file in files: # don't process empty files if os.path.getsize(file) == 0: continue # base = os.path.basename(file) path, base = os.path.split(file) print("Processing: ", file, "[", base, "]") # split filename from extension filename, ext = os.path.splitext(base) print("path: %s, base: %s, filename: %s, ext: %s" % (path, base, filename, ext)) # removed for file naming flexibility # subj = filename.split('-')[0] # group = filename.split('-')[1] # block = filename.split('-')[2] # task = filename.split('-')[3] typ = filename.rsplit('-')[-1] # print("subj: %s, group: %s, block: %s, task: %s" % (subj, group, block, task)) process = Process(width, height, screen, dist, hertz) process.parse_file(file) process.smooth(sfdegree, sfcutoff, smooth) process.differentiate(dfwidth, dfdegree, dfo) process.threshold(vt, monitor, typ, proximity) process.write_threshold_to_file("%s/%s-fxtn%s" % (outdir, filename, ".csv")) del process
def test_monitor_with_delay_model(self): m = Monitor("test/test_py-monitor-delay-simple.pl", 'x') # delayed step function (x1 is slower than a1) i0 = Itoms([Itom('a1', 0, variable='a'), Itom('x1', 0, variable='x')]) i1 = Itoms([Itom('a1', 1, variable='a'), Itom('x1', 0, variable='x')]) i2 = Itoms([Itom('a1', 1, variable='a'), Itom('x1', 1, variable='x')]) failed = m.monitor(i0) self.assertEqual(failed, None) failed = m.monitor(i0) self.assertEqual(failed, None) failed = m.monitor(i1) self.assertEqual(failed, None) # x1 (value is still 0) doesn't follow a1 (v=1) failed = m.monitor(i1) self.assertNotEqual(failed, None) failed = m.monitor(i2) self.assertEqual(failed, None) # delay = 2 timesteps m = Monitor("test/test_py-monitor-delay-general.pl", 'x') failed = m.monitor(i0) self.assertEqual(failed, None) failed = m.monitor(i0) self.assertEqual(failed, None) failed = m.monitor(i1) self.assertEqual(failed, None) failed = m.monitor(i1) self.assertEqual(failed, None) failed = m.monitor(i1) self.assertNotEqual(failed, None) failed = m.monitor(i2) self.assertEqual(failed, None)