In [14]:
from moviepy.editor import *
import pandas as pd
import numpy as np
import datetime

logfile = input("Filename (Tab-Delimited Log File): ")
myFile = pd.read_table(logfile,sep='\t')
list(myFile)
time_colname = input("Name of Timestamp Column: ")
myFile['Time'] = pd.to_datetime(myFile[time_colname])

myFile.head()


Filename (Tab-Delimited Log File): ChemData_ForStreams_FINAL.txt
Name of Timestamp Column: Time
Out[14]:
Student Date Time Activity Screen Event KC
0 synthetic_student_1 10/16/15 2016-10-10 04:46:36 3 massHydroxide cu_mass_corr Experimentation
1 synthetic_student_1 10/16/15 2016-10-10 04:46:36 3 massHydroxide sig_fig Sig.Figs
2 synthetic_student_1 10/16/15 2016-10-10 04:47:22 3 molMassCopperHyd mmatoms Mol.Mass
3 synthetic_student_1 10/16/15 2016-10-10 04:47:22 3 molMassCopperHyd numatoms Mol.Mass
4 synthetic_student_1 10/16/15 2016-10-10 04:49:28 3 molRatios molRatios Bal.Rxns

In [15]:
alignfile = input("Filename (Temporal Alignment of New Streams): ")
numstreams = int(input("How many new streams are there?: "))
align_info = pd.read_table(alignfile,sep='\t')
align_columns = list(align_info)
select_constraints = align_columns[0:(len(align_columns)-3*numstreams)]

align_info


