Get object timings
In progress: get object timings from object information data
Not complete; the object timing infomation comes from gaze tracking, so maybe not totally useful. Also, the general point of this was to output a TextGrid or something similar with these object timings, so it's incomplete in those terms, and can't be until the gaze times are.
datapath = "/Users/joregan/Playing/hsi/"
from pathlib import Path
DATAPATH = Path(datapath)
OBJECT_HEADER = "TimeCode,ObjectName,ObjectPosX,ObjectPosY,ObjectPosZ"
TIMECODE_HEADER = "Frame,Time (Seconds),TimeCode"
def read_timecode(filename):
header_data = {}
frame_data = []
header_line_seen = False
with open(filename) as inf:
for line in inf.readlines():
line = line.strip()
if line.startswith("Format Version,"):
header_data = {k[0]: k[1] for k in zip(line.split(",")[0::2], line.split(",")[1::2])}
if not header_line_seen:
if line.strip() == TIMECODE_HEADER:
header_line_seen = True
else:
continue
else:
parts = line.split(",")
frame_data.append({
"frame": parts[0],
"abs_time": parts[1],
"timecode": parts[2]
})
return header_data, frame_data
def read_ojects(filename):
header_seen = False
object_codes = []
with open(filename) as inf:
for line in inf.readlines():
line = line.strip()
if not header_seen:
if line == OBJECT_HEADER:
header_seen = True
else:
continue
else:
parts = line.split(",")
timeparts = parts[0].split(":")
assert timeparts[3][0] == "0", f"in {filename}: non-zero padded time ({line})"
timeparts[3] = timeparts[3][1:]
time = ":".join(timeparts)
object_codes.append({
"timecode": time,
"name": parts[1],
"x": parts[2],
"y": parts[3],
"z": parts[4]
})
return object_codes
test = read_ojects("/Users/joregan/Playing/hsi/objects/hsi_7_0719_209_002_objects.csv")
import json
def id_to_name(filename):
fwd = {}
bck = {}
with open(filename) as inf:
data = json.load(inf)
for child in data["origin"]["children"]:
bck[child["name"]] = child["unique_id"]
fwd[child["unique_id"]] = child["name"]
return fwd, bck
def unique_object_times(data):
output = []
last_tc = ""
cur = {}
for i in range(len(data)):
if data[i]["timecode"] == last_tc:
cur["names"].add(data[i]["name"])
else:
if cur != {}:
output.append(cur)
cur = {}
cur["timecode"] = data[i]["timecode"]
cur["names"] = set()
cur["names"].add(data[i]["name"])
last_tc = data[i]["timecode"]
return output
uniq = unique_object_times(test)
def object_window(data, span=5):
allcounts = []
def prcnt():
out = {}
for count in counts:
out[count] = counts[count] / 5
return out
for i in range(len(data) - (span - 1)):
window = data[i:i+5]
counts = {}
id_to_set = {}
timecodes = []
for item in window:
timecodes.append(item["timecode"])
set_id = "__".join(item["names"]) if len(item["names"]) != 1 else list(item["names"])[0]
if not set_id in counts:
counts[set_id] = 1
id_to_set[set_id] = item["names"]
else:
counts[set_id] += 1
countspct = prcnt()
stable = (len(counts) == 1)
allcounts.append({
"stable": stable,
"items": countspct,
"timecodes": timecodes
})
return allcounts
wd = object_window(uniq)
def merge_stable(data):
to_del = []
i = 0
j = 1
while j < len(data):
if data[i]["stable"] and data[j]["stable"]:
data[i]["timecodes"].append(data[j]["timecodes"][-1])
to_del.append(j)
j += 1
else:
i = j
j += 1
for k in reversed(to_del):
del(data[k])
return data
merge_stable(wd)[0:3]