-
Notifications
You must be signed in to change notification settings - Fork 2
/
fbdfix.py
111 lines (87 loc) · 2.64 KB
/
fbdfix.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# fbdfix.py
"""Remove data containing non-frame-markers from FLIMbox FBD files.
Usage: python fbdfix.py directory_or_file_name
"""
import os
import numpy
import lfdfiles
def fbdfix(
fbdfile,
outfile=None,
nmarkers=3,
frame_duration=None,
frame_duration_maxdiff=None,
):
"""Remove data containing non-frame-markers from FLIMbox FBD file."""
if outfile is None:
dirname, fname = os.path.split(fbdfile)
outfile = os.path.join(dirname, '_' + fname)
with lfdfiles.FlimboxFbd(fbdfile) as fbd:
bins, times, markers = fbd.decode()
frame_durations = numpy.diff(times[markers]).astype(numpy.int64)
if len(frame_durations) <= nmarkers:
return 'skipped'
if frame_duration is None:
# assume longest of last few frames is good
frame_duration = numpy.max(frame_durations[-nmarkers:])
if frame_duration_maxdiff is None:
frame_duration_maxdiff = frame_duration // 512
n = nmarkers
i = len(frame_durations)
while i > 0:
i -= 1
if abs(frame_durations[i] - frame_duration) > frame_duration_maxdiff:
n -= 1
if n == 0:
break
else:
n = nmarkers
else:
i = -nmarkers
i += nmarkers
skip_bytes = max(0, markers[i] * 2 - 4)
with open(fbdfile, 'rb') as fh:
header = fh.read(32 * 1024)
fh.seek(skip_bytes, 1)
data = fh.read()
with open(outfile, 'wb') as fh:
fh.write(header)
fh.write(data)
return f'removed {skip_bytes} bytes, {i} of {markers.size} markers'
def main():
"""Command line script main function."""
import glob
import sys
if len(sys.argv) == 2:
arg = sys.argv[1]
if '*' in arg:
files = glob.glob(arg, recursive=True)
elif os.path.isdir(arg):
files = glob.glob(os.path.join(arg, '**/*.fbd'), recursive=True)
else:
files = [arg]
else:
files = []
if not files:
print(__doc__)
return
if len(files) > 1:
common = len(os.path.commonpath(files))
if files[0][common] == os.path.sep:
common += 1
if common > 0:
print(files[0][:common])
else:
common = 0
for filename in files:
fname = os.path.split(filename)[-1]
if fname.startswith('_') or not fname.lower().endswith('.fbd'):
continue
print()
print('*', filename[common:])
try:
print(' ', fbdfix(filename))
except Exception as exc:
print(f' failed: {exc.__class__.__name__}: {exc}')
if __name__ == '__main__':
main()