Filename (Temporal Alignment of New Streams): ChemData_ForStreams_Align.txt
How many new streams are there?: 1
Out[15]:
Student Date S1.Filename S1.Min S1.Sec
0 synthetic_student_1 10/16/15 10_16_2015_synthetic_student_1.mp4 0 56
1 synthetic_student_2 10/16/15 10_16_2015_synthetic_student_2.mp4 2 52
2 synthetic_student_3 10/16/15 10_16_2015_synthetic_student_3.mp4 0 53
3 synthetic_student_4 10/16/15 10_16_2015_synthetic_student_4.mp4 1 20
4 synthetic_student_5 10/16/15 10_16_2015_synthetic_student_5.mp4 5 48
5 synthetic_student_6 10/16/15 10_16_2015_synthetic_student_6.mp4 1 56
6 synthetic_student_7 10/16/15 10_16_2015_synthetic_student_7.mp4 10 49
7 synthetic_student_8 10/16/15 10_16_2015_synthetic_student_8.mp4 3 59
8 synthetic_student_9 10/16/15 10_16_2015_synthetic_student_9.mp4 4 7
9 synthetic_student_10 10/16/15 10_16_2015_synthetic_student_10.mp4 2 56
10 synthetic_student_11 10/16/15 10_16_2015_synthetic_student_11.mp4 1 37
11 synthetic_student_12 10/16/15 10_16_2015_synthetic_student_12.mp4 0 32
12 synthetic_student_13 10/16/15 10_16_2015_synthetic_student_13.mp4 0 31
13 synthetic_student_14 10/16/15 10_16_2015_synthetic_student_14.mp4 2 49
14 synthetic_student_15 10/16/15 10_16_2015_synthetic_student_15.mp4 2 47
15 synthetic_student_16 10/16/15 10_16_2015_synthetic_student_16.mp4 2 52
16 synthetic_student_17 10/16/15 10_16_2015_synthetic_student_17.mp4 2 40
17 synthetic_student_18 10/16/15 10_16_2015_synthetic_student_18.mp4 0 54
18 synthetic_student_19 10/16/15 10_16_2015_synthetic_student_19.mp4 6 48
19 synthetic_student_20 10/16/15 10_16_2015_synthetic_student_20.mp4 2 39
20 synthetic_student_21 10/16/15 10_16_2015_synthetic_student_21.mp4 2 48
21 synthetic_student_22 10/16/15 10_16_2015_synthetic_student_22.mp4 2 26
22 synthetic_student_23 10/16/15 10_16_2015_synthetic_student_23.mp4 1 47
23 synthetic_student_24 10/16/15 10_16_2015_synthetic_student_24.mp4 6 57
24 synthetic_student_25 10/16/15 10_16_2015_synthetic_student_25.mp4 2 44
25 synthetic_student_26 10/16/15 10_16_2015_synthetic_student_26.mp4 0 42
26 synthetic_student_27 10/16/15 10_16_2015_synthetic_student_27.mp4 3 20
27 synthetic_student_28 10/16/15 10_16_2015_synthetic_student_28.mp4 0 56
28 synthetic_student_29 10/16/15 10_16_2015_synthetic_student_29.mp4 1 48
29 synthetic_student_30 10/16/15 10_16_2015_synthetic_student_30.mp4 1 29
... ... ... ... ... ...
58 synthetic_student_31 10/26/15 10_26_2015_synthetic_student_31.mp4 5 43
59 synthetic_student_17 10/26/15 10_26_2015_synthetic_student_17.mp4 6 21
60 synthetic_student_32 10/26/15 10_26_2015_synthetic_student_32.mp4 2 6
61 synthetic_student_33 10/26/15 10_26_2015_synthetic_student_33.mp4 0 54
62 synthetic_student_19 10/26/15 10_26_2015_synthetic_student_19.mp4 12 51
63 synthetic_student_34 10/26/15 10_26_2015_synthetic_student_34.mp4 5 0
64 synthetic_student_21 10/26/15 10_26_2015_synthetic_student_21.mp4 2 24
65 synthetic_student_22 10/26/15 10_26_2015_synthetic_student_22.mp4 3 43
66 synthetic_student_35 10/26/15 10_26_2015_synthetic_student_35.mp4 3 44
67 synthetic_student_24 10/26/15 10_26_2015_synthetic_student_24.mp4 3 26
68 synthetic_student_36 10/26/15 10_26_2015_synthetic_student_36.mp4 5 50
69 synthetic_student_25 10/26/15 10_26_2015_synthetic_student_25.mp4 9 42
70 synthetic_student_26 10/26/15 10_26_2015_synthetic_student_26.mp4 0 54
71 synthetic_student_28 10/26/15 10_26_2015_synthetic_student_28.mp4 0 33
72 synthetic_student_29 10/26/15 10_26_2015_synthetic_student_29.mp4 5 18
73 synthetic_student_40 10/26/15 10_26_2015_synthetic_student_40.mp4 9 6
74 synthetic_student_41 10/26/15 10_26_2015_synthetic_student_41.mp4 5 13
75 synthetic_student_42 10/26/15 10_26_2015_synthetic_student_42.mp4 2 7
76 synthetic_student_43 10/26/15 10_26_2015_synthetic_student_43.mp4 6 0
77 synthetic_student_44 10/26/15 10_26_2015_synthetic_student_44.mp4 6 17
78 synthetic_student_45 10/26/15 10_26_2015_synthetic_student_45.mp4 2 22
79 synthetic_student_46 10/26/15 10_26_2015_synthetic_student_46.mp4 0 29
80 synthetic_student_47 10/26/15 10_26_2015_synthetic_student_47.mp4 5 28
81 synthetic_student_48 10/26/15 10_26_2015_synthetic_student_48.mp4 1 43
82 synthetic_student_37 10/26/15 10_26_2015_synthetic_student_37.mp4 4 40
83 synthetic_student_49 10/26/15 10_26_2015_synthetic_student_49.mp4 4 32
84 synthetic_student_50 10/26/15 10_26_2015_synthetic_student_50.mp4 2 41
85 synthetic_student_51 10/26/15 10_26_2015_synthetic_student_51.mp4 7 14
86 synthetic_student_52 10/26/15 10_26_2015_synthetic_student_52.mp4 5 29
87 synthetic_student_53 10/26/15 10_26_2015_synthetic_student_53.mp4 5 52

88 rows × 5 columns


In [7]:
def find_start_time (row, column):
    end_time = row[column]
    times = selection[selection[column] < end_time][column]
    if len(times)==0:
        return 0
    return max(times)

def find_total_seconds(row, column):
    if row[column]==0: return 0
    return row[column].total_seconds()

master = pd.DataFrame()
    
for index, row in align_info.iterrows():
    
    selection = myFile.loc[(myFile.Student == row['Student']) & (myFile.Date == row['Date'])]
        
    for s in range(1,numstreams+1):
    
        prefix = str(align_columns[len(align_columns)-3*s]).split(".")[0]

        stream_file = row[len(align_columns)-3*s]
        mins = row[len(align_columns)-3*s+1]
        secs = row[len(align_columns)-3*s+2]
        print(prefix + ': ' + stream_file + ' ' + str(mins) + ':' + str(secs))

        selection[str(prefix+'.Filename')]=str(stream_file)
        selection[str(prefix+'.VideoTimeEnd')]=selection.Time-selection.Time.iloc[0]+datetime.timedelta(minutes=mins,seconds=secs)
        selection[str(prefix+'.VideoTimeEnd_sec')]=selection.apply(lambda row:find_total_seconds(row,str(prefix+'.VideoTimeEnd')),axis=1)
        selection[str(prefix+'.VideoTimeStart_sec')] = selection.apply(lambda row: find_start_time(row,str(prefix+'.VideoTimeEnd_sec')), axis=1)
        selection = selection.drop(str(prefix+'.VideoTimeEnd'), 1)

    #selection.to_csv(str(stream_file + '.txt'), sep='\t') ## writes out a text file for each selection
    master2 = master.copy() ## adds each selection to master data frame
    master = master2.append(selection)

