Beispiel #1
0
def strips(points, user_id=None):
    log.info("Drawing strips for user %s..." % user_id)
    lines = []
    q = 0
    for p, point in enumerate(points):
        prev = points[p - 1] if p > 0 else None
        if prev is not None and point.period < prev.period:
            q += 1
        color = colors[point.location % len(colors)]
        lines.append([(point.period / PERIODS) * 1000, q,
                      ((point.period + point.duration) / PERIODS) * 1000, q,
                      color, 8.0])
        if point.period + point.duration > PERIODS:
            overflow = (point.period + point.duration) - PERIODS
            lines.append(
                [0, q + 1, (overflow / PERIODS) * 1000, q + 1, color, 8.0])
    ctx = drawing.Context(1000, ((q + 2) * 10) + 2,
                          relative=False,
                          flip=False,
                          hsv=False,
                          background=(0., 0., 0., 1.))
    for line in lines:
        line[1] = line[3] = (((line[1] / (q + 2))) * ((q + 2) * 10)) + 6
        ctx.line(*line)
    ctx.output("images/%s_strips.png" % user_id, False)
Beispiel #2
0
def plot(walk_id, xs, ys, zs, ds, peaks, total_samples, fs):

    try:
        from housepy import drawing
    except:
        log.error("Can't draw")
        return

    # plot
    ctx = drawing.Context(5000, 600, relative=True, flip=True)
    ctx.line(200.0 / total_samples,
             0.5,
             350.0 / total_samples,
             0.5,
             thickness=10.0)
    ctx.line([(float(i) / total_samples, x) for (i, x) in enumerate(xs)],
             stroke=(1., 0., 0., 1.0))  # thickness=3.0)
    ctx.line([(float(i) / total_samples, y) for (i, y) in enumerate(ys)],
             stroke=(0., 1., 0., 1.0))  #, thickness=3.0)
    ctx.line([(float(i) / total_samples, z) for (i, z) in enumerate(zs)],
             stroke=(0., 0., 1., 1.0))  #, thickness=3.0)
    ctx.line([(float(i) / total_samples, d) for (i, d) in enumerate(ds)],
             stroke=(0., 0., 0.),
             thickness=3.0)
    ctx.line([(float(i) / total_samples, f) for (i, f) in enumerate(fs)],
             stroke=(1., 0., 1.),
             thickness=5.0)
    for peak in peaks:
        x, y = peak
        x = float(x) / total_samples
        ctx.arc(x,
                y, (10.0 / ctx.width), (10.0 / ctx.height),
                fill=(1., 0., 0.),
                thickness=0.0)
    ctx.output("charts/steps_%s_%s.png" % (walk_id, int(time.time())))
Beispiel #3
0
def path_print(points, index):
    t = str(timeutil.timestamp(ms=True)).replace(".", "-")
    log.info("Drawing path...")
    ctx = drawing.Context(3000,
                          int(3000 / RATIO),
                          relative=True,
                          flip=True,
                          hsv=True)
    ctx.image("basemap/basemap.png")
    midline = sum([point.x for point in points]) / len(points)
    poss = []
    for p in range(len(points)):
        x1, y1 = points[p].x, points[p].y
        if p < len(points) - 1:
            x2, y2 = points[p + 1].x, points[p + 1].y
            ctx.line(x1, y1, x2, y2, stroke=(0., 0., .5, 1.), thickness=5.0)
        ctx.arc(x1,
                y1,
                15 / ctx.width,
                15 / ctx.height,
                fill=(0., 0., 0., 1.),
                thickness=0.0)
        flip = False
        if x1 < midline:
            flip = True
        for pos in poss:
            dist_x = abs(x1 - pos[0]) * ctx.height
            dist_y = abs(y1 - pos[1]) * ctx.height
            if dist_y <= 100 and dist_x <= 400:
                flip = not flip
        if not flip:
            x = x1 + (30 / ctx.width)
        else:
            x = x1 - (50 / ctx.width)
        y = y1 - (12 / ctx.height)
        poss.append((x, y))
        ctx.label(x,
                  y,
                  str(p + 1),
                  stroke=(0., 0., 0., 1.),
                  font="Monaco",
                  size=36)
    for p, point in enumerate(points):
        label = "%d) %s %s%s" % (p + 1, "Wake up at" if p == 0 else "%s," %
                                 point.display_time, point.address, "" if p !=
                                 (len(points) - 1) else " ... sleep")
        ctx.label((200 / ctx.width),
                  1.0 - ((200 + (40 * p)) / ctx.height),
                  label,
                  stroke=(0., 0., 0., 1.),
                  font="Monaco",
                  size=36)
    ctx.output("images/%s_path.png" % (index, ))
    log.info("--> done")
