Measure devel notes

From OLPC
Revision as of 11:52, 25 October 2007 by Arjs (talk | contribs) (Profiling code)
Jump to navigation Jump to search

Development notes. For the official page, please see Measure


Metadata file associated with Logs

Measure Activity logs metadata file
Filename
Filename
Filename
Logname
Logname
Logname

Log file format

sec/minute/hour/snapshot
2232
3445
stop

Draw dotted log

context.move_to(x,y)
context.arc(x,y,r,0,2*pi)


Convert #RRGGBB to an (R, G, B) tuple

colorstring = colorstring.strip()
if colorstring[0] == '#': colorstring = colorstring[1:]
r, g, b = colorstring[:2], colorstring[2:4], colorstring[4:]
r, g, b = [int(n, 16) for n in (r, g, b)]
return (r, g, b)

Get the XO colors

from sugar import profile
color=profile.get_color()
fill = color.get_fill_color()
stroke = color.get_stroke_color()

DSP

Filtering using sinc


Scaling - for scale display, and RMS values

  • I get a buffer of 16bit values (-32768 to 32768). I need to calculate the corresponding rms value of the voltage
  • The correspondence between digital domain values and physical values has been found out experimentally as
v = (m/g)*(s) + 1180   millivolts
where s is a sample value ranging from -32768 to +32768
where m = .0238(i.e. slope when all capture gains are 0dB i.e. g=1)
where g is the gain introduced by capture gains.
There are two such gains Mic Boost +20dB and Capture Gain. 
Note that g IS NOT in dB.
  • Also let k = m/g and c = 1180
  • One option is to scale each sample in voltage domain (which would come out to be a float value) to get rms voltage, Rv = sqrt(sigma(Vi^2)) / N
  • The other option is to calculate RMS of all samples s and then convert result to equivalent voltage
  • For calculating RMS of samples s and then converting to Rv
    • sigma(Vi^2) = (k^2)*(sigma(Xi^2)) + N*c^2 + 2*k*c*sigma(Xi)
    • Once we have sigma(Vi^2) we can take square root of that and divide by N
  • The big question is which one would be better suited in terms of performance overheads on the XO ? <-- profiling is the answer ?


You can get rid of the floating point and the division if Python does OK with 64-bit numbers. You do something like this...
G = 1000/g
V = s*238*G + 1180*10000000
v = V/10000000
...except that you don't immediately divide to get v, and you don't use 10000000. Use 2**32 instead, allowing a 32-bit right shift (free) instead of the division. (so the 1000 has to change, and you don't do .0238*10000 but rather something else appropriate) You may also delay that right shift, adding up the numbers first.

Profiling

import os
import cProfile
import lsprofcalltree
self._profiler = cProfile.Profile()
self._profiler.enable()

self._profiler.disable()
k = lsprofcalltree.KCacheGrind(self._profiler)
data = open(os.path.expanduser('/tmp/measure.kgrind'), 'w+')
k.output(data)
data.close()