master.head()


S1: 10_16_2015_synthetic_student_1.mp4 0:56
S1: 10_16_2015_synthetic_student_2.mp4 2:52
S1: 10_16_2015_synthetic_student_3.mp4 0:53
S1: 10_16_2015_synthetic_student_4.mp4 1:20
S1: 10_16_2015_synthetic_student_5.mp4 5:48
S1: 10_16_2015_synthetic_student_6.mp4 1:56
S1: 10_16_2015_synthetic_student_7.mp4 10:49
S1: 10_16_2015_synthetic_student_8.mp4 3:59
S1: 10_16_2015_synthetic_student_9.mp4 4:7
S1: 10_16_2015_synthetic_student_10.mp4 2:56
S1: 10_16_2015_synthetic_student_11.mp4 1:37
S1: 10_16_2015_synthetic_student_12.mp4 0:32
S1: 10_16_2015_synthetic_student_13.mp4 0:31
S1: 10_16_2015_synthetic_student_14.mp4 2:49
S1: 10_16_2015_synthetic_student_15.mp4 2:47
S1: 10_16_2015_synthetic_student_16.mp4 2:52
S1: 10_16_2015_synthetic_student_17.mp4 2:40
S1: 10_16_2015_synthetic_student_18.mp4 0:54
S1: 10_16_2015_synthetic_student_19.mp4 6:48
S1: 10_16_2015_synthetic_student_20.mp4 2:39
S1: 10_16_2015_synthetic_student_21.mp4 2:48
S1: 10_16_2015_synthetic_student_22.mp4 2:26
S1: 10_16_2015_synthetic_student_23.mp4 1:47
S1: 10_16_2015_synthetic_student_24.mp4 6:57
S1: 10_16_2015_synthetic_student_25.mp4 2:44
S1: 10_16_2015_synthetic_student_26.mp4 0:42
S1: 10_16_2015_synthetic_student_27.mp4 3:20
S1: 10_16_2015_synthetic_student_28.mp4 0:56
S1: 10_16_2015_synthetic_student_29.mp4 1:48
S1: 10_16_2015_synthetic_student_30.mp4 1:29
S1: 10_16_2015_synthetic_student_40.mp4 2:28
S1: 10_16_2015_synthetic_student_41.mp4 2:53
S1: 10_16_2015_synthetic_student_44.mp4 4:8
S1: 10_16_2015_synthetic_student_46.mp4 0:30
S1: 10_16_2015_synthetic_student_47.mp4 3:33
S1: 10_16_2015_synthetic_student_48.mp4 0:54
S1: 10_16_2015_synthetic_student_37.mp4 3:20
S1: 10_16_2015_synthetic_student_50.mp4 5:46
S1: 10_16_2015_synthetic_student_51.mp4 1:56
S1: 10_16_2015_synthetic_student_52.mp4 0:25
S1: 10_16_2015_synthetic_student_53.mp4 1:39
S1: 10_26_2015_synthetic_student_1.mp4 2:40
S1: 10_26_2015_synthetic_student_2.mp4 7:20
S1: 10_26_2015_synthetic_student_3.mp4 5:18
S1: 10_26_2015_synthetic_student_60.mp4 6:45
S1: 10_26_2015_synthetic_student_4.mp4 2:57
S1: 10_26_2015_synthetic_student_5.mp4 7:28
S1: 10_26_2015_synthetic_student_7.mp4 4:25
S1: 10_26_2015_synthetic_student_61.mp4 6:55
S1: 10_26_2015_synthetic_student_8.mp4 2:26
S1: 10_26_2015_synthetic_student_9.mp4 2:48
S1: 10_26_2015_synthetic_student_10.mp4 5:0
S1: 10_26_2015_synthetic_student_62.mp4 5:18
S1: 10_26_2015_synthetic_student_12.mp4 1:57
S1: 10_26_2015_synthetic_student_13.mp4 4:28
S1: 10_26_2015_synthetic_student_63.mp4 8:43
S1: 10_26_2015_synthetic_student_15.mp4 3:21
S1: 10_26_2015_synthetic_student_64.mp4 2:29
S1: 10_26_2015_synthetic_student_31.mp4 5:43
S1: 10_26_2015_synthetic_student_17.mp4 6:21
S1: 10_26_2015_synthetic_student_32.mp4 2:6
S1: 10_26_2015_synthetic_student_33.mp4 0:54
S1: 10_26_2015_synthetic_student_19.mp4 12:51
S1: 10_26_2015_synthetic_student_34.mp4 5:0
S1: 10_26_2015_synthetic_student_21.mp4 2:24
S1: 10_26_2015_synthetic_student_22.mp4 3:43
S1: 10_26_2015_synthetic_student_35.mp4 3:44
S1: 10_26_2015_synthetic_student_24.mp4 3:26
S1: 10_26_2015_synthetic_student_36.mp4 5:50
S1: 10_26_2015_synthetic_student_25.mp4 9:42
S1: 10_26_2015_synthetic_student_26.mp4 0:54
S1: 10_26_2015_synthetic_student_28.mp4 0:33
S1: 10_26_2015_synthetic_student_29.mp4 5:18
S1: 10_26_2015_synthetic_student_40.mp4 9:6
S1: 10_26_2015_synthetic_student_41.mp4 5:13
S1: 10_26_2015_synthetic_student_42.mp4 2:7
S1: 10_26_2015_synthetic_student_43.mp4 6:0
S1: 10_26_2015_synthetic_student_44.mp4 6:17
S1: 10_26_2015_synthetic_student_45.mp4 2:22
S1: 10_26_2015_synthetic_student_46.mp4 0:29
S1: 10_26_2015_synthetic_student_47.mp4 5:28
S1: 10_26_2015_synthetic_student_48.mp4 1:43
S1: 10_26_2015_synthetic_student_37.mp4 4:40
S1: 10_26_2015_synthetic_student_49.mp4 4:32
S1: 10_26_2015_synthetic_student_50.mp4 2:41
S1: 10_26_2015_synthetic_student_51.mp4 7:14
S1: 10_26_2015_synthetic_student_52.mp4 5:29
S1: 10_26_2015_synthetic_student_53.mp4 5:52
Out[7]:
Student Date Time Activity Screen Event KC S1.Filename S1.VideoTimeEnd_sec S1.VideoTimeStart_sec
174 synthetic_student_1 10/16/15 2016-10-10 04:50:34 3 amountReacted amount Bal.Rxns 10_16_2015_synthetic_student_1.mp4 56.0 -10.0
220 synthetic_student_1 10/16/15 2016-10-10 04:50:34 3 amountReacted molMass Mol.Mass 10_16_2015_synthetic_student_1.mp4 56.0 -10.0
257 synthetic_student_1 10/16/15 2016-10-10 04:50:34 3 amountReacted molRatio Bal.Rxns 10_16_2015_synthetic_student_1.mp4 56.0 -10.0
264 synthetic_student_1 10/16/15 2016-10-10 04:59:41 3 calcReactedBaSO4 amount Bal.Rxns 10_16_2015_synthetic_student_1.mp4 603.0 557.0
324 synthetic_student_1 10/16/15 2016-10-10 04:59:41 3 calcReactedBaSO4 molMass Mol.Mass 10_16_2015_synthetic_student_1.mp4 603.0 557.0