Beispiel #4
0
def gradient_test():
    ctx = drawing.Context(1000, 250, relative=True, flip=True, hsv=True)
    for x in range(1440):
        # c = ((x/288) * 0.35) + .3
        # c = ((x/288) * 0.35) + .0
        c = ((x / 1440) * 0.65) + .0
        c = x / 1440
        ctx.line(x / 1440,
                 0,
                 x / 1440,
                 1,
                 stroke=(c, 1., 1., 1.),
                 thickness=(ctx.width / 1440) + 1)
    ctx.output("gradient.png")
Beispiel #5
0
def days(days, user_id=None):
    ctx = drawing.Context(1000,
                          len(days) * 10,
                          relative=True,
                          flip=False,
                          hsv=True,
                          background=(0., 0., 0., 1.))
    for d, day in enumerate(days):
        for period, point in enumerate(day):
            # color = colors[point.location % len(colors)]
            color = point.location / 100, 1., 1., 1.
            ctx.line(period / PERIODS, (d / len(days)) + 5 / ctx.height,
                     (period + 1) / PERIODS, (d / len(days)) + 5 / ctx.height,
                     stroke=color,
                     thickness=8)
    ctx.output("images/%s_days.png" % user_id, True)
Beispiel #6
0
def map(points, user_id=None):
    log.info("Drawing map for user %s..." % user_id)
    ctx = drawing.Context(3000,
                          int(3000 / RATIO),
                          relative=True,
                          flip=True,
                          hsv=True)
    ctx.image("basemap/basemap.png")
    for point in points:
        color = point.location / 100, 1., 1., 1.
        ctx.arc(point.x,
                point.y,
                6 / ctx.width,
                6 / ctx.height,
                fill=color,
                thickness=0.0)
    ctx.output("images/%d_map.png" % user_id, True)
    log.info("--> done")
Beispiel #7
0
def path(points):
    t = str(timeutil.timestamp(ms=True)).replace(".", "-")
    log.info("Drawing path...")
    ctx = drawing.Context(3000,
                          int(3000 / RATIO),
                          relative=True,
                          flip=True,
                          hsv=True)
    ctx.image("basemap/basemap.png")
    for p in range(len(points)):
        x1, y1 = points[p].x, points[p].y
        color = points[p].period / PERIODS, 1., 1., 1.
        ctx.arc(x1,
                y1,
                5 / ctx.width,
                5 / ctx.height,
                fill=color,
                thickness=0.0)
        if p < len(points) - 1:
            x2, y2 = points[p + 1].x, points[p + 1].y
            ctx.line(x1, y1, x2, y2, stroke=color, thickness=1.0)
    ctx.output("images/%s_path.png" % t)
    log.info("--> done")
