Skip to content

Commit 91b9e15

Browse files
committed
[meta-manager] tool to update sigmf annotations
1 parent 2366836 commit 91b9e15

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

meta-manager

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import argparse
5+
import json
6+
import datetime
7+
8+
9+
def Annotation(**kwargs):
10+
t = {}
11+
if 'width' in kwargs:
12+
t['freq_upper_edge'] = round(kwargs['freq']+kwargs['width']/2)
13+
t['freq_lower_edge'] = round(kwargs['freq']-kwargs['width']/2)
14+
del kwargs['width']
15+
del kwargs['freq']
16+
if 'count' in kwargs:
17+
t['sample_count'] = kwargs['count']
18+
del kwargs['count']
19+
if 'start' in kwargs:
20+
t['sample_start'] = kwargs['start']
21+
del kwargs['start']
22+
23+
for a in kwargs:
24+
t[a] = kwargs[a]
25+
26+
return {"core:"+k: v for k, v in t.items()}
27+
28+
29+
parser = argparse.ArgumentParser()
30+
31+
parser.add_argument("-v", "--verbose", action="store_true",
32+
help="increase output verbosity")
33+
parser.add_argument("-d", "--debug", action="store_true")
34+
parser.add_argument("-w", "--write", help="write new file")
35+
parser.add_argument("-p", "--peaks", help="add peaks from file")
36+
37+
filters = parser.add_argument_group('filters')
38+
filters.add_argument("--f-min", metavar="freq", type=int, help="minmum frequency")
39+
filters.add_argument("--f-max", metavar="freq", type=int, help="maximum frequency")
40+
filters.add_argument("--t-max", metavar="seconds", type=int, help="maxiumum time")
41+
filters.add_argument("--c-max", metavar="count", type=int, help="maxiumum number of annotations")
42+
43+
parser.add_argument("metafile", help="filename")
44+
45+
args = parser.parse_args()
46+
47+
with open(args.metafile) as f:
48+
data = json.load(f)
49+
50+
assert(len(data["captures"]) == 1)
51+
assert(data["captures"][0]["core:sample_start"] == 0)
52+
assert(data["captures"])
53+
54+
rate = int(data["global"]["core:sample_rate"])
55+
dt = data["captures"][0]["core:datetime"]
56+
freq = int(data["captures"][0]["core:frequency"])
57+
58+
print(f'{args.metafile}: [{data["global"]["core:datatype"]}] {rate/1e6:.9g}Msps @{freq/1e9:.9g}GHz')
59+
60+
# Remove empty annotations
61+
ann = [a for a in data["annotations"] if len(a) > 0]
62+
63+
print(f'in {len(ann)} annotations')
64+
65+
if args.peaks is not None:
66+
with open(args.peaks) as f:
67+
for line in f:
68+
try:
69+
sample, fftbin, _ = line.split(",")
70+
sample = int(sample)
71+
fftbin = int(fftbin)
72+
except main:
73+
pass
74+
75+
bins = 8192
76+
77+
freq = freq + rate * (fftbin / bins - 0.5)
78+
width = rate / bins
79+
80+
a = Annotation(comment="Peak", description="", freq=freq, width=width, start=sample, count=bins)
81+
82+
ann.append(a)
83+
84+
85+
if args.f_max is not None:
86+
ann = [a for a in ann if a["core:freq_upper_edge"] > args.f_max]
87+
88+
if args.f_min is not None:
89+
ann = [a for a in ann if a["core:freq_lower_edge"] < args.f_min]
90+
91+
if args.t_max is not None:
92+
ann = [a for a in ann if a["core:sample_start"] < args.t_max*rate]
93+
94+
if args.c_max is not None:
95+
ann = sorted(ann, key=lambda v: v["core:sample_start"])[:args.c_max]
96+
97+
data["annotations"] = ann
98+
99+
fmin = min([a["core:freq_lower_edge"] for a in data["annotations"]])
100+
fmax = max([a["core:freq_upper_edge"] for a in data["annotations"]])
101+
tmin = min([a["core:sample_start"] for a in data["annotations"]])
102+
tmax = max([a["core:sample_start"] for a in data["annotations"]])
103+
104+
if False:
105+
for a in data["annotations"]:
106+
print(f'{a["core:sample_start"]}')
107+
pass
108+
109+
110+
def s2t(samples): # convert samples to time
111+
return samples / rate
112+
113+
114+
print(f'out {len(data["annotations"])} annotations')
115+
print(f' {fmin/1e9:.6f} - {fmax/1e9:.6f} GHz / {s2t(tmin):.3f} - {s2t(tmax):.3f} sec')
116+
117+
118+
if args.write:
119+
os.rename(args.metafile, args.metafile+".bak")
120+
121+
with open(args.metafile, "w") as f:
122+
json.dump(data, f, indent=0)

0 commit comments

Comments
 (0)