In [12]:
def find_start_time (row, column):
    end_time = row[column]
    times = selection[selection[column] < end_time][column]
    if len(times)==0:
        return 0
    return max(times)

def find_total_seconds(row, column):
    if row[column]==0: return 0
    return row[column].total_seconds()

selection = myFile.loc[(myFile.Student == 'synthetic_student_1') & (myFile.Date == '10/16/15')]
          
prefix = 'S1'
mins = 0
secs = 56

selection[str(prefix+'.Filename')]='synthetic_student_1.mp4'
selection[str(prefix+'.VideoTimeEnd')]=selection.Time-selection.Time.iloc[0]+datetime.timedelta(minutes=mins,seconds=secs)
selection.Time


Out[12]:
174    2016-10-10 04:50:34
220    2016-10-10 04:50:34
257    2016-10-10 04:50:34
264    2016-10-10 04:59:41
324    2016-10-10 04:59:41
340    2016-10-10 04:59:41
693    2016-10-10 04:46:36
704    2016-10-10 04:46:36
748    2016-10-10 04:58:55
774    2016-10-10 04:58:55
827    2016-10-10 04:47:22
861    2016-10-10 04:47:22
885    2016-10-10 04:49:28
905    2016-10-10 04:49:28
959    2016-10-10 04:56:46
1025   2016-10-10 04:51:17
1059   2016-10-10 04:58:31
1077   2016-10-10 04:58:31
1122   2016-10-10 04:58:31
1287   2016-10-10 05:01:15
1322   2016-10-10 05:01:15
1363   2016-10-10 05:01:15
1401   2016-10-10 05:01:15
Name: Time, dtype: datetime64[ns]

In [21]:
master.to_csv('ChemData_StreamsAligned.txt', sep='\t')