Beispiel #8
0
def main(session_id):

    ctx = drawing.Context(2000, 1000)

    for sensor in [2, 3, 4]:
        result = db.branches.find({
            'session': session_id,
            'sensor': sensor
        }).sort([('t', ASCENDING)])
        if not result.count():
            continue

        result = list(result)
        ts = [r['t'] for r in result]
        xs = [r['sample'][0] for r in result]
        ys = [r['sample'][1] for r in result]
        zs = [r['sample'][2] for r in result]
        rms = [r['sample'][3] for r in result]

        duration = ts[-1] - ts[0]
        SAMPLING_RATE = 50  # hz

        x_signal = (sp.resample(ts, xs, duration * SAMPLING_RATE) -
                    RANGE[0]) / (RANGE[1] - RANGE[0])
        y_signal = (sp.resample(ts, ys, duration * SAMPLING_RATE) -
                    RANGE[0]) / (RANGE[1] - RANGE[0])
        z_signal = (sp.resample(ts, zs, duration * SAMPLING_RATE) -
                    RANGE[0]) / (RANGE[1] - RANGE[0])
        rms_signal = (sp.resample(ts, rms, duration * SAMPLING_RATE) -
                      RANGE[0]) / (RANGE[1] - RANGE[0])

        # ctx.plot(x_signal, stroke=(1.0, 0.0, 0.0, 1.0), thickness=2.0)
        # ctx.plot(y_signal, stroke=(0.0, 1.0, 0.0, 1.0), thickness=2.0)
        # ctx.plot(z_signal, stroke=(0.0, 0.0, 1.0, 1.0), thickness=2.0)
        rms_signal = sp.normalize(rms_signal)
        ctx.plot(rms_signal, stroke=colors[sensor], thickness=2.0)
    ctx.output("graphs")
Beispiel #9
0
signals = []
labels = list(streams.keys())
log.info("LABELS %s" % labels)
for label in labels:
    log.info(label)
    ts = tses[label]
    ts = [t_min] + ts + [t_max]
    values = [d[label] if label in d else None for d in streams[label]]
    values = [values[0]] + values + [values[-1]]
    values = sp.remove_shots(values, nones=True)  # repair missing values
    signal = sp.resample(ts, values)
    num_samples = len(signal)
    sample_rate = num_samples / duration
    signal = sp.normalize(signal)
    signal = sp.smooth(signal, 15)
    signals.append(signal)    

log.info("Drawing...")
ctx = drawing.Context(1200, 500, margin=20, hsv=True)
for b in range(12):
    ctx.line(b / 12, 0, b / 12, 1, stroke=(0.5, 0.5, 0.5, 0.5), thickness=0.5)
ctx.line(1, 0, 1, 1, stroke=(0.5, 0.5, 0.5, 0.5), thickness=0.5)
for i, signal in enumerate(signals):
    color = i / (len(signals) + 4) + .1, 1., .8, 1.
    ctx.plot(signal, stroke=color, thickness=1.5)
    ctx.line(10 / ctx.width, 1 - ((10 + (i * 10)) / ctx.height), 30 / ctx.width, 1 - ((10 + (i * 10)) / ctx.height), stroke=color, thickness=2)
    ctx.label(35 / ctx.width, 1 - ((13 + (i * 10)) / ctx.height), labels[i].upper(), size=8)            

ctx.output("charts/")
        # limit
        signal = sp.limit(signal, 1.0)
        signal *= 0.9  # hack, just controlling gain
        signals.append(signal)

        names.append(name)

        i += 1

    return signals, names


if __name__ == "__main__":

    signals, names = generate()
    ctx = drawing.Context(1500, 750)
    for i, signal in enumerate(signals):
        color = colors[i % len(colors)]
        ctx.plot(signal, stroke=color, thickness=2)
        ctx.line(10 / ctx.width,
                 1 - ((10 + (i * 10)) / ctx.height),
                 30 / ctx.width,
                 1 - ((10 + (i * 10)) / ctx.height),
                 stroke=color,
                 thickness=2)
        ctx.label(35 / ctx.width,
                  1 - ((13 + (i * 10)) / ctx.height),
                  names[i].upper(),
                  size=10)
    ctx.output("charts")
Beispiel #11
0
from housepy import log, config, strings, net, s3, util, process, drawing
from scipy.io import wavfile

DURATION = 10
AUDIO_TMP = os.path.abspath(os.path.join(os.path.dirname(__file__), "audio_tmp"))

t = sys.argv[1]

