# -*- coding: utf-8 -*- import logging import time from datetime import datetime from collections import defaultdict import string from utils.xml import StringToTree, TreeToFile, subelement, FileToTree from utils import pos2rgb import cPickle as pickle import scipy import simulate import evaluate import plotter log = logging.getLogger('lws') BASE = ''' %(js)s %(body)s ''' def render(js=None, **kwargs): # prepare js definitions - optionally add a file given by @param js s = '' jsfiles = ['jquery-1.7.1.min.js', 'main.js', 'loco.js'] if isinstance(js, basestring): jsfiles.append(js) elif isinstance(js, (list, tuple)): jsfiles.extend(js) jsdefs = [s % f for f in jsfiles] data = defaultdict(str) data.update(kwargs) data['js'] = '\n '.join(jsdefs) return BASE % data def renderView(lws, station): trs = [] for mac, cfg in sorted(lws.mac2cfg.items(), key=lambda e: e[1].name): ap_css_id = cfg['mac'].replace(':', '_') tr = ''' %s ''' % (ap_css_id, cfg.name) trs.append(tr) s = '' for i in range(-100, -10): rgb = pos2rgb(120+i, 100, spread=0.35, saturation=0.45) s += '%s' % (i, rgb) rgbvals = '
%s
' % s body = ''' %s
AP Mean Sigma^2 clear!History
''' % ('view2', station.name, rgbvals, '\n'.join(trs)) return render(body=body) def getLastMeasurementRuns(lws, station, count): runs = [] #~ print station, len(lws.stored_measurements[station]) for locid in lws.stored_measurements[station]: ll = lws.stored_measurements[station][locid] # list of tuples (datetime, run dict) runs.extend([(e[0], e[1], locid) for e in ll]) return [(e[1], e[2]) for e in list(sorted(runs))[-count:]] def renderMeasure(lws, station): trs = [] locid_tds = '' if station is not None: lastruns = getLastMeasurementRuns(lws, station.name, 5) for ssid, mac, values in sorted((ssid, mac, values) for (mac, ssid), values in station.data.items()): rssi = values[-1].rssi delta = values[-1].delta try: apid = lws.mac2cfg[mac].name except Exception: apid = '?' continue avg_rssis_tds = '' for rssis, locid in lastruns: if mac in rssis: avg_rssi = '%.1f' % (sum(rssis[mac]) / float(len(rssis[mac]))) else: avg_rssi = '' avg_rssis_tds += '%s' % avg_rssi tr = ''' %s %s/%s %s %s %s ''' % (mac.replace(':', '_'), apid, ssid[:6], mac[-6:], rssi, delta, avg_rssis_tds) trs.append(tr) for _, locid in lastruns: locid_tds += 'loc%s' % locid activity_table = ''' %s %s
ID AccessPoint RSSI Delta
''' % (locid_tds, '\n'.join(trs)) body = '''
locid
duration
startts n/a
endts n/a
%s
''' % ('measure', station.name if station is not None else 'UNKNOWN', activity_table) return render(body=body) def renderIndex(lws): body = '

%s known mobile stations:

' % len(lws.config['knownStations']) body += 'all measurements' for station in lws.config['knownStations']: body += '''

%(station)s:

