From 5291970420560f232edaef99ef8149a4ccaffd64 Mon Sep 17 00:00:00 2001 From: jaseg Date: Mon, 20 Jan 2020 11:52:25 +0100 Subject: Initial commit --- .gitignore | 3 + Makefile | 41 ++ main.py.example | 125 ++++ viz.ipynb | 1719 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1888 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 main.py.example create mode 100644 viz.ipynb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..705b185 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.mpy +main.py +.ipynb_checkpoints diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dd83a4b --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +ESPTOOL = esptool.py +# TOOL can be 'mpfshell' or 'ampy' +TOOL = mpfshell +FIRMWARE = esp32-idf3-20191220-v1.12.bin +PORT = /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 +SHELL = /bin/sh +MPY := $(patsubst %.py,%.mpy,$(wildcard *.py)) + + +.PHONY: erase flash all install clean repl help sanitize + +all: $(MPY) + +%.mpy: %.py ## Compile all python files + mpy-cross -march=xtensa -o $@ $< + +install: $(MPY) ## Copy all compiled python files to the ESP32 + if [ "${TOOL}" = "mpfshell" ]; then ${TOOL} -n -c "open ${PORT:/dev/%=%}; mput ${MPY}"; fi + if [ "${TOOL}" = "ampy" ]; then ${TOOL} -p ${PORT} put *.mpy; fi + +sanitize: main.py.example + +%.py.example: %.py + sed -n '/#### CONFIG ####/,/#### END ####/{/^#/p;d};p' $< > $@ + +clean: ## Delete all compiled python files + rm -f *.mpy + +erase: ## Erase the flash of the ESP32 + ${ESPTOOL} --chip esp32 --port ${PORT} erase_flash + +flash: ## Download micropython firmware and flash to ESP32 + curl -sSLO https://micropython.org/resources/firmware/${FIRMWARE} + ${ESPTOOL} --chip esp32 --port ${PORT} --baud 460800 write_flash -z 0x1000 ${FIRMWARE} + +repl: ## Start repl shell + if [ "${TOOL}" = "mpfshell" ]; then ${TOOL} -n -o ${BOARD} -c repl; fi + if [ "${TOOL}" != "mpfshell" ]; then screen /dev/${BOARD} ; fi + +help: ## Show this help + grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/main.py.example b/main.py.example new file mode 100644 index 0000000..3d2d0ad --- /dev/null +++ b/main.py.example @@ -0,0 +1,125 @@ + +from machine import Pin, ADC, Timer +import network +import time +import ujson +from uhashlib import sha256 +import binascii +import math +import urequests + + +######################################################## CONFIG ######################################################## +# Wifi settings: +# WIFI_ESSID = 'Your wifi ESSID (name)' +# WIFI_PSK = 'Your wifi key' +# +# Notification settings: +# NOTIFICATION_URL = 'https://automation.jaseg.de/notify/klingel' +# NOTIFICATION_SECRET = b'Your notification proxy secret for this endpoint' +# +# NOTIFICATION_COOLDOWN = 60 # how long to wait after sending a notification before sending the next, in seconds +# +# Detection settings +# MEAN_LEN = 8 # Window length for DC offset determination in seconds (1024ms to be exact) +# RMS_THRESHOLD = 1000 # Threshold for rms detection threshold over 1s window in ADC counts +######################################################### END ########################################################## + + +def wifi_connect(): + iface = network.WLAN(network.STA_IF) + if not iface.isconnected(): + print('Connecting to wifi... ') + iface.active(True) + iface.connect(WIFI_ESSID, WIFI_PSK) + for i in range(20): + if iface.isconnected(): + print('Wifi connected. IP config: ', iface.ifconfig()) + break + time.sleep(0.5) + else: + print("Couldn't connect to wifi.") + + +buf = [0] * 1024 +capture = None +mean = 0 +rms = 0 +sample_tim = Timer(-1) + +def start_sampling(): + global sample_tim + buf_pos = 0 + buf_sum = 0 + mean_acc = [] + + adc = ADC(Pin(34)) + adc.atten(ADC.ATTN_11DB) + + def sample_cb(tim): + global buf, mean, rms, capture + nonlocal adc, buf_pos, buf_sum, mean_acc + + val = adc.read() + buf[buf_pos] = val + buf_sum += val + + buf_pos += 1 + if buf_pos == len(buf): + buf_pos = 0 + mean_acc = [buf_sum/len(buf)] + mean_acc[:MEAN_LEN-1] + mean = sum(mean_acc)/len(mean_acc) + buf_sum = 0 + + rms = math.sqrt( sum( (x-mean)**2 for x in buf )/len(buf) ) + capture = list(buf) # Make a copy + + sample_tim.init(period=1, mode=Timer.PERIODIC, callback=sample_cb) # period in ms + +def uhmac(key, data): + blocksize = 64 + key += bytes(64 - len(key)) + tx = lambda s, x: bytes( b ^ x for b in s ) + outer = sha256(tx(key, 0x5C)) + inner = sha256(tx(key, 0x36)) + inner.update(data) + outer.update(inner.digest()) + return outer.digest() + +def usign(secret, payload=None, seq=None): + payload = {'time': int(time.time()), 'd': payload} + if seq is not None: + payload['seq'] = seq + + payload = ujson.dumps(payload).encode() + auth = binascii.hexlify(uhmac(secret, payload)) + + return ujson.dumps({'payload': payload, 'auth': auth}) + +def notify(**kwargs): + data = usign(NOTIFICATION_SECRET, kwargs) + print(time.time(), 'Notifying', NOTIFICATION_URL) + urequests.post(NOTIFICATION_URL, data=data, headers={'Content-Type': 'application/json'}) + +def klingel_notify(rms, capture): + notify(rms=rms, capture=capture) + +def loop(): + global rms, capture + while True: + if rms > RMS_THRESHOLD: + wifi_connect() + old_capture = capture + rms = 0 + while rms == 0: + time.sleep(0.1) + rms = 0 + klingel_notify(rms, [old_capture, capture]) + time.sleep(NOTIFICATION_COOLDOWN) + + time.sleep(0.1) + +wifi_connect() +start_sampling() +loop() + diff --git a/viz.ipynb b/viz.ipynb new file mode 100644 index 0000000..18c464a --- /dev/null +++ b/viz.ipynb @@ -0,0 +1,1719 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "import statistics\n", + "import math\n", + "import numpy as np\n", + "\n", + "from matplotlib import pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib notebook" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "# led off\n", + "data_led_off = [1753, 1763, 1738, 1696, 1653, 1666, 1773, 1616, 1725, 1616, 1583, 1663, 1605, 1654, 1616, 1606, 1664, 1575, 1647, 1647, 1598, 1682, 1630, 1673, 1699, 1702, 1686, 1753, 1635, 1715, 1810, 1636, 1715, 1638, 1712, 1559, 1619, 1683, 1692, 1636, 1639, 1647, 1691, 1759, 1787, 1702, 1783, 1728, 1647, 1795, 1681, 1616, 1622, 1561, 1627, 1583, 1663, 1655, 1757, 1639, 1698, 1616, 1627, 1615, 1663, 1628, 1669, 1758, 1651, 1651, 1754, 1590, 1615, 1647, 1660, 1625, 1626, 1648, 1729, 1776, 1584, 1712, 1705, 1689, 1667, 1685, 1517, 1648, 1730, 1715, 1632, 1669, 1745, 1664, 1727, 1720, 1678, 1679, 1599, 1723, 1739, 1635, 1611, 1655, 1715, 1658, 1694, 1616, 1779, 1691, 1535, 1762, 1600, 1642, 1648, 1664, 1657, 1678, 1574, 1587, 1695, 1612, 1666, 1571, 1715, 1765, 1697, 1670, 1520, 1683, 1657, 1600, 1646, 1670, 1665, 1643, 1694, 1653, 1612, 1641, 1607, 1607, 1616, 1591, 1598, 1667, 1603, 1618, 1596, 1639, 1654, 1636, 1692, 1730, 1726, 1655, 1706, 1579, 1600, 1591, 1575, 1707, 1591, 1698, 1655, 1649, 1718, 1702, 1622, 1707, 1685, 1655, 1741, 1575, 1622, 1662, 1672, 1687, 1625, 1664, 1586, 1647, 1619, 1626, 1665, 1667, 1745, 1618, 1556, 1715, 1744, 1723, 1599, 1644, 1685, 1711, 1591, 1698, 1619, 1790, 1707, 1671, 1578, 1664, 1725, 1645, 1649, 1633, 1613, 1632, 1639, 1663, 1681, 1711, 1625, 1694, 1695, 1668, 1675, 1810, 1609, 1741, 1701, 1819, 1719, 1659, 1695, 1729, 1667, 1685, 1680, 1731, 1602, 1616, 1687, 1685, 1657, 1627, 1661, 1717, 1709, 1585, 1648, 1622, 1657, 1630, 1692, 1662, 1685, 1648, 1623, 1698, 1621, 1700, 1594, 1602, 1677, 1701, 1755, 1733, 1650, 1665, 1667, 1707, 1651, 1602, 1673, 1794, 1693, 1616, 1647, 1569, 1675, 1776, 1654, 1618, 1628, 1651, 1525, 1569, 1631, 1697, 1588, 1617, 1608, 1803, 1606, 1683, 1667, 1712, 1619, 1686, 1681, 1658, 1589, 1659, 1686, 1523, 1712, 1587, 1717, 1651, 1653, 1647, 1667, 1605, 1687, 1694, 1751, 1694, 1643, 1706, 1611, 1679, 1616, 1717, 1776, 1667, 1707, 1703, 1600, 1587, 1653, 1685, 1706, 1750, 1719, 1665, 1697, 1630, 1611, 1753, 1671, 1679, 1655, 1655, 1731, 1745, 1602, 1655, 1661, 1595, 1599, 1755, 1708, 1675, 1641, 1703, 1702, 1607, 1648, 1631, 1584, 1581, 1664, 1719, 1665, 1679, 1689, 1766, 1696, 1725, 1677, 1543, 1676, 1755, 1616, 1749, 1803, 1615, 1719, 1654, 1563, 1651, 1712, 1706, 1617, 1679, 1635, 1687, 1649, 1681, 1591, 1851, 1637, 1650, 1659, 1625, 1639, 1679, 1631, 1675, 1713, 1654, 1655, 1840, 1613, 1606, 1569, 1712, 1680, 1610, 1710, 1690, 1598, 1687, 1631, 1727, 1677, 1691, 1628, 1658, 1613, 1681, 1637, 1664, 1634, 1712, 1621, 1680, 1607, 1636, 1694, 1709, 1682, 1616, 1661, 1689, 1618, 1687, 1636, 1739, 1664, 1535, 1731, 1590, 1744, 1742, 1691, 1661, 1659, 1634, 1581, 1580, 1674, 1647, 1662, 1671, 1663, 1577, 1654, 1652, 1635, 1563, 1629, 1641, 1719, 1679, 1664, 1703, 1649, 1636, 1582, 1675, 1517, 1726, 1610, 1683, 1712, 1682, 1748, 1591, 1599, 1609, 1566, 1691, 1707, 1663, 1712, 1636, 1691, 1702, 1702, 1642, 1664, 1656, 1663, 1700, 1550, 1680, 1665, 1710, 1738, 1613, 1680, 1691, 1661, 1723, 1619, 1561, 1681, 1719, 1689, 1584, 1642, 1573, 1648, 1644, 1769, 1819, 1677, 1699, 1789, 1742, 1601, 1570, 1627, 1680, 1659, 1606, 1596, 1591, 1648, 1680, 1754, 1695, 1623, 1670, 1595, 1774, 1744, 1725, 1699, 1696, 1743, 1648, 1579, 1742, 1590, 1725, 1623, 1649, 1667, 1654, 1612, 1581, 1648, 1569, 1623, 1653, 1585, 1749, 1599, 1748, 1680, 1601, 1713, 1590, 1743, 1711, 1677, 1687, 1701, 1712, 1650, 1661, 1641, 1635, 1671, 1691, 1728, 1621, 1618, 1618, 1616, 1651, 1647, 1716, 1513, 1616, 1695, 1611, 1680, 1706, 1559, 1691, 1669, 1691, 1575, 1615, 1658, 1650, 1718, 1761, 1690, 1648, 1637, 1657, 1665, 1514, 1670, 1575, 1639, 1683, 1738, 1741, 1733, 1557, 1623, 1740, 1711, 1743, 1663, 1630, 1759, 1701, 1639, 1636, 1627, 1552, 1649, 1549, 1729, 1551, 1685, 1552, 1754, 1639, 1647, 1631, 1731, 1605, 1639, 1639, 1676, 1729, 1615, 1584, 1597, 1633, 1651, 1566, 1674, 1778, 1632, 1794, 1657, 1623, 1687, 1646, 1753, 1703, 1663, 1668, 1731, 1686, 1634, 1658, 1616, 1569, 1667, 1712, 1672, 1647, 1646, 1653, 1671, 1727, 1603, 1744, 1726, 1671, 1683, 1662, 1641, 1655, 1584, 1657, 1774, 1647, 1625, 1643, 1702, 1557, 1616, 1617, 1555, 1667, 1675, 1554, 1648, 1783, 1608, 1739, 1580, 1661, 1680, 1669, 1642, 1699, 1699, 1702, 1602, 1677, 1718, 1658, 1674, 1735, 1703, 1680, 1702, 1579, 1701, 1690, 1553, 1744, 1691, 1662, 1622, 1654, 1648, 1599, 1654, 1648, 1675, 1683, 1711, 1652, 1603, 1600, 1690, 1652, 1689, 1579, 1633, 1773, 1766, 1631, 1698, 1707, 1692, 1721, 1629, 1595, 1666, 1562, 1617, 1827, 1649, 1747, 1615, 1715, 1645, 1706, 1737, 1658, 1730, 1702, 1639, 1689, 1666, 1673, 1627, 1726, 1753, 1618, 1697, 1706, 1661, 1582, 1313, 1608, 1653, 1690, 1671, 1645, 1687, 1583, 1702, 1711, 1694, 1762, 1699, 1609, 1718, 1691, 1695, 1647, 1568, 1651, 1720, 1643, 1552, 1675, 1712, 1609, 1666, 1757, 1695, 1723, 1666, 1711, 1577, 1677, 1555, 1699, 1619, 1577, 1645, 1670, 1637, 1690, 1646, 1654, 1696, 1677, 1683, 1676, 1645, 1692, 1717, 1549, 1582, 1659, 1718, 1629, 1570, 1718, 1693, 1725, 1739, 1605, 1594, 1743, 1619, 1618, 1648, 1633, 1728, 1710, 1648, 1648, 1728, 1685, 1715, 1603, 1598, 1773, 1567, 1610, 1770, 1731, 1678, 1744, 1602, 1648, 1648, 1616, 1648, 1731, 1717, 1670, 1690, 1666, 1696, 1673, 1648, 1727, 1665, 1661, 1719, 1645, 1712, 1559, 1657, 1666, 1719, 1616, 1600, 1618, 1717, 1637, 1655, 1623, 1637, 1637, 1595, 1713, 1676, 1753, 1622, 1632, 1774, 1744, 1590, 1685, 1617, 1731, 1654, 1589, 1653, 1637, 1603, 1705, 1690, 1623, 1664, 1645, 1749, 1671, 1667, 1746, 1643, 1670, 1744, 1715, 1558, 1627, 1685, 1635, 1560, 1747, 1693, 1616, 1552, 1761, 1669, 1683, 1657, 1710, 1634, 1642, 1626, 1680, 1685, 1675, 1669, 1590, 1735, 1637, 1663, 1685, 1664, 1683, 1665, 1714, 1633, 1609, 1651, 1696, 1679, 1733, 1727, 1633, 1569, 1653]\n", + "# led on, sensor over thinkpad keyboard space bar\n", + "data_keyboard = [1501, 1693, 1715, 1811, 1750, 0, 1250, 1790, 1661, 1943, 1690, 1645, 4095, 2615, 0, 31, 4095, 1531, 2494, 1650, 4095, 0, 3280, 595, 1519, 2001, 1555, 0, 1129, 3077, 1557, 0, 1746, 2062, 1801, 1680, 1410, 2133, 3280, 0, 0, 0, 1370, 4095, 0, 4095, 2800, 2190, 0, 4095, 4095, 1595, 4095, 1458, 1563, 1794, 1557, 3906, 1547, 1571, 1745, 0, 2667, 0, 1472, 0, 1142, 1511, 1454, 0, 3919, 195, 1680, 1989, 1827, 1853, 4066, 1562, 1648, 1601, 3861, 1425, 1489, 1610, 3978, 2918, 1680, 1722, 0, 2000, 1345, 1495, 1549, 0, 1992, 0, 1520, 1607, 1526, 1639, 1663, 1648, 1637, 1523, 1488, 109, 845, 1717, 1620, 0, 925, 0, 1722, 1703, 1743, 1631, 4095, 0, 1566, 1760, 1559, 1600, 1522, 1510, 1669, 13, 1443, 1696, 1578, 1825, 1649, 1725, 1646, 2478, 1543, 1689, 1534, 1659, 1779, 1797, 1748, 2065, 1526, 1552, 1829, 1381, 1735, 1102, 0, 1427, 1778, 1519, 1338, 1602, 1635, 1303, 1613, 1823, 1650, 4095, 1542, 1157, 1611, 1231, 1572, 0, 1670, 1521, 1680, 1721, 1739, 1385, 1618, 1526, 1606, 1633, 1459, 1503, 1609, 1589, 2453, 1819, 1616, 1698, 1142, 0, 914, 1595, 1806, 2593, 1223, 1595, 1749, 1505, 1744, 1547, 1647, 607, 1519, 1651, 1600, 1831, 1776, 1242, 1584, 0, 1571, 1579, 1509, 2032, 1423, 368, 3691, 0, 1232, 1663, 0, 1683, 1649, 1648, 1862, 1219, 1439, 1664, 1547, 1535, 1456, 1387, 1676, 2340, 1485, 1493, 1706, 1532, 1840, 1553, 1522, 0, 1293, 1486, 1561, 1535, 1431, 1872, 2165, 1648, 1619, 1611, 1613, 1682, 1449, 1838, 1808, 1815, 1682, 1433, 1745, 1614, 1587, 0, 1524, 455, 1283, 4095, 1546, 1491, 1437, 1423, 1670, 0, 1601, 1713, 1758, 1472, 1727, 1702, 1870, 1707, 1603, 1399, 1715, 1678, 1605, 1666, 2448, 1761, 1388, 1743, 1363, 957, 139, 1579, 1589, 1535, 1441, 1781, 1694, 1643, 1834, 1680, 1770, 2299, 1501, 1594, 1648, 1582, 1088, 1679, 2130, 287, 1837, 949, 1388, 1375, 1567, 1743, 1665, 0, 1386, 1555, 1674, 1810, 1821, 1698, 1930, 462, 262, 1520, 1903, 1532, 1600, 1610, 1456, 2449, 1808, 1840, 1583, 1671, 1565, 1581, 2141, 437, 1829, 1902, 1520, 1973, 1787, 1553, 1641, 1571, 1443, 1699, 2609, 1323, 1310, 1606, 1890, 1830, 1424, 1523, 1774, 1452, 1623, 0, 1037, 1638, 4095, 1458, 1589, 1587, 1682, 1859, 2193, 1035, 1727, 1712, 1485, 1616, 1681, 1662, 1673, 1616, 1626, 1482, 1521, 1613, 1619, 1515, 1574, 3433, 0, 1710, 1522, 1802, 1493, 1591, 1681, 0, 1479, 1747, 1621, 1781, 1616, 1744, 1747, 1023, 1516, 1586, 1360, 1600, 1654, 1727, 1507, 1680, 1703, 1751, 1581, 1381, 1578, 1553, 3159, 0, 1299, 1556, 1631, 1911, 1746, 1621, 1831, 2015, 1521, 1826, 1766, 1565, 1687, 1593, 2011, 2815, 1604, 1533, 1648, 1858, 2469, 1935, 1437, 2256, 1562, 1744, 1712, 1772, 1699, 1573, 1473, 2205, 1583, 1789, 1694, 1668, 1733, 1515, 1744, 1702, 1793, 1894, 1614, 1667, 3998, 1478, 1232, 1887, 1789, 1726, 1623, 1557, 1685, 1808, 1786, 1854, 1821, 1595, 1894, 1687, 1634, 1642, 1679, 1633, 1507, 1591, 1833, 0, 2063, 1648, 2311, 1749, 1447, 1846, 1763, 1432, 1531, 1364, 1456, 1125, 1872, 1519, 384, 1715, 0, 1455, 1584, 0, 1767, 1910, 1840, 1495, 1757, 1693, 1767, 0, 1390, 1711, 1458, 1614, 2027, 1734, 1595, 0, 1408, 2438, 1824, 1762, 1811, 1605, 2519, 368, 1679, 1639, 1835, 1535, 1740, 1712, 1535, 1797, 2142, 1558, 1413, 1746, 1549, 1778, 1748, 2015, 784, 1901, 1547, 1638, 2023, 1584, 1935, 1280, 1414, 976, 1680, 1591, 1854, 1817, 1770, 1680, 1683, 1547, 1446, 1600, 1474, 1306, 1398, 1744, 1754, 1648, 1744, 1871, 1351, 1774, 1661, 0, 1775, 1669, 1616, 1776, 1759, 1808, 1644, 1909, 4095, 1327, 1427, 1659, 1655, 1718, 2031, 1646, 1736, 1600, 1794, 1819, 1918, 1720, 1477, 0, 1535, 1610, 1675, 509, 1743, 1766, 1563, 981, 1643, 3815, 1520, 4095, 1392, 2287, 1745, 7, 1730, 1699, 2704, 1792, 1725, 2311, 2409, 0, 1410, 1653, 1669, 1723, 1644, 1711, 1584, 779, 1730, 1707, 1664, 1829, 1631, 1763, 2711, 0, 0, 912, 2202, 1680, 1398, 1904, 1530, 0, 1583, 1770, 1804, 1556, 1469, 1661, 4095, 1490, 1723, 1450, 4095, 1614, 1714, 859, 1717, 1722, 1762, 567, 1669, 1569, 1550, 1622, 1648, 2486, 1776, 1765, 1727, 1410, 1630, 1683, 1723, 1151, 1458, 1587, 1675, 1520, 0, 4095, 834, 1662, 1483, 1696, 1915, 1581, 1654, 1779, 1469, 1721, 1958, 1697, 1749, 1887, 1494, 465, 1551, 0, 1671, 1920, 1600, 1472, 1493, 1686, 1862, 0, 1451, 1672, 1763, 1811, 1899, 1667, 2339, 48, 1591, 2069, 1790, 1653, 1843, 1455, 1580, 0, 1382, 1610, 1791, 1877, 1596, 1738, 1712, 0, 1508, 0, 1023, 1808, 1553, 1700, 1729, 38, 1561, 1891, 1491, 1667, 1581, 1601, 1852, 731, 1610, 1881, 970, 1929, 1566, 1703, 1386, 1166, 1589, 4095, 1557, 1783, 1488, 1821, 1710, 1764, 2257, 2331, 1419, 1654, 1759, 1667, 1630, 1721, 1779, 1841, 1443, 1702, 1645, 1443, 1350, 0, 4081, 592, 1566, 1602, 694, 1792, 1744, 1475, 1606, 1040, 0, 4095, 1666, 1677, 1877, 1840, 1449, 4095, 1663, 2025, 1670, 1830, 1638, 0, 1473, 1723, 1738, 1729, 1406, 1751, 2875, 0, 1745, 1705, 1619, 1927, 1389, 1648, 2331, 1067, 1375, 1511, 1290, 1838, 1617, 1776, 1721, 0, 1471, 1415, 0, 1557, 89, 1680, 283, 779, 1470, 1501, 1784, 1683, 1759, 1595, 1664, 1335, 1813, 1876, 1868, 1667, 1665, 1951, 1654, 0, 1666, 1557, 1758, 1575, 1559, 1734, 1643, 1391, 1813, 1763, 1616, 1499, 1776, 1424, 1648, 1523, 1767, 1795, 1531, 1392, 1630, 1399, 1678, 1089, 1439, 1445, 1825, 1681, 0, 0, 779, 2320, 791, 1535, 2352, 1789, 1600, 1863, 1584, 1699, 1617, 1520, 1648, 1795, 0, 0, 1686, 1670, 1565, 1751, 1578, 1702, 1761, 1616, 2557, 848, 832, 1467, 1754, 1649, 1769, 2103, 1646, 22, 1596, 1585, 1839, 1643, 1894, 1587, 0, 0, 1488, 1402, 1559, 1622, 1450, 1882, 1475, 0, 1551, 1666, 1008, 1889, 1555, 583, 1942, 254, 1575, 1901, 1513, 1831, 1913, 1645, 1681, 961, 1520, 1890, 1487, 1647, 1940, 1535, 1810, 180, 1552, 1692, 1360, 1727, 1620, 1670, 1733, 1099, 1546, 1424, 1717, 1581, 1392, 1741, 2000, 1782, 1718, 1754, 1471, 1754, 1607, 1386, 1542, 1530, 1523, 1955, 1433, 1718, 1559, 1691, 1419, 49, 1410, 1563, 1870, 1833, 1333, 1616, 1661, 1711, 1599, 1631, 1950, 1782, 1635, 1855, 1911, 1744, 1418, 1648, 1456, 1488, 4095, 1735, 1737, 1040, 1727, 1551]\n", + "\n", + "# ring upstairs, thr=250\n", + "#capture = [1792, 1890, 2014, 1888, 1770, 1862, 1888, 1857, 1817, 1967, 1714, 1665, 1739, 1714, 1674, 1666, 1651, 1730, 1587, 1681, 1690, 1631, 1729, 1727, 1663, 1663, 1744, 1639, 1729, 1658, 1674, 1710, 1654, 1763, 1651, 1696, 1693, 1662, 1773, 1655, 1646, 1661, 1744, 1667, 1611, 1655, 1680, 1695, 1642, 1716, 1707, 1610, 1594, 1600, 1650, 1605, 1710, 1737, 1621, 1669, 1669, 1771, 1687, 1663, 1629, 1678, 1607, 1675, 1693, 1721, 1551, 1728, 1590, 1650, 1607, 1715, 1771, 1631, 1703, 1626, 1634, 1664, 1691, 1654, 1640, 1691, 1527, 1647, 1740, 1659, 1713, 1630, 1682, 1643, 1613, 1622, 1599, 1555, 1601, 1680, 1613, 1693, 1655, 1635, 1651, 1683, 1673, 1533, 1745, 1684, 1689, 1673, 1647, 1680, 1725, 1663, 1687, 1710, 1711, 1639, 1703, 1677, 1642, 1687, 1617, 1681, 1715, 1651, 1664, 1600, 1584, 1619, 1623, 1715, 1565, 1654, 1594, 1751, 1760, 1646, 1691, 1714, 1726, 1682, 1614, 1659, 1689, 1625, 1627, 1776, 1694, 1699, 1766, 1616, 1680, 1651, 1669, 1747, 1695, 1675, 1567, 1681, 1680, 1648, 1818, 1664, 1658, 1648, 1707, 1678, 1645, 1680, 1687, 1744, 1617, 1677, 1627, 1639, 1680, 1674, 1664, 1680, 1743, 1616, 1675, 1697, 1615, 1779, 1680, 1746, 1662, 1664, 1621, 1552, 1751, 1674, 1745, 1680, 1673, 1633, 1729, 1667, 1666, 1653, 1649, 1707, 1606, 1669, 1747, 1683, 1674, 1685, 1579, 1585, 1669, 1713, 1657, 1651, 1680, 1559, 1680, 1621, 1535, 1649, 1644, 1713, 1651, 1658, 1671, 1648, 1707, 1682, 1641, 1678, 1647, 1735, 1643, 1747, 1745, 1808, 1568, 1655, 1671, 1622, 1581, 1595, 1695, 1686, 1687, 1597, 1749, 1616, 1747, 1638, 1786, 1750, 1680, 1668, 1679, 1617, 1854, 1610, 1702, 1674, 1614, 1661, 1589, 1682, 1595, 1552, 1692, 1711, 1660, 1600, 1663, 1654, 1745, 1601, 1715, 1767, 1643, 1630, 1574, 1598, 1664, 1671, 1643, 1707, 1718, 1591, 1716, 1710, 1704, 1582, 1584, 1664, 1707, 1739, 1709, 1589, 1582, 1651, 1621, 1705, 1717, 1626, 1643, 1734, 1682, 1641, 1680, 1754, 1590, 1709, 1685, 1667, 1647, 1709, 1667, 1744, 1590, 1712, 1722, 1628, 1678, 1646, 1693, 1635, 1662, 1728, 1701, 1626, 1717, 1603, 1529, 1606, 1700, 1733, 1604, 1575, 1654, 1726, 1697, 1595, 1634, 1638, 1667, 1663, 1616, 1709, 1693, 1580, 1725, 1826, 1671, 1653, 1632, 1719, 1698, 1654, 1658, 1693, 1600, 1595, 1649, 1603, 1679, 1637, 1673, 1737, 1648, 1555, 1775, 1685, 1707, 1663, 1686, 1594, 1754, 1805, 1730, 1590, 1745, 1689, 1622, 1638, 1655, 1680, 1583, 1663, 1672, 1679, 1677, 1687, 1601, 1550, 1650, 1647, 1703, 1715, 1712, 1633, 1661, 1673, 1675, 1642, 1616, 1613, 1616, 1667, 1650, 1744, 1668, 1664, 1680, 1655, 1675, 1586, 1584, 1683, 1631, 1631, 1646, 1619, 1635, 1641, 1651, 1621, 1712, 1601, 1661, 1584, 1662, 1719, 1617, 1681, 1793, 1754, 1691, 1728, 1626, 1754, 1681, 1571, 1676, 1712, 1639, 1648, 1727, 1651, 1691, 1617, 1754, 1607, 1712, 1682, 1706, 1637, 1609, 1666, 1664, 1637, 1626, 1669, 1705, 1715, 1675, 1717, 1663, 1531, 1733, 1679, 1722, 1648, 1578, 1603, 1803, 1737, 1651, 1642, 1627, 1680, 1725, 1745, 1620, 1657, 1699, 1685, 1505, 1638, 1742, 1670, 1730, 1676, 1691, 1639, 1637, 1619, 1679, 1771, 1646, 1648, 1744, 1775, 1581, 1651, 1618, 1666, 1665, 1692, 1675, 1680, 1597, 1683, 1711, 1639, 1697, 1655, 1723, 1675, 1594, 1631, 1627, 1664, 1729, 1679, 1706, 1637, 1616, 1712, 1759, 1646, 1694, 1653, 1633, 1710, 1725, 1575, 1621, 1613, 1582, 1590, 1699, 1744, 1680, 1760, 1681, 1704, 1579, 1717, 1712, 1604, 1663, 1665, 1663, 1707, 1641, 1616, 1648, 1635, 1562, 1958, 1669, 1721, 1645, 1743, 1648, 1605, 2006, 1644, 1663, 1701, 1583, 1677, 1659, 1744, 1709, 1728, 1635, 1686, 1570, 1610, 1729, 1667, 1638, 1619, 1664, 1702, 1686, 1643, 1628, 1680, 1603, 1615, 1594, 1600, 1577, 1522, 1727, 1664, 1680, 1611, 1716, 1642, 1629, 1665, 1630, 1678, 1655, 1594, 1552, 1648, 1665, 1675, 1741, 1635, 1649, 1680, 1667, 1584, 1629, 1584, 1597, 1680, 1692, 1655, 1584, 1691, 1614, 1753, 1722, 1637, 1594, 1673, 1649, 1628, 1645, 1786, 1648, 1744, 1591, 1660, 1577, 1666, 1706, 1728, 1709, 1639, 1666, 1673, 1682, 1662, 1649, 1729, 1677, 1638, 1651, 1803, 1731, 1719, 1666, 1648, 1643, 1655, 1725, 1697, 1734, 1614, 1655, 1647, 1731, 1786, 1618, 1706, 1716, 1552, 1648, 1616, 1645, 1755, 1616, 1696, 1723, 1683, 1635, 1683, 1794, 1600, 1692, 1741, 1712, 1690, 1648, 1609, 1663, 1727, 1646, 1725, 1696, 1686, 1617, 1649, 1682, 1680, 1719, 1575, 1659, 1638, 1712, 1593, 1779, 1680, 1722, 1607, 1680, 1699, 1759, 1645, 1661, 1661, 1616, 1668, 1616, 1750, 1761, 1680, 1743, 1697, 1613, 1629, 1682, 1669, 1581, 1643, 1617, 1627, 1712, 1702, 1778, 1630, 1662, 1621, 1680, 1648, 1674, 1514, 1615, 1557, 1639, 1623, 1703, 1664, 1680, 1552, 1696, 1659, 1579, 1617, 1689, 1675, 1531, 1655, 1600, 1728, 1587, 1648, 1575, 1671, 1669, 1602, 1649, 1685, 1639, 1643, 1728, 1682, 1655, 1641, 1600, 1679, 1671, 1503, 1750, 1709, 1721, 1614, 1606, 1709, 1682, 1659, 1785, 1653, 1595, 1547, 1712, 1600, 1578, 1666, 1714, 1670, 1683, 1667, 1631, 1651, 1746, 1658, 1611, 1618, 1669, 1713, 1739, 1681, 1690, 1763, 1674, 1621, 1631, 1593, 1616, 1681, 1637, 1619, 1685, 1589, 1637, 1562, 1674, 1716, 1661, 1626, 1733, 1603, 1634, 1674, 1573, 1649, 1574, 1554, 1645, 1616, 1642, 1659, 1761, 1623, 1743, 1637, 1709, 1618, 1719, 1597, 1704, 1744, 1679, 1697, 1644, 1711, 1638, 1675, 1698, 1739, 1597, 1651, 1674, 1728, 1651, 1743, 1771, 1706, 1893, 1667, 1641, 1662, 1815, 1721, 1665, 1747, 1611, 1677, 1661, 1694, 1709, 1751, 1730, 1680, 1776, 1600, 1739, 1696, 1677, 1581, 1766, 1638, 1761, 1773, 1553, 1562, 1605, 1664, 1725, 1600, 1525, 1631, 1605, 1683, 1738, 1634, 1636, 1675, 1552, 1664, 1707, 1745, 1654, 1727, 1666, 1627, 1734, 1613, 1759, 1731, 1584, 1719, 1687, 1681, 1661, 1686, 1575, 1662, 1703, 1738, 1646, 1552, 1664, 1712, 1547, 1702, 1631, 1761, 1651, 1743, 1647, 1729, 1590, 1731, 1689, 1600, 1605, 1723, 1680, 1660, 1658, 1567, 1712, 1602, 1606, 1651, 1572, 1641, 1584, 1665, 1531, 1633, 1680, 1574, 1735, 1651, 1712, 1712, 1629, 1348, 1600, 1495, 1655, 1695, 1872, 1936, 1958, 1911, 1741, 1747, 1897, 1518, 1454, 1462, 1883, 1719, 1680, 1713, 1825, 1606, 1610, 1489, 1840, 1625, 1651, 1621, 1781, 1488, 1809, 1392, 1350, 1655, 1759, 1509, 1825, 1654, 1567, 1551, 1629, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095]\n", + "# ring upstairs, thr=1000\n", + "#capture = [4095, 0, 0, 0, 0, 4095, 4095, 4095, 4095, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 1984, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 1952, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4016, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 3296, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 2606, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 1855, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 3530, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 3184, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 1079, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 3152, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 447, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4032, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 1215, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095]\n", + "# ring downstairs, thr=1000\n", + "captures = [1787, 1953, 1932, 1936, 1898, 1933, 1911, 1872, 1885, 1895, 1749, 1647, 1615, 1706, 1649, 1627, 1674, 1646, 1602, 1632, 1665, 1732, 1647, 1614, 1619, 1744, 1596, 1761, 1569, 1647, 1729, 1649, 1619, 1648, 1694, 1628, 1669, 1653, 1648, 1651, 1707, 1683, 1535, 1641, 1595, 1735, 1711, 1622, 1683, 1691, 1685, 1794, 1650, 1631, 1663, 1687, 1664, 1671, 1697, 1680, 1683, 1769, 1685, 1727, 1705, 1695, 1712, 1725, 1666, 1680, 1679, 1586, 1648, 1605, 1639, 1655, 1631, 1634, 1557, 1610, 1646, 1712, 1643, 1734, 1511, 1694, 1707, 1757, 1659, 1661, 1600, 1669, 1622, 1666, 1646, 1654, 1655, 1698, 1638, 1717, 1616, 1663, 1673, 1623, 1629, 1585, 1718, 1583, 1675, 1648, 1665, 1627, 1528, 1616, 1583, 1637, 1633, 1620, 1579, 1639, 1658, 1644, 1711, 1710, 1419, 1648, 1806, 1679, 1443, 1668, 1771, 1585, 1559, 1745, 1607, 1673, 1623, 1629, 1399, 1639, 1674, 1600, 1534, 1717, 1462, 1579, 1525, 1748, 1662, 1529, 1535, 1866, 1549, 1472, 1683, 1663, 1591, 1519, 1687, 1728, 1530, 1603, 1687, 1598, 1731, 1632, 1647, 1552, 1671, 1692, 1619, 1535, 1614, 1616, 1616, 1611, 1650, 1597, 1648, 1671, 1600, 1563, 1735, 1677, 1619, 1674, 1783, 1648, 1660, 1570, 1655, 1575, 1666, 1648, 1613, 1651, 1771, 1552, 1631, 1584, 1683, 1683, 1725, 1593, 1638, 1643, 1495, 1644, 1562, 1674, 1667, 1700, 1625, 1648, 1642, 1648, 1675, 1628, 1572, 1678, 1691, 1651, 1675, 1611, 1663, 1611, 1676, 1562, 1679, 1607, 1638, 1718, 1664, 1600, 1600, 1669, 1657, 1589, 1670, 1680, 1716, 1711, 1675, 1591, 1570, 1690, 1612, 1680, 1625, 1671, 1718, 1665, 1692, 1557, 1607, 1753, 1635, 1699, 1665, 1675, 1665, 1561, 1637, 1744, 1648, 1900, 1922, 1707, 1641, 1699, 1514, 1781, 1729, 1623, 1643, 1643, 1680, 1786, 1649, 1599, 1695, 1617, 1705, 1734, 1575, 1658, 1530, 1683, 1679, 1520, 1678, 1653, 1586, 1616, 1744, 1638, 1647, 1654, 1614, 1665, 1665, 1653, 1591, 1669, 1654, 1698, 1576, 1623, 1726, 1633, 1699, 1675, 1610, 1711, 1645, 1616, 1713, 1696, 1666, 1624, 1606, 1806, 1516, 1515, 1805, 1611, 1518, 1598, 1921, 1556, 1484, 1711, 1438, 1409, 1623, 1675, 1590, 1486, 1691, 1618, 1520, 1695, 1607, 1646, 1554, 1567, 1510, 1603, 1451, 1747, 1584, 1473, 1589, 1658, 1552, 1474, 1627, 1659, 1557, 4095, 1246, 1578, 1669, 1467, 1411, 1469, 1562, 1616, 1387, 1313, 1573, 1500, 1535, 1488, 1518, 1367, 1569, 1606, 1507, 1565, 1535, 1520, 1486, 1519, 1454, 1494, 1437, 1527, 1527, 1498, 1458, 1535, 1554, 1518, 1511, 1569, 1457, 1584, 1440, 1548, 1553, 1549, 1524, 1526, 1586, 1483, 1519, 1471, 1644, 1504, 1463, 1553, 1521, 1515, 1504, 1526, 1520, 1531, 1558, 1547, 1574, 1616, 1664, 1661, 1593, 1446, 1479, 1458, 1553, 1485, 1569, 1420, 1558, 1493, 1607, 1609, 1623, 1517, 1533, 1552, 1475, 1562, 1510, 1679, 1511, 1550, 1594, 1562, 1584, 1504, 1582, 1456, 1551, 1415, 1473, 1495, 1519, 1574, 1520, 1565, 1435, 1558, 1556, 1533, 1466, 1498, 1523, 1531, 1535, 1557, 1488, 1565, 1463, 1521, 1491, 1471, 1533, 1563, 1534, 1549, 1584, 1552, 1471, 1549, 1571, 1589, 1535, 1531, 1392, 1535, 1558, 1605, 1598, 1555, 1495, 1632, 1555, 1587, 1570, 1455, 1579, 1529, 1485, 1425, 1552, 1505, 1439, 1531, 1510, 1478, 1471, 1577, 1493, 1535, 1552, 1472, 1488, 1600, 1525, 1565, 1489, 1509, 1487, 1517, 1563, 1459, 1599, 1445, 1590, 1552, 1494, 1530, 1566, 1524, 1545, 1345, 1513, 1534, 1518, 1634, 1523, 1454, 1628, 1517, 1505, 1478, 1651, 1616, 1555, 1381, 1581, 1513, 1681, 1481, 1527, 1640, 1492, 1590, 1530, 1488, 1558, 1472, 1526, 1553, 1569, 1515, 1565, 1491, 1535, 1567, 1597, 1584, 1651, 1841, 1554, 1520, 1520, 1511, 1600, 1619, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 415, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 3795, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 3203, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 3518, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 2241, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4090, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4019, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 92, 0, 4095, 0, 4095, 0, 4095, 0, 2639, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 3179, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 3936, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 2303, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095], [4095, 0, 0, 0, 0, 0, 0, 0, 4095, 4095, 0, 3259, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 779, 0, 4095, 0, 4095, 0, 4095, 0, 1565, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 3130, 0, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 2778, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 2096, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 2951, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4028, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 2384, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 2052, 0, 4095, 0, 4095, 0, 4095, 0, 605, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 3920, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 1640, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4039, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4032, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 1488, 0, 4095, 0, 4095, 0, 4095, 0, 981, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 3312, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 720, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 4095, 919, 0, 4095, 0, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 3809, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 1832, 0, 4095, 0, 4095, 0, 4095, 0, 721, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 0, 4095]" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "(array([[1.16263635e+05, 1.17516983e+05, 1.14159440e+05, ...,\n", + " 1.81110593e+05, 1.98501199e+05, 1.90240084e+05],\n", + " [2.32455272e+05, 2.34962883e+05, 2.28249748e+05, ...,\n", + " 3.62114688e+05, 3.96886544e+05, 3.80363971e+05],\n", + " [2.32239396e+05, 2.34749751e+05, 2.28042468e+05, ...,\n", + " 3.61795366e+05, 3.96539170e+05, 3.80015573e+05],\n", + " ...,\n", + " [1.31973095e+01, 7.33739226e+00, 1.49770074e+01, ...,\n", + " 5.68101887e+02, 1.15431061e+01, 2.16135322e+02],\n", + " [1.32081642e+01, 7.35024163e+00, 1.49773133e+01, ...,\n", + " 5.67992560e+02, 1.15598690e+01, 2.16139910e+02],\n", + " [6.60589216e+00, 3.67726423e+00, 7.48870808e+00, ...,\n", + " 2.83978052e+02, 5.78274574e+00, 1.08070693e+02]]),\n", + " array([0.00000000e+00, 2.44140625e-01, 4.88281250e-01, ...,\n", + " 4.99511719e+02, 4.99755859e+02, 5.00000000e+02]),\n", + " array([0.032, 0.064, 0.096, 0.128, 0.16 , 0.192, 0.224, 0.256, 0.288,\n", + " 0.32 , 0.352, 0.384, 0.416, 0.448, 0.48 , 0.512, 0.544, 0.576,\n", + " 0.608, 0.64 , 0.672, 0.704, 0.736, 0.768, 0.8 , 0.832, 0.864,\n", + " 0.896, 0.928, 0.96 , 0.992, 1.024, 1.056, 1.088, 1.12 , 1.152,\n", + " 1.184, 1.216, 1.248, 1.28 , 1.312, 1.344, 1.376, 1.408, 1.44 ,\n", + " 1.472, 1.504, 1.536, 1.568, 1.6 , 1.632, 1.664, 1.696, 1.728,\n", + " 1.76 , 1.792, 1.824, 1.856, 1.888, 1.92 , 1.952, 1.984, 2.016]),\n", + " )" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.specgram(np.array(captures[0] + captures[1]), NFFT=64, noverlap=32, Fs=1000, pad_to=4096)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} -- cgit