filename = "%s/%s.wav" % (AUDIO_TMP, t)
sample_rate, signal = wavfile.read(filename)
log.debug("samples %s" % len(signal))
log.debug("sample_rate %s" % sample_rate)
duration = float(len(signal)) / sample_rate
log.debug("duration %ss" % strings.format_time(duration))
signal = (np.array(signal).astype('float') / (2**16 * 0.5))   # assuming 16-bit PCM, -1 - 1
signal = abs(signal)    # magnitude

ctx = drawing.Context()
ctx.plot(signal)
ctx.line(0, config['noise_threshold'], 1, config['noise_threshold'], stroke=(255, 0, 0))
ctx.output("screenshots")

log.debug("noise threshold is %s" % config['noise_threshold'])
log.debug("found magnitude")
content_samples = 0
for sample in signal:
    if sample > config['noise_threshold']:
        content_samples += 1
total_content_time = float(content_samples) / sample_rate
log.info("total_content_time %s" % total_content_time)
Beispiel #12
0
points = np.array([(result['location']['coordinates'][0],
                    result['location']['coordinates'][1], result['user_id'])
                   for result in results])

min_lon, max_lon = (np.min(points[:, 0]), np.max(points[:, 0]))
min_lat, max_lat = (np.min(points[:, 1]), np.max(points[:, 1]))
log.debug("%f %f %f %f" % (min_lon, max_lon, min_lat, max_lat))

min_x, max_y = geo.project((min_lon, max_lat))
max_x, min_y = geo.project((max_lon, min_lat))

ratio = (max_x - min_x) / (max_y - min_y)

ctx = drawing.Context(1000,
                      int(1000 / ratio),
                      relative=True,
                      flip=True,
                      hsv=True)
log.info("Drawing %d %d..." % (ctx.width, ctx.height))

