In [60]:
from PIL import Image
import numpy as np
import pandas as pd

import sklearn as sk
from sklearn import cluster
from sklearn import linear_model
from scipy.optimize import minimize

from sklearn.cluster import KMeans

import itertools
import os
from itertools import cycle

import scipy.stats as stats
from scipy.misc import factorial

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

import bisect 

import time
import pylab as pl
from IPython import display

import copy

import seaborn as sns

import cv2
import statsmodels.api as sm

%matplotlib inline

sns.set_style('whitegrid')
sns.set_context('poster')

Look for user Actions


In [61]:
threshold = 15  # 15 pixles out of place
                # A log roughlt corresponds to 25 pixles

In [62]:
y_max = 1080 - 864
x_max = 384

def load_image( infilename ) :
    img = Image.open(infilename)
    img.load()
    data = np.asarray( img, dtype="int32" )
    return data

def save_image( npdata, outfilename ) :
    img = Image.fromarray( np.asarray( np.clip(npdata,0,255), dtype="uint8"), "L" )
    img.save( outfilename )

In [63]:
def extract_boundary(original,hsv_image, lower, upper, flag):
    # need end points of the boundary too
    mask = cv2.inRange(hsv_image, lower, upper)
    # Bitwise-AND mask and original image
    res = cv2.bitwise_and(original,original,mask= mask)
    #boundaries in gray scale
    gray = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)
    # Otsu's thresholding and gaussian filtering  to make the logs white and the background black for better detection
    ret2,th2 = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    # Otsu's thresholding after Gaussian filtering
    blur = cv2.GaussianBlur(gray,(5,5),0)
    #logs will be white in th3
    ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    if(flag==1):
        black, extLeft, extRight, cx,cy = find_contour(th3,original)
        return black,extLeft,extRight,cx,cy
    return th3   

#just identify water flow path for drawing graphs   
def detect_water(min_video_frame):
    hsv = cv2.cvtColor(min_video_frame, cv2.COLOR_BGR2HSV)
    # define range of green/yellow color in HSV
    lower_green = np.array([29,86,6])
    upper_green = np.array([64,255,255])
    th3 = extract_boundary(min_video_frame,hsv,lower_green, upper_green,0)    
    store = th3
    # morphing to get the skeletal structure/ medial line of the water flow    
    size = np.size(th3)    
    skel = np.zeros(th3.shape,np.uint8)    
    element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
    done = False
 
    while(not done):
        eroded = cv2.erode(th3,element)
        temp = cv2.dilate(eroded,element)
        temp = cv2.subtract(th3,temp)
        skel = cv2.bitwise_or(skel,temp)
        th3 = eroded.copy()
 
        zeros = size - cv2.countNonZero(th3)
        if zeros==size:
            done = True
    return store,skel

def detect_logs(min_video_frame):
    hsv = cv2.cvtColor(min_video_frame, cv2.COLOR_BGR2HSV)
    # define range of blue color in HSV
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])  
    
    th3 = extract_boundary(min_video_frame,hsv,lower_blue, upper_blue,0)    

    #smooth the logs (current version very fat lines)
    image ,contours, heirarchy = cv2.findContours(th3,1,2)#cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    
#     print(contours)
    
    #Draw log contour + bonding rects
    colored = cv2.cvtColor(image,cv2.COLOR_GRAY2BGR) 
    count =0    
    black = np.zeros(colored.shape)

    return image,[]

09-19 23min game from Andee/Nick/Aditi/Leilah session with CW


In [64]:
cap = cv2.VideoCapture('./2017-09-19T10_01_14-0.mov')
count = 0

logs_minus1 = []
diffs = []
iter_num = 0
images = []
i = 0

while cap.isOpened():
    i+=1
    if i < 6:
        continue
    ret,frame = cap.read()
    
    if ret==True:
        logs,centers = detect_logs(frame[864:1080,0:384])
        logs = logs / 255 # get a 0 or a 1
        if len(logs_minus1) <= 0:
            logs_minus1 = logs
            
        diff = np.linalg.norm(logs_minus1 - logs)
        if diff > threshold:
            diffs.append(iter_num)
            images.append(frame[864:1080,0:384])
            
        logs_minus1 = logs
        iter_num += 1
    else:
        cap.set(1, count-1)
        print("something not working")
        cv2.waitKey(1000)
    if cv2.waitKey(10) == 27:
        break
    if cap.get(1) == cap.get(7):
        break
    if count >= 20:
        break
        
cap.release()

In [65]:
print("There are {number_changes} in the file, each occured at:\n{change_points}".format(
    number_changes = len(diffs),
    change_points = ["%0.2f"%(d/60) for d in diffs]))


There are 136 in the file, each occured at:
['0.10', '0.13', '0.45', '0.48', '0.52', '0.53', '0.55', '0.58', '0.60', '0.62', '0.63', '0.65', '0.67', '0.68', '0.70', '0.72', '0.73', '0.75', '0.77', '0.78', '0.80', '0.82', '0.88', '0.90', '0.93', '0.95', '0.97', '0.98', '1.00', '1.03', '1.13', '1.33', '1.48', '1.75', '1.77', '1.85', '1.90', '2.07', '2.32', '2.33', '2.35', '2.37', '2.38', '2.40', '2.50', '2.52', '2.65', '2.68', '2.73', '4.97', '5.00', '5.02', '5.03', '5.05', '5.15', '5.22', '5.23', '5.52', '5.55', '5.57', '5.58', '5.62', '5.65', '5.70', '6.18', '6.27', '6.28', '6.30', '6.32', '6.33', '6.38', '6.80', '6.85', '6.87', '6.92', '6.93', '7.57', '7.58', '7.60', '7.62', '7.63', '7.78', '7.82', '8.25', '8.27', '8.45', '8.47', '8.70', '8.72', '8.80', '8.85', '10.42', '11.68', '11.98', '12.00', '12.02', '12.03', '12.07', '12.13', '12.17', '12.25', '12.27', '12.28', '12.47', '12.48', '12.67', '12.68', '12.70', '12.73', '13.20', '13.27', '13.33', '13.35', '13.37', '13.38', '13.40', '13.43', '14.00', '14.25', '14.35', '14.42', '14.50', '14.53', '14.55', '14.57', '14.58', '14.65', '14.68', '14.70', '14.72', '15.37', '15.40', '20.10', '20.15', '20.27', '20.30']

In [66]:
fig, ax = plt.subplots(1,1, figsize=(15,2))
data_diffs = {}

for i in diffs:
    ax.axvline(x=i/60, alpha=0.5)
    ax.yaxis.set_visible(False)
    ax.set_xlabel('Events occuring in log movements over time (min)')

data_diffs['df_1'] = diffs
plt.show()