view measure collect path evaluate build optfile localize ''' % {'station': station} body += '''
''' return render(body=body) def renderLocate(lws, station): LAST_N = 3 avg_rssis = {} trs = [] for (mac, ssid), values in station.data.items(): if not mac in lws.mac2cfg: continue apid = lws.mac2cfg[mac].name apinfos = values[-LAST_N:] avg_rssi = sum(e.rssi for e in apinfos) / float(len(apinfos)) tr = ''' %s %s/%s %.1f ''' % (mac.replace(':', '_'), apid, ssid[:6], mac, avg_rssi) trs.append(tr) body = ''' %s
ID AccessPoint RSSI
''' % ('locate', station.name, '\n'.join(trs)) return render(body=body) def renderCluster(lws): worker_trs = [] for wname, worker in sorted(lws.simulator.workers.items()): total = sum(worker.durations) avg = total / len(worker.durations) if total > 0 else 0 num_per_hour = worker.jobcount / (total / 3600) if total > 0 else 0 color = 'green' if worker.active else 'red' available_hours = (time.time() - worker.firstseen) / 3600 active_hours = worker.jobcount * avg / 3600 tr = '''   %s %s %s %.1f %.0f %.2f %.2f %.1f ''' % (color, wname, worker.jobcount, worker.failurecount, avg, num_per_hour, active_hours, available_hours, active_hours / available_hours * 100) worker_trs.append(tr) knownruns = simulate.Run.known waiting, running, finished = lws.simulator.queryRuns(set(knownruns.keys())) waiting_trs = [] for runid in waiting: run = knownruns[runid] tr = ''' %s %.1f ''' % (run.id, time.time() - run.qts) waiting_trs.append(tr) running_trs = [] for runid in running: run = knownruns[runid] tr = ''' %s %s requeue %.1f %.1f ''' % (run.id, run.worker, run.worker, run.id, run.rts - run.qts, time.time()-run.rts) running_trs.append(tr) finished_trs = [] # sort by finished ts finished = list(sorted(finished, key=lambda x: knownruns[x].fts)) for runid in finished[-40:]: run = knownruns[runid] tr = ''' %s %s %.1f %.1f ''' % (run.id, run.worker, run.rts - run.qts, run.fts - run.rts) finished_trs.append(tr) body = ''' %s
Worker Nodes (%s) Plot Stats
Worker Count Fail s/Jobs Jobs/h Active Available Ratio
%s
Waiting Jobs (%s)
Run-ID Queuetime
%s
Running Jobs (%s)
Run-ID Worker Requeue Queuetime Runtime
%s
Finished Jobs (%s)
Run-ID Worker Queuetime Runtime
''' % ('cluster', len(worker_trs), '\n'.join(worker_trs), len(waiting_trs), '\n'.join(waiting_trs), len(running_trs), '\n'.join(running_trs), len(finished), '\n'.join(finished_trs), ) return render(body=body) def getInterestingOptruns(lws): return [d.name for d in lws.optimizer.tmpdir.dirs() if d.joinpath('.interested').exists()] def getAllOptruns(lws, filter=None): ''' return optruns that have reached at least a minimum''' dirs = [d for d in lws.optimizer.tmpdir.dirs() if d.joinpath('mins.txt').exists()] if filter is not None: _dirs = [] for d in dirs: data = [s for s in d.joinpath('mins.txt').lines()[-1].split()] data_init = [s for s in d.joinpath('init.txt').lines() if s.strip()] allowed = [] if 'gen' in filter: for s in data: if s.startswith('gen:'): allowed.append(int(s[4:]) > filter['gen']) if filter.get('station'): for s in data_init: if s.startswith('station:'): allowed.append(any(e in s[8:] for e in filter['station'].split(',') if e.strip())) if filter.get('ts'): allowed.append(data[0] >= filter['ts']) if all(allowed): _dirs.append(d) dirs = set(_dirs) return list(sorted(d.name for d in dirs)) def renderOptimizer(lws): active_session = lws.optimizer.optsession if lws.optimizer.running else None session_trs = [] lastinit = {} files = sorted(lws.optimizer.tmpdir.dirs(), key=lambda x: x.files('*.txt')[0].mtime if len(x.files('*.txt')) > 0 else 0) for i, d in enumerate(reversed(files)): f = d.joinpath('init.txt') if not f.exists(): continue initparams = dict([(e.split(':')[0], e.split(':')[1].strip()) for e in f.text().split('\n') if e.strip()]) if i == 0: lastinit = initparams trdata = defaultdict(str) trdata.update({'name': d.name, 'ts': datetime.fromtimestamp(d.mtime).strftime('%d.%m %H:%M')}) trdata.update(initparams) trdata['min_avg_delta'] = '' trdata['min_generation'] = '' trdata['curr_generation'] = '' f = d.joinpath('mins.txt') if f.exists(): lastmin = f.text().strip().split('\n')[-1].split() generation, orgid, mindelta = lastmin[1].split(':')[1], lastmin[2].split(':')[1], lastmin[3].split(':')[1] trdata['min_avg_delta'] = '%s@%s' % (mindelta, generation) cmp = lambda x: int(x.namebase.split('_')[1]) if x.namebase.startswith('population_') else -1 popfiles = list(sorted(d.files('*.txt'), key=cmp)) # and again get the last line lastsim = popfiles[-1].text().strip().split('\n')[-1].split() generation, orgid = lastsim[1].split(':')[1], lastsim[2].split(':')[1] trdata['curr_generation'] = '%s' % generation trdata['isinterest'] = 'yes' if d.joinpath('.interested').exists() else 'no' station_evaluate = [] for station in initparams['station'].split(','): a = '%s' % (station, d.name, station) station_evaluate.append(a) trdata['stations'] = '\n'.join(station_evaluate) restarturl = '/' tr = ''' %(name)s %(stations)s %(timelimit)s %(genlimit)s %(min_avg_delta)s %(curr_generation)s %(scene)s %(ts)s %(power)s %(density)s %(resolution)s %(numphotons)s %(bbox)s %(startpop)s %(childcount)s %(childcull)s %(mutprob)s %(mutamt)s %(isinterest)s build ''' % trdata session_trs.append(tr) body = '''
Start Optimizer Session
Session
Station
Timelimit (sec)
max Gens
Photon Params
Power
Density
Numphotons
Resolution (X)
Bounding Box
Scene
Genetic Sim Params
Startpop
Childcount
Childcull
Mutprob
Mutamt
Resume Population
Session
New Organisms
%(lastsessions)s
Optimizer Sessions [Active: %(active_session)s] Stop!
Session Station Timelimit Genlimit MinDelta CurrGen Scene Started Power [+/-] Density Resolution Photons BoundingBox Startpop [+/-] Childcount Childcull Mutprob Mutamt Interest Build
''' % {'pagename': 'optimize', 'active_session': active_session, 'stoppable': 'none' if active_session is None else 'inline', 'lastsessions': '\n'.join(session_trs), 'power': lastinit.get('power', '2.0e-6'), 'session': lastinit.get('session', 'optsession'), 'station': lastinit.get('station', lws.config['defaultDevice']), 'timelimit': lastinit.get('timelimit', '0'), 'genlimit': lastinit.get('genlimit', '0'), 'density': lastinit.get('density', str(lws.activeScene['density'])), 'resolution': lastinit.get('resolution', ','.join(str(e) for e in lws.activeScene['resolution'])), 'numphotons': lastinit.get('numphotons', str(lws.activeScene['numphotons'])), 'bbox': lastinit.get('bbox', ','.join(str(e) for e in lws.activeScene['bbox'])), 'scene': lastinit.get('scene', lws.activeScene.name), 'startpop': lastinit.get('startpop', '6'), 'childcount': lastinit.get('childcount', '8'), 'childcull': lastinit.get('childcull', '20'), 'mutprob': lastinit.get('mutprob', '0.1'), 'mutamt': lastinit.get('mutamt', '0.1'), } css = ''' td.genparam, td.raytracerparam { display:none; } tr.optrun:hover { background:#DDF; } table{ border-collapse:collapse; border: 1px solid #ccc; font-size: 14; float:left; }; ''' return render(body=body, css=css) def renderEvaluteOptruns(lws, optruns, compact=False, **kwargs): optruns = [e for e in optruns.split(',') if e] if 'all' in optruns: optruns = getAllOptruns(lws, filter={'gen': 20, 'station': kwargs.get('station', ''), 'ts': kwargs.get('ts')}) optruns_a = [] for o in sorted(getInterestingOptruns(lws)): _optruns = set(optruns) if o in _optruns: if len(_optruns) > 1: _optruns.discard(o) style = 'style="font-weight:bold"' else: _optruns.add(o) style = 'style="font-weight:normal"' _compact = '' if not compact else '?compact' a = '%s' % (style, ','.join(sorted(_optruns)), _compact, o) optruns_a.append(a) optrun_containerdata = defaultdict(list) for optrun in optruns: odir = lws.optimizer.tmpdir.joinpath(optrun) if not compact: ww = 'width="%s%%"' % int(100 / len(optruns)) else: ww = '' td = ''' %(optrun)s ''' % {'optrun': optrun, 'ww': ww} optrun_containerdata[optrun].append(td) trs = [] f = odir.joinpath('mins.txt') if not f.exists(): continue lastmin = f.lines()[-1] for i, s in enumerate(lastmin.split()): if i == 0: name = 'timestamp' value = s else: name, value = s.split(':') name_css = name.replace('.', '_').replace('/', '_') tr = ''' %(name)s %(value)s ''' % {'name_css': name_css, 'name': name, 'value': value} trs.append(tr) td = ''' %s
Param Value
''' % '\n'.join(trs) optrun_containerdata[optrun].append(td) if not compact: if len(optruns) < 6: td = ''' ''' % {'optrun': optrun} optrun_containerdata[optrun].append(td) if len(optruns) < 3: td = ''' ''' % {'optrun': optrun} optrun_containerdata[optrun].append(td) num_tds = len(optrun_containerdata.values()[0]) if optrun_containerdata else 0 optrun_containers = [] for i in range(num_tds): tds = [tds[i] for optrun, tds in optrun_containerdata.items()] tr = '''%s''' % '\n'.join(tds) optrun_containers.append(tr) if not compact: ww = 'width="100%"' else: ww = '' body = '''
Evaluate Optruns: %(optruns)s
%(optrun_containers)s
''' % { 'pagename': 'optruns', 'optrun_containers': '\n'.join(optrun_containers), 'optruns': '\n'.join(optruns_a), 'ww': ww, } css = ''' table { border-collapse:collapse; border: 1px solid #ccc; font-size: 14; float:left } td.cell { border-right: 3px solid grey; vertical-align:top; } td.header{ background-color:#ccc; text-align:center; font-weight:bold; } ''' % {'width': (int(100 / len(optruns)) if optruns else 0)} return render(body=body, css=css) def renderMeasurements(lws, stations, view): tables = [] ## full data grouped by APs stats = defaultdict(int) for mac, cfg in sorted(lws.mac2cfg.items(), key=lambda e: e[1].name): s2m = {} for station in stations: measurements = lws.getMeasurements(station=station, apid=cfg.name) s2m[station] = measurements locrows = [] for locid in sorted(lws.known_locations.keys()): str_station_values = [] for station in stations: measurements = s2m[station] vals = [] rssis = [] if measurements is not None and str(locid) in measurements: m = measurements[str(locid)] rssis = m.rssis for _view in view: if _view == 'mean': vals.append(str(int(scipy.mean(rssis)))) if _view == 'median': vals.append(str(int(scipy.median(rssis)))) if _view == 'stddev': stddev = scipy.std(rssis) vals.append('%.1f' % stddev) else: m = None str_station_values.append(('/'.join(e for e in vals), ','.join('%.1f' % e for e in sorted(rssis)), m, cfg, (lws.known_locations[locid].x, lws.known_locations[locid].y, lws.known_locations[locid].z), station )) if len(stations) == 2: # HACK FOR COMPARING TWO MEASUREMENT-SETS try: # most ugly delta = '%.1f' % (float(str_station_values[0][0].split('/')[0]) - float(str_station_values[1][0].split('/')[0])) except ValueError: delta = '' str_station_values.append((delta, '', None, None, None, None)) def styleFromMeasurement(m, apcfg, location, station, locid): MAX_REQUIRED_DISTANCE = 20 # mark location grey if distance exceeds MAX_REQUIRED_DISTANCE MIN_REQUIRED_DISTANCE = 10 if location is not None: dist = ((location[0]-apcfg['x'])**2 + (location[1]-apcfg['y'])**2 + + (location[2]-apcfg['z'])**2)**0.5 else: dist = None if m is not None and len(m.rssis) > 0: stats[(station, 'collected')] += 1 stats[(station, 'ap_%s' % apcfg.name)] += 1 stats[(station, 'locid_%s' % locid)] += 1 if station == 'wispy' and 'asus' != apcfg['powerid'] and m is None: return "background-color:silver" if dist is not None and dist > MAX_REQUIRED_DISTANCE and m is None: #~ stats[(station, 'faraway')] += 1 return "background-color:silver" if dist is not None and dist < MIN_REQUIRED_DISTANCE and m is None: #~ stats[(station, 'faraway')] += 1 return "background-color:#FFCCCC" elif m is None: stats[(station, 'missing')] += 1 return '' elif scipy.std(m.rssis) > 10: stats[(station, 'highstddev')] += 1 stats[(station, 'brutalstddev')] += 1 return "background-color:#FF8866" elif scipy.std(m.rssis) > 5: stats[(station, 'highstddev')] += 1 return "background-color:yellow" elif scipy.std(m.rssis) > 4: stats[(station, 'highstddev')] += 1 return "background-color:FFFFCC" elif len(m.rssis) <= 5: stats[(station, 'tosmall')] += 1 return "background-color:#CCCCFF" else: if len(m.rssis) > 0: stats[(station, 'nice')] += 1 return '' locrow = ''' %s %s ''' % ( locid, '\n'.join('%s' % ( e[1], styleFromMeasurement(e[2], e[3], e[4], e[5], locid), e[0] ) for e in str_station_values) ) locrows.append(locrow) table = ''' %s %s
%s
LocID
''' % ( '%s/%s' % (cfg.name, mac), '\n'.join(['%s' % s for s in stations] + (['Delta'] if len(stations) == 2 else [])), '\n'.join(locrows), ) tables.append(table) ## aggregated by APs trs = [] for station in stations: nice = stats[(station, 'nice')] collected = stats[(station, 'collected')] missing = stats[(station, 'missing')] highstddev = stats[(station, 'highstddev')] brutalstddev = stats[(station, 'brutalstddev')] tosmall = stats[(station, 'tosmall')] ap_aggregated = [] for mac, cfg in sorted(lws.mac2cfg.items(), key=lambda e: e[1].name): v = stats[(station, 'ap_%s' % cfg.name)] ap_aggregated.append('%s' % v) tr = ''' %s%s%s%s%s%s%s %s ''' % (station, collected, missing, nice, highstddev, brutalstddev, tosmall, '\n'.join(ap_aggregated)) trs.append(tr) apheader = [] for mac, cfg in sorted(lws.mac2cfg.items(), key=lambda e: e[1].name): apid = cfg.name apheader.append('%s' % apid) table = ''' %s %s
device collected missing nice highstddev brutalstddev tosmall
''' % ('\n'.join(apheader), '\n'.join(trs)) tables.insert(0, table) ## aggregated by location trs = [] for station in stations: locid_aggregated = [] for locid in lws.known_locations: v = stats[(station, 'locid_%s' % locid)] style = 'background-color:#FFCCCC' if v == 0 else '' locid_aggregated.append('%s' % (style, v)) tr = ''' %s%s%s %s ''' % (station, 0, 0, '\n'.join(locid_aggregated)) trs.append(tr) locidheader = [] for locid in lws.known_locations: locidheader.append('%s' % locid) table = ''' %s %s
device avail miss
''' % ('\n'.join(locidheader), '\n'.join(trs)) tables.insert(1, table) ## the rest cutplanes = ['cut %s' % (s, s) for s in lws.activeScene['levels2d'].scalars] body = '''
Examples: All Stations with Mean/Median/Stddev Compare mean of first 2 Stations Compare stdev of first 2 Stations
%(cutplanes)s
%(tables)s ''' % {'pagename': 'measurements', 'stations': ','.join(lws.config['knownStations']), 'compare': ','.join(lws.config['knownStations'][:2]), 'tables': '\n'.join(tables), 'cutplanes': '\n'.join(cutplanes), } return render(body=body) def renderCollectPath(lws, station): spans = [] options = [] for pathid in sorted(lws.activeScene['paths'].scalars): locids = ','.join(lws.activeScene['paths'][pathid]) spans.append('%s' % (pathid, locids)) options.append('' % (pathid, pathid)) eval_on_optrun = [] for optrun in 'all_5', 'all_31': a = '''%(optrun)s''' eval_on_optrun.append(a % {'optrun': optrun, 'station': station}) body = '''
feedback
next
start
view %(station)s %(eval_on_optrun)s
''' % {'pagename': 'collect', 'station': station, 'configured_paths': '\n'.join(spans), 'options_pathid': '\n'.join(options), 'eval_on_optrun': '\n'.join(eval_on_optrun), } return render(body=body) def renderEvaluate(lws, optruns, stations, cubewidth, errtype='3d', filter=None, refresh=False, algo='hmm'): if optruns is None: optruns = '' station_divs = [] for station in stations.split(','): pathids2runids = evaluate.getCollectedPathids2runids(station, lws.activeScene['paths'], lws.config['tmp_tracked'], filter) settings = ['end', 'seq'] reload(evaluate) tables = [] for optrun in sorted(optruns.split(',')): try: errors = evaluate.evaluate(lws, optrun, station, cubewidth, algo, pathids2runids, refresh) except Exception: log.exception('error during evaluate') errors = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: (0, 0)))) rows = [] all_avg_errors = defaultdict(list) for pathid, runs in sorted(pathids2runids.items()): avg_errors = defaultdict(list) runrows = [] for runid in runs: setting_tds = [] for s in settings: err3d, err2d = errors[pathid][runid][s] if (err3d, err2d) == (0, 0): e = 0.0 else: if errtype == '3d': e = err3d else: e = err2d avg_errors[s].append(e) href = '/evaluatePath/%s/%s/%s/%s/%s?cubewidth=%s&algo=%s%s' % (station, optrun, pathid, runid, s, cubewidth, algo, '&refresh' if not e else '') setting_tds.append('%.2f' % (href, e)) tr = '%s%s' % (pathid, runid, ''.join(setting_tds)) runrows.append(tr) tds = [] for s in settings: if len(avg_errors[s]) > 0: e = sum(avg_errors[s]) / float(len(avg_errors[s])) else: e = 0.0 href = '/evaluate/%s/%s?filter=%s&algo=%s' % (station, optruns, pathid, algo) tds.append('%.2f' % (href, e)) all_avg_errors[s].extend(avg_errors[s]) tr = '%s (%s)%s' % (pathid, pathid, len(runrows), ''.join(tds)) rows.append(tr) rows.extend(runrows) tds = [] for s in settings: if len(all_avg_errors[s]) > 0: tds.append('%.2f' % (sum(all_avg_errors[s]) / float(len(all_avg_errors[s])))) else: tds.append('') tr = 'total avg%s' % ''.join(tds) rows.append(tr) table = ''' %s %s
%s - %s
%s
Run
''' % ( optrun, station, 'device: %s with cubewidth: %s and errtype: %s' % (station, cubewidth, errtype), '\n'.join(['%s' % s for s in settings]), '\n'.join(rows), ) tables.append(table) station_divs.append('
%s
' % '\n'.join(tables)) optruns_a = [] for o in sorted(getInterestingOptruns(lws)): _optruns = set(e for e in optruns.split(',') if e) if o in _optruns: if len(_optruns) > 1: _optruns.discard(o) style = 'style="font-weight:bold"' else: _optruns.add(o) style = 'style="font-weight:normal"' qs = '?algo=' + algo qs += '&filter=%s' % filter if filter else '' a = '%s' % (style, stations, ','.join(sorted(_optruns)), qs, o) optruns_a.append(a) stations_a = [] for s in sorted(lws.config['knownStations']): _stations = set(stations.split(',')) if s in _stations: if len(_stations) > 1: _stations.discard(s) style = 'style="font-weight:bold"' else: _stations.add(s) style = 'style="font-weight:normal"' qs = '?algo=' + algo qs += '&filter=%s' % filter if filter else '' a = '%s' % (style, ','.join(sorted(_stations)), optruns, qs, s) stations_a.append(a) body = '''
Evaluate Optruns: %(optruns)s Stations: %(stations)s
%(station_divs)s ''' % {'pagename': 'evaluate', 'station': stations.split(',')[0], 'station_divs': '\n'.join(station_divs), 'optruns': '\n'.join(optruns_a), 'stations': '\n'.join(stations_a), } css = ''' table { border-collapse:collapse; border: 1px solid #ccc; font-size: 14; float:left } tr.run { display:none; } tr.path { cursor:pointer; background-color: #EEE; } ''' return render(body=body, css=css) def renderEvaluatePath(lws, optrun, station, pathid, runid, setting, cubewidth, algo, refresh=False): reload(evaluate) errors = evaluate.evaluate(lws, optrun, station, cubewidth, algo, {pathid: [runid]}, refresh) # exception case: should be handled better assert errors[pathid][runid][setting] != (0, 0), 'propbably error during in evalAll worker threads ' cached_err_file = lws.config['tmp'].joinpath('evaluator', '%s/%s_%s_%s_%s_%s_%s.xml' % (optrun, station, cubewidth, algo, setting, pathid, runid)) tree = FileToTree(cached_err_file) apids = set() for e in tree.xpath('//apdata'): apids.update(e.attrib.keys()) apids = list(apids) pos_rows = [] posEls = tree.getroot().xpath('pos') # move unseen aps backwards if len(posEls) > 0: apdata = posEls[0].xpath('apdata')[0].attrib def move_unseen_backward(apid1, apid2): if apdata[apid1].endswith('/2.0'): return 2 elif apdata[apid2].endswith('/2.0'): return -2 else: return -1 if apid1 < apid2 else 1 apids.sort(cmp=move_unseen_backward) for i, pel in enumerate(posEls): tds = [] hexval = pos2rgb(i, len(posEls)) s = '%s' % (hexval, i) fw = 'bold' if pel.attrib['interpolated'] == 'false' else 'normal' s += '%s,%s,%s' % (fw, pel.attrib['x'], pel.attrib['y'], pel.attrib['z']) s += '%s' % pel.attrib['ts'] s += '%s' % pel.attrib['err2d'] s += '%s,%s,%s' % (pel.attrib['sx'], pel.attrib['sy'], pel.attrib['sz']) s += '%s' % pel.attrib['tp'] s += '%s,%s,%s' % (pel.attrib['dx'], pel.attrib['dy'], pel.attrib['dz']) s += '%s' % pel.attrib['ep'] apdata = pel.xpath('apdata')[0].attrib for apid in apids: values = apdata[apid] apid = apid[3:] #~ if values != '-100.0/-1.0': max_delta = 6.0 if values.endswith('/2.0'): bgc = '#AAF' delta = 0 continue elif values.endswith('/1.0'): bgc = '#DDD' delta = 0 else: simulated, measured = values.split('/') delta = abs(float(simulated) - float(measured)) bgc = pos2rgb(max(0, max_delta - delta), max_delta, spread=0.35, saturation=0.5) td = '%s' % (bgc, apid, delta, values) tds.append(td) cls = 'measured' if pel.attrib['interpolated'] == 'false' else 'interpolated' pos_rows.append('%s' % (cls, s + ''.join(tds))) ap_tds = ''.join('%s' % apid[3:] for apid in apids if not posEls[0].xpath('apdata')[0].attrib[apid].endswith('/2.0')) table = ''' %s %s
# Pos TS Err2d Cube Transition tx,ty,tz Emission
''' % (ap_tds, ''.join(pos_rows)) plots = [ ('end', '' % (optrun, station, pathid, runid, 'end', cubewidth, algo)), ('seq', '' % (optrun, station, pathid, runid, 'seq', cubewidth, algo)), ] levels = lws.activeScene['levels2d'].scalars plots.extend(('%s' % l, '' % l) for l in levels) plots_table = '''
%(imgs)s %(imgs)s
%(switchs)s %(switchs)s
''' imgs = '\n'.join(e[1] for e in plots) switchs = ''.join('%s' % e[0] for e in plots) plots_table = plots_table % {'imgs': imgs, 'switchs': switchs} num_measurements = int(tree.getroot().xpath('count(//pos[@interpolated="false"])')) num_signals = int(tree.getroot().xpath('count(//pos)')) duration = float(tree.getroot().xpath('string(//pos[position()=last()]/@ts)')) sec_permeasurements = duration / num_measurements body = '''

%(pathid)s/%(runid)s

err2d: %(err2d)s seq-err2d: %(seqerr2d)s duration: %(duration)s sec measurements: %(num_measurements)s [%(num_signals)s] sec/measurements: %(sec_permeasurements).2f sec
%(plots_table)s %(table)s ''' % {'pagename': 'evaluatePath', 'station': station, 'plots_table': plots_table, 'table': table, 'pathid': pathid, 'runid': runid, 'err2d': tree.getroot().attrib['err2d'], 'seqerr2d': tree.getroot().attrib['seqerr2d'], 'duration': duration, 'num_measurements': num_measurements, 'sec_permeasurements': sec_permeasurements, 'num_signals': num_signals, 'optrun': optrun, } css = ''' table { border-collapse:collapse; width: 100%; } tr.measured td { border-top: 1px solid #999; } img.plots { display: none; width: 100%; } span.switch { margin-left: 10px; cursor: pointer; } ''' return render(body=body, css=css) def renderLocalize(lws, device, refresh=False): numcolors = 256 rgbdata = ','.join(pos2rgb(i, numcolors, spread=0.75, saturation=0.85) for i in range(0, numcolors)) from utils.tiles import createLog2Tiles for level in lws.activeScene['levels2d']: destfile = lws.config['tmp'].joinpath('tiling_%s.png' % level) plotter.plot2DMap(lws.activeScene, level, {}, {}, destfile=destfile, resizeFactor=8, refresh=refresh) destdir = lws.config['tmp'].joinpath('tiles_%s' % level) if not destdir.exists() or refresh: createLog2Tiles(destfile, destdir, logger=log) aptrs = [] aptds = [] for i, apcfg in enumerate(sorted(lws.mac2cfg.values(), key=lambda e: e.name)): apid, x, y, z = apcfg.name, apcfg['x'], apcfg['y'], apcfg['z'] x, y, z = lws.intoMapSpace(x, y, z) activeness = ' inactive_ap' if apid in lws.localizeSessionInactiveAPs[device] else 'active_ap' s = ''' [x] %s:   ''' % (activeness, apid, apid, apid, apid, apid, x, y, z) aptds.append(s) if i % 7 == 6: aptrs.append('%s' % ''.join(aptds)) aptds[:] = [] aptrs.append('%s' % ''.join(aptds)) body = '''
session ID: queuesize: client: z: hight (m): %(aptrs)s
Top N

APs

Positions


EG

OG1

OG2


Start
''' % {'pagename': 'localize', 'station': device, 'rgbdata':rgbdata, 'numcolors': numcolors, 'aptrs': '\n'.join(aptrs), } css = ''' table { border-collapse:collapse; width: 100%; } div#buttons div { padding-left: 10px; padding-right: 10px; padding-top: 5px; padding-bottom: 5px; background-color: #EEE; border: 2px solid #AAA; cursor:pointer; font-weight:bold; } div#buttons div:hover { border: 2px solid #444; } div#buttons div#startstop { background-color: #25BB25; } table#aptable { font-size: small; width: 1250px; } span.apinfo { font-weight: normal; float:right; } span.apid { cursor: pointer; } span.apdisable { cursor: pointer; font-weight: normal; } span.inactive_ap { color: red; } span.show_ap_data { color: green; } ''' js = ['/OpenLayers-2.12/OpenLayers.js', 'localize.js'] #~ js = ['OpenLayers-2.8/OpenLayers.js', 'localize.js'] return render(body=body, css=css, js=js)