for point in points:

    x, y = geo.project((point[0], point[1]))

    if x > max_x or x < min_x or y > max_y or y < min_y:
        continue

    x = (x - min_x) / (max_x - min_x)
    y = (y - min_y) / (max_y - min_y)

    ctx.arc(x,
Beispiel #13
0
def sample(draw=False):
    log.info("START SAMPLE")
    # get the time
    # dt = timeutil.get_dt(tz=config['tz'])
    # dt -= datetime.timedelta(days=300)  # time adjustment if necessary for testing
    # t_utc = timeutil.t_utc(dt)
    t_utc = timeutil.t_utc()
    dt = timeutil.get_dt(t_utc, tz=config['tz'])
    log.info("CURRENT TIME %s" % timeutil.get_string(t_utc, tz=config['tz']))

    # pull the last 24 hours worth -- we're going to normalize over that to set our dynamic levels
    log.info(config['sites'][config['sample']])

    # # this is the real-time last 24 hours
    # query = {'site': config['sample'], 't_utc': {'$gt': t_utc - 86400, '$lt': t_utc}}
    # log.info(query)
    # results = db.entries.find(query)

    # this is the last 24 hours we have
    # assume updating every 15 minutes, last 24 hours is the last 96 results
    results = db.entries.find({
        'site': config['sample']
    }).sort([('t_utc', DESCENDING)]).limit(96)
    results = list(results)
    results.reverse()
    log.info("%s results" % len(results))  # should be 96
    log.info(json.dumps(results[-1], indent=4,
                        default=lambda d: str(d)))  # show the last one

    # resample signals for each
    ts = [d['t_utc'] for d in results]
    duration = ts[-1] - ts[0]
    log.info("DURATION %s %s" % (duration, timeutil.format_seconds(duration)))
    signals = []
    rates = []
    labels = list(config['labels'].values())
    labels.sort()
    for i, label in enumerate(labels):
        # log.debug(label)
        try:
            values = [d[label] if label in d else None for d in results]
            values = sp.remove_shots(values,
                                     nones=True)  # repair missing values
            signal = sp.resample(ts, values)
            num_samples = len(signal)
            sample_rate = num_samples / duration
            rates.append(sample_rate)
            signal = sp.normalize(signal)
            signal = sp.smooth(signal, 15)
            signals.append(signal)
        except KeyError as e:
            log.error(log.exc(e))
            log.error(values)

    # draw if desired
    if draw:
        from housepy import drawing
        ctx = drawing.Context(1200, 500, margin=20, hsv=True)
        for i, label in enumerate(labels):
            color = i / len(labels), .8, .8, 1.
            signal = signals[i]
            ctx.plot(signal, stroke=color, thickness=2)
        ctx.output("charts/")

    # collapse into n-dimensional points
    points = []
    for i in range(len(signals[0])):
        point = [signal[i] for signal in signals]
        points.append(point)

    # PCA to 4D -- this takes whatever data we've got and maximizes variation for our four panels
    points = np.array(points)
    # log.debug("INPUT: %s POINTS, %s DIMENSIONS" % points.shape)
    points = decomposition.PCA(n_components=4).fit_transform(points)
    # log.debug("OUTPUT: %s POINTS, %s DIMENSIONS" % points.shape)

    # normalize each dimension independently, again amplifying dynamics
    points = np.column_stack((sp.normalize(points[:, 0], np.min(points[:, 0]),
                                           np.max(points[:, 0])),
                              sp.normalize(points[:, 1], np.min(points[:, 1]),
                                           np.max(points[:, 1])),
                              sp.normalize(points[:, 1], np.min(points[:, 1]),
                                           np.max(points[:, 2])),
                              sp.normalize(points[:, 2], np.min(points[:, 3]),
                                           np.max(points[:, 3]))))

    # now, for each time this is queried we want to return an interpolation between the last two points
    # this essentially implements a delay that closes in on the most recent query
    # ...hopefully to be refreshed with a new USGS reading when it gets there
    # if that reading doesnt come, it's ok, it just hovers there until we proceed
    # aaandd actually we want a couple of hours delay, because these come in at bulk every 1-4 hours

    # we know we have 96 points. four hours back is 16 points
    # interpolating between points -17 and -16 should give the most recent guaranteed smooth transitions
    # transduction takes time, pues

    point_a = points[-17]
    point_b = points[-16]
    # log.debug(point_a)
    # log.debug(point_b)

    # linear interpolation over 15 minutes
    position = (((dt.minute % 15) * 60) + dt.second) / (15 * 60)
    # log.debug(position)
    point = [(point_a[i] * (1.0 - position)) + (point_b[i] * position)
             for i in range(len(point_a))]

    log.info("RESULT: %s" % point)

    return point
Beispiel #14
0
def main(session_id):
    result = db.branches.find({'session': session_id}).sort([('t', ASCENDING)])
    if not result.count():
        print("NO DATA!")
        exit()

    log.info("Start processing...")

    result = list(result)
    ts = [r['t'] for r in result]
    rms = [r['sample'][3] for r in result]
    duration = ts[-1] - ts[0]
    SAMPLING_RATE = 60 # hz
    log.info("DURATION %fs" % duration)

    signal = sp.resample(ts, rms, duration * SAMPLING_RATE)
    signal = sp.remove_shots(signal)
    signal = sp.normalize(signal)    
    signal = sp.smooth(signal, 15)

    # this number should match some lower frequency bound. ie, put this in hz.
    # the smaller the number, the more it will affect small motion
    # so this should be higher than the slowest motion we care about
    # ie, dont care about motion over 0.5hz, which is 120 samples
    trend = sp.smooth(signal, 120)  
    signal -= trend
    signal += 0.5

    atrend = sp.smooth(signal, 500)



    ## autocorrelation

    auto = sp.autocorrelate(signal)
    # this should be small -- if 60hz, fastest gesture would reasonably be half of that, so 30
    peaks, valleys = sp.detect_peaks(auto, 10)
    peaks = [peak for peak in peaks[1:] if peak[1] > 0.5]
    partials = []
    for peak in peaks:    
        frequency = SAMPLING_RATE / peak[0]
        partial = frequency * 1000
        partials.append([partial, float(peak[1])])
        log.info("%d samps\t%fhz\t%f magnitude\t%f map" % (peak[0], frequency, peak[1], partial))
    log.info(partials)    

    ctx = drawing.Context(2000, 750)
    ctx.plot(auto, stroke=(0.0, 0.0, 0.0, 1.0), thickness=2.0)
    for peak in peaks:
        x = peak[0] / len(auto)
        ctx.line(x, 0.0, x, peak[1], stroke=(1.0, 0.0, 0.0, 1.0))
    ctx.output("graphs")


    ## audio

    audio_signal = sp.make_audio(signal)
    spectrum(audio_signal, SAMPLING_RATE)

    AUDIO_RATE = 11025
    filename = "%s.wav" % util.timestamp()
    sound.write_audio(audio_signal, filename, AUDIO_RATE)
    subprocess.call(["open", filename])
    log.info("AUDIO DURATION %fs" % (duration / (AUDIO_RATE / SAMPLING_RATE)))

    ctx = drawing.Context(2000, 750)
    ctx.plot(signal, stroke=(0.0, 0.0, 0.0, 1.0), thickness=2.0)
    ctx.plot(trend, stroke=(1.0, 0.0, 0.0, 1.0), thickness=2.0)
    ctx.plot(atrend, stroke=(0.0, 0.0, 1.0, 1.0), thickness=2.0)
    ctx.output("graphs")


    log.info("--> done") # around 300ms
Beispiel #15
0
def spectrum(signal, rate):

    log.info("Computing spectrogram...")

    block_size = 512
    block_overlap = block_size / 2  # power of two, default is 128

    # freqs, ts, spectrum = spectrogram(sound.signal, fs=sound.rate, noverlap=block_overlap, nfft=block_size, detrend='constant', return_onesided=True, scaling='density', axis=-1, mode='psd', window=('tukey', 0.25), nperseg=block_overlap*2)
    spectrum, freqs, ts, image = plt.specgram(signal,
                                              NFFT=block_size,
                                              Fs=rate,
                                              noverlap=block_overlap)

    # (plt is 3k smaller)

    # print("spectrum", spectrum) # freq rows of time columns.
    # print()
    # print(freqs)
    # print()
    # print(ts)

    log.info("--> done")
    log.info("--> freq bins %s" % len(freqs))
    log.info("--> time columns %s" % len(ts))

    log.info("Drawing...")

    # with gzip.open("spectrum.pklz", 'wb') as f:
    #     f.write(pickle.dumps(spectrum))

    ctx = drawing.Context(
        len(ts) * 1, len(freqs) * 1,
        relative=True)  # if it's not an even multiple, artifacts happen

    pixel_width = ctx.width / len(spectrum[0])
    pixel_height = ctx.height / len(spectrum)

    # for y, row in enumerate(spectrum):
    #     for x, value in enumerate(row):
    #         v = min(value / (allmax / 500), 1.0)
    #         v = 1 - v
    #         # print((x * pixel_width) / ctx.width, (y * pixel_height) / ctx.height, pixel_width / ctx.width, pixel_height / ctx.height)
    #         ctx.rect((x * pixel_width) / ctx.width, (y * pixel_height) / ctx.height, pixel_width / ctx.width, pixel_height / ctx.height, fill=(v, v, v, 1.), stroke=(1., 0., 0., 0.), thickness=0.0)

    # mx = spectrum.flatten().max()
    # print("maximum", spectrum.flatten().max())
    # print("minimum", spectrum.flatten().min())

    spectrum = sp.normalize(
        np.sqrt(spectrum), 0.0,
        200.0)  # sqrt compresses, good for power. 200 is a clipping threshold.

    for y, row in enumerate(spectrum):
        for x, v in enumerate(row):
            ctx.line((x * pixel_width) / ctx.width,
                     (y * pixel_height) / ctx.height,
                     ((x * pixel_width) + pixel_width) / ctx.width,
                     (y * pixel_height) / ctx.height,
                     stroke=(v, v, v, 1.),
                     thickness=pixel_height)

    log.info("--> done")
    ctx.output("charts/")