In [67]:
num_rows=min(len(diffs)//2, 8)

fig, axes = plt.subplots(num_rows, 2, figsize=(15, 8*num_rows))
axes = axes.flatten()

for i, ax in enumerate(axes):
    
    ax.set_title('Timestamp: %i'%diffs[i])
    ax.imshow(images[i])
    ax.set_axis_off()

fig.tight_layout()
plt.show()


09-09 1h15 game


In [68]:
cap = cv2.VideoCapture('./2017-09-09T12_08_00-0.mov')
count = 0
log_centers = []
mu, cov = None, None
logs_minus1 = []
diffs = []
iter_num = 0

images = []

while cap.isOpened():
    ret,frame = cap.read()
    
    if ret==True:
#         store, skel = detect_water(frame[864:1080,0:384])
        logs,centers = detect_logs(frame[864:1080,0:384])
        
        logs = logs / 255 # get a 0 or a 1

        if len(logs_minus1) <= 0:
            logs_minus1 = logs
            
        diff = np.linalg.norm(logs_minus1 - logs)
#         print(diff)
        if diff > threshold:
            diffs.append(iter_num)
            images.append(frame[864:1080,0:384])
            
#         plt.imshow(logs)
        logs_minus1 = logs
        iter_num += 1
        
#         cv2.imwrite("frames/frame_log%04d.jpg" % count, logs)
#         count = count + 1
#         log_centers.append(centers)
    else:
        # The next frame is not ready, so we try to read it again
        cap.set(1, count-1)
        print("something not working")
        # It is better to wait for a while for the next frame to be ready
        cv2.waitKey(1000)

    if cv2.waitKey(10) == 27:
        break
    if cap.get(1) == cap.get(7):
        # If the number of captured frames is equal to the total number of frames,
        # we stop
        break
    if count >= 20:
        break
        
cap.release()

In [69]:
print("There are {number_changes} in the file, each occured at:\n{change_points}".format(
    number_changes = len(diffs),
    change_points = ["%0.2f"%(d/60) for d in diffs]))


There are 2016 in the file, each occured at:
['0.10', '0.12', '0.13', '0.30', '0.32', '0.33', '0.35', '0.37', '0.38', '0.40', '0.57', '0.58', '0.60', '0.62', '0.63', '0.67', '0.70', '0.92', '0.95', '0.97', '1.02', '1.08', '1.12', '1.13', '1.18', '1.28', '1.32', '1.42', '1.80', '1.83', '1.85', '1.87', '1.88', '1.90', '1.92', '2.18', '2.20', '2.22', '2.65', '3.70', '3.72', '3.73', '3.75', '3.78', '3.80', '3.87', '3.88', '4.10', '4.12', '4.48', '4.50', '4.60', '5.30', '6.53', '8.38', '8.40', '8.42', '8.97', '8.98', '9.08', '9.35', '9.38', '9.55', '9.75', '9.78', '9.80', '9.98', '10.08', '10.12', '10.13', '10.15', '10.17', '11.20', '11.23', '11.25', '12.43', '13.05', '13.30', '14.37', '14.90', '15.42', '16.28', '16.30', '16.32', '16.33', '17.90', '17.92', '18.00', '18.37', '18.40', '18.43', '18.45', '18.47', '18.50', '18.52', '18.53', '18.55', '18.57', '18.58', '18.60', '18.62', '18.63', '18.65', '18.68', '18.72', '18.75', '18.77', '18.78', '18.80', '18.82', '18.83', '18.85', '18.87', '18.88', '18.93', '18.95', '18.97', '18.98', '19.00', '19.02', '19.03', '19.05', '19.07', '19.08', '19.10', '19.12', '19.13', '19.15', '19.17', '19.27', '19.28', '19.30', '19.32', '19.33', '19.43', '19.45', '19.47', '19.50', '19.52', '19.53', '19.55', '19.57', '19.58', '19.60', '19.62', '19.63', '19.65', '19.67', '19.68', '19.70', '19.72', '19.73', '19.75', '19.77', '19.78', '19.80', '19.82', '19.83', '19.85', '19.88', '19.95', '19.97', '19.98', '20.00', '20.02', '20.03', '20.05', '20.07', '20.08', '20.12', '20.13', '20.15', '20.20', '20.27', '20.28', '20.38', '20.40', '20.47', '20.48', '20.50', '20.53', '20.60', '20.67', '20.73', '20.75', '20.77', '20.78', '20.80', '20.82', '20.83', '20.85', '20.87', '20.88', '20.90', '20.92', '20.93', '20.95', '21.03', '21.05', '21.07', '21.08', '21.10', '21.12', '21.13', '21.15', '21.17', '21.18', '21.20', '21.23', '21.25', '21.27', '21.28', '21.30', '21.32', '21.35', '21.37', '21.38', '21.40', '21.42', '21.43', '21.45', '21.48', '21.50', '21.52', '21.53', '21.55', '21.57', '21.58', '21.60', '21.68', '21.75', '21.77', '21.78', '21.82', '21.83', '21.90', '21.92', '21.93', '22.02', '22.03', '22.05', '22.07', '22.08', '22.10', '22.12', '22.13', '22.17', '22.18', '22.20', '22.22', '22.23', '22.28', '22.30', '22.32', '22.33', '22.35', '22.37', '22.38', '22.40', '22.42', '22.43', '22.50', '22.52', '22.53', '22.55', '22.57', '22.58', '22.62', '22.63', '22.65', '22.67', '22.73', '22.75', '22.77', '22.78', '22.80', '22.82', '22.83', '22.85', '22.87', '22.88', '22.90', '22.97', '23.02', '23.03', '23.05', '23.07', '23.08', '23.10', '23.12', '23.13', '23.15', '23.17', '23.18', '23.20', '23.22', '23.25', '23.27', '23.28', '23.38', '23.40', '23.42', '23.43', '23.45', '23.47', '23.48', '23.50', '23.55', '23.57', '23.58', '23.60', '23.62', '23.63', '23.65', '23.67', '23.68', '23.70', '23.72', '23.73', '23.75', '23.77', '23.78', '23.83', '23.85', '23.87', '23.88', '23.90', '23.92', '23.93', '23.95', '23.97', '23.98', '24.00', '24.02', '24.03', '24.05', '24.07', '24.08', '24.10', '24.12', '24.13', '24.15', '24.17', '24.18', '24.20', '24.22', '24.23', '24.25', '24.27', '24.28', '24.30', '24.32', '24.33', '24.35', '24.38', '24.40', '24.42', '24.43', '24.45', '24.47', '24.48', '24.50', '24.52', '24.53', '24.55', '24.57', '24.58', '24.60', '24.62', '24.63', '24.67', '24.68', '24.70', '24.72', '24.73', '24.75', '24.77', '24.78', '24.80', '24.82', '24.83', '24.85', '24.87', '24.88', '24.90', '24.92', '24.93', '24.95', '24.97', '24.98', '25.00', '25.02', '25.05', '25.07', '25.10', '25.12', '25.13', '25.15', '25.17', '25.18', '25.20', '25.23', '25.27', '25.28', '25.30', '25.32', '25.33', '25.35', '25.37', '25.38', '25.40', '25.42', '25.43', '25.45', '25.47', '25.48', '25.52', '25.53', '25.55', '25.58', '25.60', '25.62', '25.63', '25.65', '25.67', '25.68', '25.70', '25.72', '25.73', '25.75', '25.77', '25.78', '25.80', '25.82', '25.83', '25.85', '25.87', '25.88', '25.90', '25.92', '25.93', '25.95', '25.97', '25.98', '26.00', '26.02', '26.03', '26.05', '26.07', '26.08', '26.10', '26.12', '26.15', '26.17', '26.18', '26.22', '26.25', '26.28', '26.42', '26.43', '26.50', '26.52', '26.53', '26.55', '26.57', '26.58', '26.60', '26.62', '26.65', '26.67', '26.68', '26.70', '26.72', '26.73', '26.75', '26.77', '26.78', '26.80', '26.82', '26.85', '26.87', '26.88', '26.90', '26.92', '26.93', '26.95', '26.97', '26.98', '27.00', '27.02', '27.03', '27.05', '27.07', '27.08', '27.10', '27.13', '27.15', '27.17', '27.18', '27.20', '27.22', '27.28', '27.30', '27.32', '27.33', '27.35', '27.37', '27.38', '27.40', '27.42', '27.45', '27.47', '27.48', '27.53', '27.55', '27.57', '27.58', '27.60', '27.62', '27.63', '27.65', '27.67', '27.68', '27.72', '27.73', '27.75', '27.77', '27.78', '27.80', '27.82', '27.83', '27.85', '27.87', '27.88', '27.90', '27.92', '27.95', '27.97', '27.98', '28.00', '28.02', '28.03', '28.05', '28.07', '28.08', '28.10', '28.12', '28.13', '28.15', '28.17', '28.18', '28.20', '28.22', '28.23', '28.25', '28.27', '28.28', '28.35', '28.37', '28.40', '28.42', '28.43', '28.45', '28.47', '28.48', '28.50', '28.52', '28.53', '28.55', '28.57', '28.58', '28.60', '28.62', '28.63', '28.65', '28.68', '28.70', '28.72', '28.73', '28.75', '28.78', '28.80', '28.82', '28.85', '28.87', '28.88', '28.90', '28.92', '28.93', '28.95', '28.97', '28.98', '29.00', '29.02', '29.03', '29.05', '29.08', '29.10', '29.17', '29.18', '29.20', '29.22', '29.25', '29.30', '29.32', '29.33', '29.35', '29.37', '29.38', '29.40', '29.42', '29.43', '29.47', '29.48', '29.52', '29.55', '29.57', '29.58', '29.60', '29.62', '29.65', '29.67', '29.72', '29.77', '29.82', '29.83', '29.87', '29.88', '29.90', '29.92', '29.93', '29.95', '29.97', '29.98', '30.00', '30.02', '30.07', '30.08', '30.10', '30.12', '30.15', '30.18', '30.20', '30.22', '30.23', '30.25', '30.27', '30.28', '30.30', '30.32', '30.33', '30.35', '30.37', '30.38', '30.43', '30.45', '30.47', '30.48', '30.50', '30.52', '30.53', '30.55', '30.57', '30.58', '30.60', '30.62', '30.63', '30.65', '30.68', '30.70', '30.72', '30.73', '30.75', '30.77', '30.78', '30.80', '30.82', '30.83', '30.85', '30.87', '30.88', '30.90', '30.92', '30.93', '30.95', '30.97', '30.98', '31.00', '31.03', '31.07', '31.08', '31.15', '31.20', '31.25', '31.32', '31.33', '31.35', '31.37', '31.38', '31.42', '31.43', '31.45', '31.47', '31.48', '31.50', '31.52', '31.55', '31.57', '31.58', '31.60', '31.62', '31.63', '31.65', '31.67', '31.68', '31.72', '31.75', '31.77', '31.78', '31.80', '31.82', '31.83', '31.85', '31.87', '31.88', '31.90', '31.92', '31.93', '31.97', '31.98', '32.20', '32.22', '32.27', '32.30', '32.32', '32.33', '32.35', '32.37', '32.38', '32.40', '32.42', '32.43', '32.45', '32.47', '32.48', '32.50', '32.52', '32.53', '32.55', '32.57', '32.58', '32.60', '32.62', '32.63', '32.65', '32.68', '32.70', '32.72', '32.73', '32.75', '32.77', '32.80', '32.82', '32.83', '32.85', '32.87', '32.88', '32.90', '32.92', '32.93', '32.95', '32.97', '32.98', '33.03', '33.05', '33.08', '33.12', '33.17', '33.37', '33.40', '33.43', '33.45', '33.47', '33.60', '33.65', '33.85', '33.87', '33.93', '34.23', '34.25', '34.27', '34.28', '34.30', '34.37', '34.38', '34.40', '34.45', '34.48', '34.52', '34.55', '34.58', '34.60', '34.62', '34.63', '34.65', '34.67', '34.68', '34.72', '34.73', '34.75', '34.77', '34.80', '34.85', '34.87', '34.88', '34.90', '34.93', '35.00', '35.02', '35.03', '35.05', '35.07', '35.08', '35.10', '35.12', '35.15', '35.17', '35.18', '35.20', '35.22', '35.23', '35.25', '35.33', '35.35', '35.37', '35.38', '35.42', '35.43', '35.45', '35.47', '35.48', '35.52', '35.53', '35.55', '35.58', '35.60', '35.62', '35.63', '35.65', '35.67', '35.70', '35.72', '35.73', '35.77', '35.78', '35.80', '35.82', '35.83', '35.85', '35.87', '35.88', '35.90', '35.92', '35.93', '35.95', '35.97', '35.98', '36.03', '36.07', '36.08', '36.10', '36.12', '36.13', '36.15', '36.17', '36.20', '36.22', '36.23', '36.25', '36.27', '36.28', '36.30', '36.32', '36.33', '36.35', '36.37', '36.38', '36.40', '36.47', '36.48', '36.50', '36.53', '36.55', '36.57', '36.58', '36.60', '36.65', '36.67', '36.70', '36.72', '36.73', '36.75', '36.92', '37.13', '37.27', '37.28', '37.30', '37.33', '37.37', '37.57', '37.58', '37.60', '37.62', '37.63', '37.65', '37.67', '37.68', '37.72', '37.73', '37.75', '37.77', '37.78', '37.80', '37.87', '38.32', '38.33', '38.40', '38.47', '38.50', '38.52', '38.53', '38.55', '38.65', '38.67', '38.75', '38.77', '38.93', '38.98', '39.47', '39.52', '39.53', '39.55', '39.57', '39.58', '39.60', '39.62', '39.65', '39.92', '39.97', '40.02', '40.03', '40.05', '40.07', '40.08', '40.12', '40.22', '40.25', '40.30', '40.37', '40.40', '40.43', '40.45', '40.47', '40.48', '40.50', '40.52', '40.55', '40.57', '40.58', '40.60', '40.62', '40.67', '40.68', '40.70', '40.75', '40.77', '40.78', '40.88', '40.90', '40.92', '40.93', '40.97', '41.02', '41.03', '41.05', '41.07', '41.08', '41.10', '41.12', '41.13', '41.17', '41.37', '41.58', '41.88', '41.90', '41.93', '42.02', '42.03', '42.05', '42.13', '42.15', '42.17', '42.20', '42.22', '42.23', '42.25', '42.27', '42.30', '42.33', '42.35', '42.45', '42.47', '42.52', '42.60', '42.65', '42.67', '42.68', '42.77', '42.78', '42.85', '42.87', '42.88', '42.92', '43.08', '43.10', '43.15', '43.20', '43.22', '43.27', '43.35', '43.37', '43.38', '43.40', '43.42', '43.47', '43.48', '43.52', '43.53', '43.55', '43.58', '43.60', '43.62', '43.63', '43.65', '43.67', '43.68', '43.70', '43.72', '43.75', '43.77', '43.85', '43.88', '43.90', '43.92', '43.93', '43.95', '43.97', '43.98', '44.00', '44.02', '44.03', '44.05', '44.07', '44.08', '44.10', '44.12', '44.13', '44.15', '44.18', '44.20', '44.22', '44.23', '44.25', '44.27', '44.28', '44.30', '44.35', '44.37', '44.38', '44.40', '44.42', '44.43', '44.45', '44.47', '44.48', '44.50', '44.52', '44.53', '44.55', '44.57', '44.58', '44.65', '44.67', '44.68', '44.70', '44.73', '44.77', '44.78', '45.07', '45.08', '45.10', '45.12', '45.17', '45.18', '45.20', '45.22', '45.23', '45.25', '45.27', '45.28', '45.30', '45.32', '45.35', '45.37', '45.40', '45.42', '45.43', '45.47', '45.50', '45.52', '45.60', '45.62', '45.63', '45.65', '45.67', '45.68', '45.70', '45.72', '45.73', '45.75', '45.77', '45.78', '45.80', '45.82', '45.83', '45.85', '45.87', '45.90', '45.92', '46.00', '46.02', '46.10', '46.12', '46.13', '46.33', '46.35', '46.37', '46.38', '46.42', '46.43', '46.45', '46.47', '46.48', '46.50', '46.52', '46.53', '46.55', '46.62', '46.63', '46.65', '46.67', '46.68', '46.70', '46.72', '46.73', '46.75', '46.77', '46.78', '46.82', '46.88', '46.90', '46.92', '46.95', '46.97', '46.98', '47.00', '47.02', '47.03', '47.05', '47.23', '47.25', '47.40', '47.43', '47.47', '47.48', '47.53', '47.55', '47.57', '47.62', '47.70', '47.72', '47.73', '47.75', '47.77', '47.78', '47.80', '47.82', '47.83', '47.85', '47.87', '47.88', '47.90', '48.02', '48.03', '48.17', '48.20', '48.23', '48.27', '48.28', '48.30', '48.32', '48.33', '48.35', '48.37', '48.42', '48.43', '48.62', '48.67', '48.78', '48.85', '48.88', '48.90', '48.92', '48.95', '49.30', '49.38', '49.40', '49.45', '49.47', '49.48', '49.50', '49.55', '49.83', '49.85', '49.88', '50.02', '50.03', '50.05', '50.07', '50.08', '50.10', '50.12', '50.13', '50.17', '50.22', '50.38', '50.40', '50.42', '50.43', '50.45', '50.47', '50.48', '50.50', '50.52', '50.53', '50.57', '50.58', '50.62', '50.63', '50.72', '50.75', '50.77', '50.85', '50.87', '50.88', '50.92', '50.93', '50.95', '50.97', '50.98', '51.00', '51.02', '51.03', '51.05', '51.07', '51.08', '51.10', '51.12', '51.13', '51.15', '51.17', '51.18', '51.20', '51.22', '51.23', '51.25', '51.27', '51.28', '51.30', '51.32', '51.33', '51.35', '51.38', '51.40', '51.45', '51.47', '51.48', '51.60', '51.62', '51.63', '51.65', '51.67', '51.68', '51.70', '51.72', '51.73', '51.75', '51.77', '51.78', '51.80', '51.82', '51.83', '51.85', '51.87', '51.90', '51.95', '51.98', '52.00', '52.02', '52.07', '52.08', '52.10', '52.12', '52.13', '52.17', '52.20', '52.23', '52.25', '52.30', '52.32', '52.33', '52.35', '52.40', '52.42', '52.43', '52.50', '52.58', '52.62', '52.63', '52.65', '52.67', '52.68', '52.72', '52.78', '52.82', '52.83', '52.85', '52.87', '52.90', '52.92', '52.93', '52.98', '53.00', '53.02', '53.03', '53.05', '53.12', '53.13', '53.22', '53.25', '53.27', '53.28', '53.30', '53.32', '53.37', '53.38', '53.40', '53.42', '53.43', '53.45', '53.47', '53.48', '53.50', '53.53', '53.57', '53.58', '53.60', '53.62', '53.65', '53.83', '53.92', '54.00', '54.07', '54.08', '54.10', '54.12', '54.13', '54.15', '54.17', '54.22', '54.25', '54.27', '54.28', '54.32', '54.35', '54.37', '54.42', '54.43', '54.45', '54.47', '54.50', '54.52', '54.53', '54.57', '54.58', '54.60', '54.62', '54.63', '54.65', '54.67', '54.70', '54.80', '54.82', '54.83', '54.88', '54.90', '54.92', '54.93', '54.95', '54.97', '54.98', '55.02', '55.05', '55.07', '55.08', '55.10', '55.12', '55.13', '55.20', '55.22', '55.23', '55.27', '55.28', '55.30', '55.32', '55.33', '55.35', '55.45', '55.47', '55.48', '55.50', '55.52', '55.53', '55.60', '55.62', '55.63', '55.65', '55.77', '55.80', '55.82', '55.83', '55.85', '55.87', '55.90', '55.92', '55.95', '55.97', '56.00', '56.05', '56.07', '56.08', '56.10', '56.12', '56.15', '56.17', '56.18', '56.40', '56.42', '56.43', '56.48', '56.50', '56.52', '56.55', '56.57', '56.58', '56.60', '56.62', '56.63', '56.65', '56.67', '56.68', '56.70', '56.72', '56.73', '56.75', '56.77', '56.78', '56.80', '56.82', '56.83', '56.85', '56.87', '56.88', '56.90', '56.92', '56.95', '56.98', '57.02', '57.05', '57.08', '57.10', '57.12', '57.13', '57.15', '57.17', '57.27', '57.28', '57.30', '57.32', '57.33', '57.35', '57.37', '57.40', '57.42', '57.43', '57.45', '57.47', '57.48', '57.55', '57.57', '57.62', '57.65', '57.67', '57.68', '57.75', '57.77', '57.82', '57.97', '57.98', '58.00', '58.07', '58.17', '58.18', '58.35', '58.37', '58.38', '58.43', '58.45', '58.50', '58.55', '58.57', '58.67', '58.70', '58.77', '58.78', '58.80', '58.82', '58.83', '58.85', '58.87', '58.88', '58.90', '58.92', '58.93', '58.95', '58.97', '58.98', '59.00', '59.02', '59.03', '59.05', '59.07', '59.08', '59.10', '59.12', '59.13', '59.15', '59.17', '59.20', '59.22', '59.23', '59.25', '59.27', '59.28', '59.30', '59.32', '59.33', '59.37', '59.40', '59.42', '59.43', '59.45', '59.47', '59.48', '59.50', '59.52', '59.53', '59.55', '59.57', '59.58', '59.60', '59.62', '59.63', '59.67', '59.68', '59.70', '59.72', '59.73', '59.75', '59.78', '59.80', '59.82', '59.83', '59.85', '59.87', '59.88', '59.90', '59.93', '59.95', '59.97', '59.98', '60.00', '60.03', '60.08', '60.15', '60.17', '60.18', '60.22', '60.23', '60.25', '60.27', '60.32', '60.38', '60.47', '60.48', '60.50', '60.52', '60.53', '60.55', '60.57', '60.58', '60.60', '60.62', '60.63', '60.65', '60.82', '60.87', '60.93', '60.95', '60.98', '61.03', '61.05', '61.07', '61.10', '61.13', '61.15', '61.17', '61.20', '61.22', '61.23', '61.28', '61.30', '61.32', '61.50', '61.52', '61.53', '61.55', '61.68', '61.70', '61.72', '61.73', '61.75', '61.77', '61.78', '61.80', '61.82', '61.83', '61.87', '61.88', '61.90', '61.93', '61.95', '61.98', '62.00', '62.02', '62.03', '62.05', '62.07', '62.10', '62.12', '62.13', '62.15', '62.17', '62.18', '62.22', '62.23', '62.25', '62.27', '62.32', '62.33', '62.40', '62.42', '62.72', '63.05', '63.08', '63.10', '63.12', '63.13', '63.15', '63.27', '63.38', '63.40', '63.43', '63.45', '63.50', '63.82', '63.87', '63.88', '64.00', '64.02', '64.03', '64.10', '64.12', '64.13', '64.20', '64.22', '64.25', '64.27', '64.28', '64.32', '64.62', '64.63', '64.65', '64.67', '64.68', '64.70', '64.72', '64.73', '64.75', '64.77', '64.78', '64.82', '64.87', '64.88', '64.95', '65.27', '65.33', '65.35', '65.38', '65.50', '65.53', '65.55', '65.57', '65.58', '65.60', '65.62', '65.63', '65.65', '65.67', '65.75', '65.78', '65.83', '65.85', '65.87', '65.88', '65.90', '65.92', '65.93', '65.95', '65.97', '66.17', '66.18', '66.23', '66.25', '66.27', '66.28', '66.30', '66.35', '66.38', '66.67', '66.87', '66.88', '66.90', '66.97', '67.00', '67.02', '67.03', '67.13', '67.17', '67.30', '67.38', '67.40', '67.45', '67.48', '67.50', '67.52', '67.53', '67.65', '67.68', '67.70', '67.72', '67.75', '67.77', '67.80', '67.82', '67.83', '67.85', '67.87', '67.88', '67.90', '67.92', '67.93', '68.05', '68.07', '68.08', '68.12', '68.18', '68.35', '68.45', '68.47', '68.48', '68.50', '68.52', '68.53', '68.55', '68.57', '68.58', '68.60', '68.62', '68.63', '68.65', '68.68', '68.70', '68.77', '68.78', '68.80', '68.82', '68.85', '68.87', '68.88', '68.90', '68.92', '68.93', '69.03', '69.13', '69.23', '69.40', '69.43', '69.45', '69.47', '69.50', '69.53', '69.55', '69.57', '69.58', '69.60', '69.65', '69.73', '69.75', '69.87', '69.88', '69.92', '69.93', '69.97', '69.98', '70.02', '70.03', '70.05', '70.07', '70.08', '70.13', '70.18', '70.20', '70.22', '70.23', '70.25', '70.27', '70.28', '70.30', '70.32', '70.33', '70.35', '70.37', '70.38', '70.52', '70.57', '70.58', '70.60', '70.68', '70.70', '70.73', '70.75', '70.77', '70.83', '70.85', '70.87', '70.88', '70.90', '70.92', '70.93', '70.95', '71.03', '71.05', '71.07', '71.08', '71.10', '71.12', '71.13', '71.15', '71.17', '71.18', '71.20', '71.22', '71.23', '71.25', '71.27', '71.28', '71.30', '71.32', '71.33', '71.35', '71.37', '71.42', '71.43', '71.45', '71.47', '71.48', '71.50', '71.52', '71.53', '71.55', '71.57', '71.58', '71.60', '71.62', '71.68', '71.87', '71.88', '71.90', '71.92', '71.97', '72.08', '72.10', '72.12', '72.13', '72.15', '72.17', '72.18', '72.20', '72.38', '72.40', '72.42', '72.43', '72.47', '72.60', '72.67', '72.73', '72.85', '72.90', '73.17', '73.20', '73.23', '73.40', '73.42', '73.52', '73.53', '73.55', '73.57', '73.58', '73.63', '73.65', '73.67', '73.68', '73.70', '73.72', '73.73', '73.75', '73.77', '73.78', '73.82', '73.83', '73.85', '73.87', '73.88', '73.93', '73.98', '74.02', '74.03', '74.05', '74.07', '74.08', '74.10', '74.12', '74.13', '74.15', '74.17', '74.18', '74.20', '74.22', '74.23', '74.25', '74.28', '74.30', '74.33', '74.37', '74.40', '74.45', '74.50', '74.67', '74.68', '74.70', '74.77', '74.78', '74.80', '74.82', '74.83', '74.85', '74.87', '74.88', '74.92', '75.45', '75.47', '75.52', '75.53', '75.55', '75.57']

In [70]:
fig, ax = plt.subplots(1,1, figsize=(15,2))

for i in diffs:
    ax.axvline(x=i/60, alpha=0.1)
    ax.yaxis.set_visible(False)
    ax.set_xlabel('Events occuring in log movements over time (min)')

data_diffs['df_2'] = diffs
plt.show()



In [71]:
num_rows=min(len(diffs)//2, 8)

fig, axes = plt.subplots(num_rows, 2, figsize=(15, 8*num_rows))
axes = axes.flatten()

for i, ax in enumerate(axes):
    
    ax.set_title('Timestamp: %i'%diffs[i])
    ax.imshow(images[i])
    ax.set_axis_off()

fig.tight_layout()
plt.show()


10_13 Teacher Prototype Game


In [72]:
cap = cv2.VideoCapture('./2017-09-01T13_16_45-2.mov')
count = 0

logs_minus1 = []
diffs = []
iter_num = 0

images = []
i = 0

while cap.isOpened():
    i+=1
    if i < 6:
        continue
    ret,frame = cap.read()
    
    if ret==True:
        logs,centers = detect_logs(frame[864:1080,0:384])
        logs = logs / 255 # get a 0 or a 1
        if len(logs_minus1) <= 0:
            logs_minus1 = logs
            
        diff = np.linalg.norm(logs_minus1 - logs)
        if diff > threshold:
            diffs.append(iter_num)
            images.append(frame[864:1080,0:384])
            
        logs_minus1 = logs
        iter_num += 1
    else:
        cap.set(1, count-1)
        print("something not working")
        cv2.waitKey(1000)
    if cv2.waitKey(10) == 27:
        break
    if cap.get(1) == cap.get(7):
        break
    if count >= 20:
        break
        
cap.release()

In [73]:
print("There are {number_changes} in the file, each occured at:\n{change_points}".format(
    number_changes = len(diffs),
    change_points = ["%0.2f"%(d/60) for d in diffs]))


There are 309 in the file, each occured at:
['0.02', '0.13', '0.15', '0.17', '0.22', '0.23', '0.27', '0.30', '0.32', '0.33', '0.35', '0.45', '0.47', '0.48', '0.50', '0.52', '0.53', '0.55', '0.57', '0.58', '0.60', '0.62', '0.65', '0.67', '0.70', '0.72', '0.73', '0.75', '0.80', '0.82', '0.85', '0.88', '0.90', '0.95', '0.97', '1.12', '1.13', '1.15', '1.17', '1.23', '1.25', '1.27', '1.30', '1.32', '1.33', '1.35', '1.42', '1.43', '1.45', '1.53', '1.55', '1.58', '1.62', '1.63', '1.65', '1.68', '1.70', '1.72', '1.73', '1.75', '1.77', '1.87', '1.88', '1.92', '1.93', '1.95', '1.98', '2.00', '2.08', '2.10', '2.15', '2.17', '2.18', '2.22', '2.23', '2.25', '2.27', '2.30', '2.38', '2.40', '2.42', '2.45', '2.47', '2.52', '2.63', '2.73', '2.75', '2.78', '2.82', '2.87', '2.88', '2.90', '2.92', '2.93', '2.95', '2.97', '2.98', '3.00', '3.02', '3.05', '3.07', '3.08', '3.10', '3.12', '3.13', '3.15', '3.17', '3.18', '3.22', '3.25', '3.27', '3.28', '3.30', '3.47', '3.58', '3.72', '3.93', '3.97', '3.98', '4.02', '4.12', '4.20', '4.22', '4.28', '4.30', '4.32', '4.33', '4.43', '4.47', '4.50', '4.83', '4.88', '4.90', '5.02', '5.07', '5.08', '5.10', '5.17', '5.22', '5.23', '5.28', '5.30', '5.37', '5.38', '5.53', '5.70', '5.80', '5.83', '5.85', '5.93', '5.95', '5.97', '5.98', '6.00', '6.03', '6.05', '6.07', '6.08', '6.10', '6.12', '6.18', '6.27', '6.32', '6.33', '6.37', '6.38', '6.40', '6.42', '6.45', '6.47', '6.48', '6.52', '6.53', '6.55', '6.60', '6.62', '6.65', '6.68', '6.70', '6.72', '6.77', '7.13', '7.22', '7.25', '7.28', '7.35', '7.37', '7.38', '7.40', '7.48', '7.50', '7.52', '7.53', '7.55', '7.57', '7.58', '7.60', '7.62', '7.63', '7.67', '7.70', '7.72', '7.80', '7.83', '7.85', '7.88', '7.90', '7.92', '7.93', '7.98', '8.00', '8.03', '8.05', '8.07', '8.22', '8.23', '8.60', '8.63', '8.65', '8.67', '8.68', '9.28', '9.30', '9.37', '9.50', '9.53', '9.62', '9.65', '9.73', '9.77', '9.78', '9.80', '9.82', '9.83', '9.85', '9.87', '9.88', '9.90', '9.92', '9.93', '9.95', '9.97', '10.00', '10.02', '10.05', '10.08', '10.30', '10.32', '10.35', '10.37', '10.38', '10.40', '10.42', '10.45', '10.47', '10.48', '10.57', '10.70', '10.72', '10.73', '10.75', '10.78', '10.80', '10.83', '10.85', '10.87', '10.88', '10.93', '10.95', '10.97', '11.05', '11.32', '11.33', '11.42', '11.43', '11.47', '11.50', '11.52', '11.53', '11.55', '11.57', '11.58', '11.60', '11.62', '11.70', '11.73', '11.77', '11.78', '11.80', '11.83', '11.88', '11.90', '11.92', '11.93', '11.97', '11.98', '12.00', '12.02', '12.03', '12.27', '12.32', '12.33', '12.35', '12.37', '12.38', '12.65', '12.68', '12.85', '12.87']

In [74]:
fig, ax = plt.subplots(1,1, figsize=(15,2))

for i in diffs:
    ax.axvline(x=i/60, alpha=0.1)
    ax.yaxis.set_visible(False)
    ax.set_xlabel('Events occuring in log movements over time (min)')

data_diffs['df_3'] = diffs
plt.show()



In [75]:
num_rows=min(len(diffs)//2, 8)

fig, axes = plt.subplots(num_rows, 2, figsize=(15, 8*num_rows))
axes = axes.flatten()

for i, ax in enumerate(axes):
    
    ax.set_title('Timestamp: %i'%diffs[i])
    ax.imshow(images[i])
    ax.set_axis_off()

fig.tight_layout()
plt.show()


09-06 - example of no events


In [76]:
cap = cv2.VideoCapture('./2017-09-06T09_35_14-1.mov')
count = 0

logs_minus1 = []
diffs = []
iter_num = 0

images = []
i = 0

while cap.isOpened():
    i+=1
    if i < 6:
        continue
    ret,frame = cap.read()
    
    if ret==True:
        logs,centers = detect_logs(frame[864:1080,0:384])
        logs = logs / 255 # get a 0 or a 1
        if len(logs_minus1) <= 0:
            logs_minus1 = logs
            
        diff = np.linalg.norm(logs_minus1 - logs)
        if diff > threshold:
            diffs.append(iter_num)
            images.append(frame[864:1080,0:384])
            
        logs_minus1 = logs
        iter_num += 1
    else:
        cap.set(1, count-1)
        print("something not working")
        cv2.waitKey(1000)
    if cv2.waitKey(10) == 27:
        break
    if cap.get(1) == cap.get(7):
        break
    if count >= 20:
        break
        
cap.release()

In [77]:
print("There are {number_changes} in the file, each occured at:\n{change_points}".format(
    number_changes = len(diffs),
    change_points = ["%0.2f"%(d/60) for d in diffs]))

data_diffs['df_4'] = diffs


There are 0 in the file, each occured at:
[]

Now have a look at the CSV files


In [20]:
data_csvs = {}
data_csvs['df_1'] = pd.read_csv("./2017-09-19T10_01_14-0.csv").ix[6:]
data_csvs['df_2'] = pd.read_csv("./2017-09-09T12_08_00-0.csv").ix[6:]
data_csvs['df_3'] = pd.read_csv("./2017-09-01T13_16_45-2.csv").ix[6:]
data_csvs['df_4'] = pd.read_csv("./2017-09-06T09_35_14-1.csv").ix[6:]

for k,v in data_csvs.items():
    data_csvs[k].columns = v.columns.str.strip()

data_csvs['df_1'].head(2)


Out[20]:
Timestamp Time_Remaining Total_Water Total_Alive_Trees Total_Dead_Trees Total_Creatures Desert_Water MountainValley_Water Plains_Water Waterfall_Water ... MountainValley_PlantIndex MountainValley_CreatureIndex Plains_PlantIndex Plains_CreatureIndex Jungle_PlantIndex Jungle_CreatureIndex Reservoir_PlantIndex Reservoir_CreatureIndex Wetlands_PlantIndex Wetlands_CreatureIndex
6 2017-09-19-10-01-20 23:59:54 2.5 0 0 3 0.0 0.080558 0.0 1.96128 ... T5Q1 T20Q10-T21Q30-T23Q2 T28Q1
7 2017-09-19-10-01-21 23:59:53 2.5 0 0 3 0.0 0.075844 0.0 1.95348 ... T5Q1 T20Q12-T21Q60-T23Q2 T28Q1

2 rows × 93 columns


In [21]:
data_csvs['df_1'].columns


Out[21]:
Index(['Timestamp', 'Time_Remaining', 'Total_Water', 'Total_Alive_Trees',
       'Total_Dead_Trees', 'Total_Creatures', 'Desert_Water',
       'MountainValley_Water', 'Plains_Water', 'Waterfall_Water',
       'Floor_Water', 'Jungle_Water', 'Reservoir_Water', 'Wetlands_Water',
       'Desert_Clouds', 'MountainValley_Clouds', 'Plains_Clouds',
       'Waterfall_Clouds', 'Jungle_Clouds', 'Reservoir_Clouds',
       'Wetlands_Clouds', 'Desert_Creatures', 'MountainValley_Creatures',
       'Plains_Creatures', 'Jungle_Creatures', 'Reservoir_Creatures',
       'Wetlands_Creatures', 'Desert_lv1', 'Desert_lv2', 'Desert_lv3',
       'Desert_lv4', 'Plains_lv1', 'Plains_lv2', 'Plains_lv3', 'Plains_lv4',
       'Jungle_lv1', 'Jungle_lv2', 'Jungle_lv3', 'Jungle_lv4', 'Wetlands_lv1',
       'Wetlands_lv2', 'Wetlands_lv3', 'Wetlands_lv4', 'Desert_Dead_lv1',
       'Desert_Dead_lv2', 'Desert_Dead_lv3', 'Desert_Dead_lv4',
       'Desert_Balance', 'Plains_Dead_lv1', 'Plains_Dead_lv2',
       'Plains_Dead_lv3', 'Plains_Dead_lv4', 'Plains_Balance',
       'Jungle_Dead_lv1', 'Jungle_Dead_lv2', 'Jungle_Dead_lv3',
       'Jungle_Dead_lv4', 'Jungle_Balance', 'Wetlands_Dead_lv1',
       'Wetlands_Dead_lv2', 'Wetlands_Dead_lv3', 'Wetlands_Dead_lv4',
       'Wetlands_Balance', 'Desert_Users', 'MountainValley_Users',
       'Plains_Users', 'Jungle_Users', 'Reservoir_Users', 'Wetlands_Users',
       'Desert_WaterBins', 'Desert_FloodBins', 'MountainValley_WaterBins',
       'MountainValley_FloodBins', 'Plains_WaterBins', 'Plains_FloodBins',
       'Jungle_WaterBins', 'Jungle_FloodBins', 'Reservoir_WaterBins',
       'Reservoir_FloodBins', 'Wetlands_WaterBins', 'Wetlands_FloodBins',
       'Desert_PlantIndex', 'Desert_CreatureIndex',
       'MountainValley_PlantIndex', 'MountainValley_CreatureIndex',
       'Plains_PlantIndex', 'Plains_CreatureIndex', 'Jungle_PlantIndex',
       'Jungle_CreatureIndex', 'Reservoir_PlantIndex',
       'Reservoir_CreatureIndex', 'Wetlands_PlantIndex',
       'Wetlands_CreatureIndex'],
      dtype='object')

In [22]:
water_columns = ['Desert_Water', 'Plains_Water', 'Wetlands_Water', 'Jungle_Water', 'Reservoir_Water', 'MountainValley_Water', 
                 'Waterfall_Water', 'Floor_Water']

In [23]:
import scipy
from scipy.signal import butter, filtfilt

time_series = data_csvs['df_1'][water_columns[1]]
b,a = butter(10, 0.05, btype='low')

time_series.plot()
plt.plot(time_series.index.values, filtfilt(b, a, time_series), 'r--', alpha=0.5)


Out[23]:
[<matplotlib.lines.Line2D at 0x138e8e710>]

In [24]:
time_series = data_csvs['df_2'][water_columns[1]]
b,a = butter(5, 0.1, btype='low')

time_series.plot()
plt.plot(time_series.index.values, filtfilt(b, a, time_series), 'r--', alpha=0.5)


Out[24]:
[<matplotlib.lines.Line2D at 0x11e237d30>]

In [25]:
signal_data = {}

for k,v in data_csvs.items():
    
    signal_data[k] = {}
    signal_data[k]['index'] = v.index.values


for i, tsname in enumerate(water_columns):
    
    for k,v in signal_data.items():
        
        signal_data[k][tsname] = filtfilt(b, a, data_csvs[k][water_columns[i]])

Let's perform stepwise greedy selection to choose the best wavelets


In [26]:
def construct_x_matrix(best_splits, stop):
    start = 0

    for i,split in enumerate(best_splits):

        next_part = np.arange(start, split, 1)
        constant = np.ones_like(next_part)

        if i == 0:

            X = np.concatenate([
                np.concatenate([constant, np.zeros(stop - split)]).reshape(-1,1),
                np.concatenate([next_part, np.zeros(stop - split)]).reshape(-1,1)], axis=1)
            start = split
            continue

        X = np.concatenate([
                X,
                np.concatenate([np.zeros(start), constant, np.zeros(stop - split)]).reshape(-1,1),
                np.concatenate([np.zeros(start), next_part, np.zeros(stop - split)]).reshape(-1,1),
            ], axis=1)

        start = split
    return X

Exploration to get working code


In [27]:
step_size = 2

# start with the entire dataset
time_series = signal_data['df_1']['Plains_Water']
start, stop = 0, len(time_series)
best_splits = [stop]
best_bics = []
store_best_splits = []

for i in range(25):
    # naive approach is to iterate through at window size
    bics = []
    splits = list(range(start+step_size, stop, step_size))
    for i in splits:

        temp_splits = copy.deepcopy(best_splits)
        bisect.insort(temp_splits, i)

        X = construct_x_matrix(temp_splits, stop)
        y = time_series
        result = sm.OLS(endog=y, exog=X).fit()
        bics.append(result.bic)


    arg_best_bic = np.argmin(bics)
    best_split = splits[arg_best_bic]
    bisect.insort(best_splits, best_split)
    best_bics.append(bics[arg_best_bic])
    store_best_splits.append(copy.deepcopy(best_splits))

In [28]:
plt.plot(best_bics)


Out[28]:
[<matplotlib.lines.Line2D at 0x117db6cf8>]

In [29]:
#     first_part = np.arange(start, best_split, 1)
#     second_part = np.arange(best_split, stop, 1)

#     X = np.concatenate([
#             np.concatenate([np.ones_like(first_part), np.zeros_like(second_part)]).reshape(-1,1),
#             np.concatenate([first_part, np.zeros_like(second_part)]).reshape(-1,1),
#             np.concatenate([np.zeros_like(first_part), np.ones_like(second_part)]).reshape(-1,1),
#             np.concatenate([np.zeros_like(first_part), second_part]).reshape(-1,1)
#         ], axis=1)
# result = sm.OLS(endog=y, exog=X).fit()

# I am trying to select the next best split based on the p-values but
# it might make more sense to just make a split based on the length of the 
# training data

# column_to_break = np.argmax((X[::2] > 0).sum())
# column_to_break = np.argmax(result.pvalues[::2] / (X[::2] > 0).sum())
# column_to_break

In [30]:
X = construct_x_matrix(store_best_splits[7], len(signal_data['df_1']['index']))
result = sm.OLS(endog=y, exog=X).fit()

index = signal_data['df_1']['index']
plt.scatter(index, result.predict())
plt.plot(time_series)
plt.show()


Explore df1 to get bics at different number of breaks

DF1 - 09-19 (Nick/Aditi/Leilah/Andee session)


In [31]:
def get_best_split_points_and_plot_BICs(axes, df):
    split_points = []

    for k, ts_name in enumerate(water_columns):

        split_points.append([])

        time_series = signal_data[df][ts_name]
        y = time_series
        index = signal_data[df]['index']

        step_size = 10

        # start with the entire dataset
        start, stop = 0, len(time_series)
        best_splits = [stop]
        best_bics = []
        store_best_splits = []

        for i in range(15):
            # naive approach is to iterate through at window size
            bics = []
            splits = list(range(start+step_size, stop, step_size))
            for i in splits:

                temp_splits = copy.deepcopy(best_splits)
                bisect.insort(temp_splits, i)

                X = construct_x_matrix(temp_splits, stop)
                result = sm.OLS(endog=y, exog=X).fit()
                bics.append(result.bic)


            arg_best_bic = np.argmin(bics)
            best_split = splits[arg_best_bic]
            bisect.insort(best_splits, best_split)
            best_bics.append(bics[arg_best_bic])
            store_best_splits.append(copy.deepcopy(best_splits))

        split_points[k].append(store_best_splits)
        axes[k].plot(best_bics)
        axes[k].set_title(ts_name)

    return split_points

In [32]:
fig, axes = plt.subplots(4,2, figsize=(15,16))
axes = axes.flatten()

signal_data['df_1']['best_splits'] = get_best_split_points_and_plot_BICs(axes, 'df_1')

plt.show()



In [40]:
def generate_colour():
    while True:
        yield tuple(np.random.uniform(0,1,3))
    
def plot_best_splits(axes, best_individual_splitpoints, df):
    events = []

    for k, ts_name in enumerate(water_columns):

        time_series = signal_data[df][ts_name]
        y = time_series
        index = signal_data[df]['index']
        start, stop = 0, len(time_series)
        splits = signal_data[df]['best_splits'][k][0][best_individual_splitpoints[k]]
        events.append(splits)
        X = construct_x_matrix(splits, stop)

        result = sm.OLS(endog=y, exog=X).fit()
        axes[k].scatter(index/60, result.predict())
        axes[k].plot(index/60, time_series)
        axes[k].set_title(ts_name)
        axes[k].set_ylim([0,1.5])
        axes[k].set_xlim([0,np.max(index/60)])

    return events

In [34]:
# best_individual_splitpoints = [
#     1, #MV
#     2, #P
#     3, #WF
#     0, #F
#     2, #R
#     1, #J
#     3, #W
#     1] #D

best_individual_splitpoints = [
    2, #MV
    2, #P
    2, #WF
    2, #F
    2, #R
    2, #J
    2, #W
    2] #D

fig, axes = plt.subplots(4,2, figsize=(15,16))
axes = axes.flatten()

events = plot_best_splits(axes, best_individual_splitpoints, 'df_1')

plt.show()


Now study the events over time to see if these match up with the observed actions from the log images.


In [35]:
# flat = []
# [[flat.append(i) for i in e] for e in events]
# flat = list(np.sort(flat))
# difference = np.diff(np.sort(flat))
# c_map = generate_colour()
# colours = []

# for i, d in enumerate(difference):
#     if i == 0:
#         colours.append(next(c_map))
        
#     if d <= 20:
#         colours.append(colours[i])
        
#     else:
#         colours.append(next(c_map))
# colours
        
# fig, ax = plt.subplots(1,1, figsize=(15,9))
# i = 0

# for event_log in events[::-1]:
    
#     ax.axhline(y=i, c='black', lw=0.5, alpha=0.5)
#     for e in event_log[:-1]:
                
#         ax.axvline(x=e/60, ymin=(i+1)/(len(events)), ymax=(i)/(len(events)), c=colours[flat.index(e)], lw=5)
    
#     i += 1
    
# ax.set_ylim(0,i)
# ax.grid(False)

# ax.set_yticks(np.arange(0,len(water_columns))+0.5)
# ax.set_yticklabels(water_columns[::-1], position=(0,-1))

# for i in data_diffs['df_1']:
#     ax.axvline(x=i/60, alpha=0.1)
    
# plt.show()

focussed_events = events[-5::-1]

def generate_colour():
    while True:
        yield tuple(np.random.uniform(0,1,3))
        
flat = []
[[flat.append(i) for i in e] for e in focussed_events]
flat = list(np.sort(flat))
difference = np.diff(np.sort(flat))
c_map = generate_colour()
colours = []

for i, d in enumerate(difference):
    if i == 0:
        colours.append(next(c_map))
        
    if d <= 20:
        colours.append(colours[i])
        
    else:
        colours.append(next(c_map))
colours
        
fig, ax = plt.subplots(1,1, figsize=(15,4))
i = 0

for event_log in focussed_events:
    
    ax.axhline(y=i, c='black', lw=0.5, alpha=0.5)
    for e in event_log[:-1]:
                
        ax.axvline(x=e/60, ymin=(i+1)/(len(focussed_events)), ymax=(i)/(len(focussed_events)), c=colours[flat.index(e)], lw=5)
    
    i += 1
    
ax.set_ylim(0,i)
ax.grid(False)

ax.set_yticks(np.arange(0,len(water_columns[:4]))+0.5)
ax.set_yticklabels(water_columns[:4][::-1], position=(0,-1))

for i in data_diffs['df1']:
    ax.axvline(x=i/60, alpha=0.1)
    
plt.show()


DF2 - 09-09


In [36]:
fig, axes = plt.subplots(4,2, figsize=(15,16))
axes = axes.flatten()

signal_data['df_2']['best_splits'] = get_best_split_points_and_plot_BICs(axes, 'df_2')

plt.show()



In [46]:
best_individual_splitpoints = [
    10, #D
    7, #P
    7, #W
    10, #J
    4, #R
    2, #MV
    3, #WF
    2] #F

fig, axes = plt.subplots(4,2, figsize=(15,16))
axes = axes.flatten()

events = plot_best_splits(axes, best_individual_splitpoints, 'df_2')

plt.show()



In [51]:
focussed_events = events[-5::-1]

def generate_colour():
    while True:
        yield tuple(np.random.uniform(0,1,3))
        
flat = []
[[flat.append(i) for i in e] for e in focussed_events]
flat = list(np.sort(flat))
difference = np.diff(np.sort(flat))
c_map = generate_colour()
colours = []

for i, d in enumerate(difference):
    if i == 0:
        colours.append(next(c_map))
        
    if d <= 20:
        colours.append(colours[i])
        
    else:
        colours.append(next(c_map))
colours
        
fig, ax = plt.subplots(1,1, figsize=(15,4))
i = 0

for event_log in focussed_events:
    
    ax.axhline(y=i, c='black', lw=0.5, alpha=0.5)
    for e in event_log[:-1]:
                
        ax.axvline(x=e/60, ymin=(i+1)/(len(focussed_events)), ymax=(i)/(len(focussed_events)), c=colours[flat.index(e)], lw=5,
                  zorder=100)
    
    i += 1
    
ax.set_ylim(0,i)
ax.grid(False)

ax.set_yticks(np.arange(0,len(water_columns[:4]))+0.5)
ax.set_yticklabels(water_columns[:4][::-1], position=(0,-1))

for i in data_diffs['df_2']:
    ax.axvline(x=i/60, alpha=0.1, zorder=10)
    
plt.show()


DF3 - 09-01


In [52]:
fig, axes = plt.subplots(4,2, figsize=(15,16))
axes = axes.flatten()

signal_data['df_3']['best_splits'] = get_best_split_points_and_plot_BICs(axes, 'df_3')

plt.show()



In [88]:
best_individual_splitpoints = [
    8, #D
    8, #P
    8, #W
    8, #J
    8, #R
    8, #MV
    8, #WF
    8] #F

fig, axes = plt.subplots(4,2, figsize=(15,16))
axes = axes.flatten()

events = plot_best_splits(axes, best_individual_splitpoints, 'df_3')

plt.show()



In [89]:
focussed_events = events[-5::-1]

def generate_colour():
    while True:
        yield tuple(np.random.uniform(0,1,3))
        
flat = []
[[flat.append(i) for i in e] for e in focussed_events]
flat = list(np.sort(flat))
difference = np.diff(np.sort(flat))
c_map = generate_colour()
colours = []

for i, d in enumerate(difference):
    if i == 0:
        colours.append(next(c_map))
        
    if d <= 20:
        colours.append(colours[i])
        
    else:
        colours.append(next(c_map))
colours
        
fig, ax = plt.subplots(1,1, figsize=(15,4))
i = 0

for event_log in focussed_events:
    
    ax.axhline(y=i, c='black', lw=0.5, alpha=0.5)
    for e in event_log[:-1]:
                
        ax.axvline(x=e/60, ymin=(i+1)/(len(focussed_events)), ymax=(i)/(len(focussed_events)), c=colours[flat.index(e)], lw=5, zorder=100)
    
    i += 1
    
ax.set_ylim(0,i)
ax.grid(False)

ax.set_yticks(np.arange(0,len(water_columns[:4]))+0.5)
ax.set_yticklabels(water_columns[:4][::-1], position=(0,-1))

for i in data_diffs['df_3']:
    ax.axvline(x=i/60, alpha=0.1)
    
plt.show()


DF4 - 09-06 - no log movements


In [80]:
fig, axes = plt.subplots(4,2, figsize=(15,16))
axes = axes.flatten()

signal_data['df_4']['best_splits'] = get_best_split_points_and_plot_BICs(axes, 'df_4')

plt.show()



In [81]:
best_individual_splitpoints = [
    0, #D
    0, #P
    0, #W
    0, #J
    0, #R
    0, #MV
    0, #WF
    0] #F

fig, axes = plt.subplots(4,2, figsize=(15,16))
axes = axes.flatten()

events = plot_best_splits(axes, best_individual_splitpoints, 'df_4')

plt.show()



In [82]:
focussed_events = events[-5::-1]

def generate_colour():
    while True:
        yield tuple(np.random.uniform(0,1,3))
        
flat = []
[[flat.append(i) for i in e] for e in focussed_events]
flat = list(np.sort(flat))
difference = np.diff(np.sort(flat))
c_map = generate_colour()
colours = []

for i, d in enumerate(difference):
    if i == 0:
        colours.append(next(c_map))
        
    if d <= 20:
        colours.append(colours[i])
        
    else:
        colours.append(next(c_map))
colours
        
fig, ax = plt.subplots(1,1, figsize=(15,4))
i = 0

for event_log in focussed_events:
    
    ax.axhline(y=i, c='black', lw=0.5, alpha=0.5)
    for e in event_log[:-1]:
                
        ax.axvline(x=e/60, ymin=(i+1)/(len(focussed_events)), ymax=(i)/(len(focussed_events)), c=colours[flat.index(e)], lw=5)
    
    i += 1
    
ax.set_ylim(0,i)
ax.grid(False)

ax.set_yticks(np.arange(0,len(water_columns[:4]))+0.5)
ax.set_yticklabels(water_columns[:4][::-1], position=(0,-1))

for i in data_diffs['df_4']:
    ax.axvline(x=i/60, alpha=0.1)
    
plt.show()