make_sigmf.py 6.38 KB
Newer Older
Thomas Telkamp's avatar
Thomas Telkamp committed
1
2
3
#!/usr/bin/env python3

import os
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
4
import time
Thomas Telkamp's avatar
Thomas Telkamp committed
5
from astropy.time import Time
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
6
from astropy.coordinates import SkyCoord
Thomas Telkamp's avatar
Thomas Telkamp committed
7
8
9
10
11
12
13
import json
from urllib.request import urlopen
import astropy.units as u
from astropy.table import Table

from argparse import ArgumentParser

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
14
from telescope import Telescope
Thomas Telkamp's avatar
Thomas Telkamp committed
15

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
16

17
def make_sigmf(metadatafilename, no_rename=False):
Thomas Telkamp's avatar
Thomas Telkamp committed
18
19
    # time_first_sample, rate, frequency, rx_gain, bandwidth, reference, time_source, format, channel, antenna, sdr_type

20
21
22
23
    with open(metadatafilename, "r") as metadatafile:
        _ = metadatafile.readline()
        metadata = metadatafile.readline().strip().split(", ")

Thomas Telkamp's avatar
Thomas Telkamp committed
24
25
26
27
    time_first_sample, rate, frequency, rx_gain, bandwidth, reference, time_source, dataformat, channel, antenna, sdr_type, num_samples = metadata
    rate = float(rate)
    frequency = float(frequency)
    rx_gain = float(rx_gain)
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
28
    time_first_sample = Time(float(time_first_sample), format="unix")
Thomas Telkamp's avatar
Thomas Telkamp committed
29

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
30
    sigmfname_meta = metadatafilename.rstrip(".metadata").rstrip("sigmf-data") + "sigmf-meta"
Thomas Telkamp's avatar
Thomas Telkamp committed
31
32
33

    meta = {}
    meta["global"] = {}
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
34
35
36
37
    global_meta = meta["global"]
    global_meta["core:description"] = "Dwingeloo Radio Telescope, PI9CAM"
    global_meta["core:version"] = "1.0.0"
    global_meta[
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
38
        "core:license"] = "https://creativecommons.org/licenses/by/4.0/"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
39
40
41
42
43
44
    global_meta["core:author"] = "Stichting CAMRAS"
    global_meta["core:recorder"] = "usrp_to_file"
    global_meta["core:dataset"] = os.path.basename(newfilename)
    global_meta["core:datatype"] = datatype
    global_meta["core:sample_rate"] = rate
    global_meta["core:hw"] = sdr_type.strip('"')
Thomas Telkamp's avatar
Thomas Telkamp committed
45
46
47
48
49
    global_meta["core:geolocation"] = []
    global_meta["core:geolocation"].append({
        "type": "Point",
        "coordinates": [6.3961694, 52.8120194, 60.0]
    })
Thomas Telkamp's avatar
Thomas Telkamp committed
50
51
52
53
54
55
56

    meta["annotations"] = []

    meta["captures"] = []
    meta["captures"].append({
        "core:sample_start": 0,
        "core:frequency": frequency,
Thomas Telkamp's avatar
Thomas Telkamp committed
57
        "core:datetime": time_first_sample.datetime.isoformat(),
Thomas Telkamp's avatar
Thomas Telkamp committed
58
59
60
    })

    # CAMRAS
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
61
    try:
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
62
63
        dt = Telescope(consoleHost="console")
        time.sleep(1.1)  # Make sure everything is updated
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
64
        console_is_on = True
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
65
66
67
68
69
70
71
    except IOError:
        console_is_on = False

    if not console_is_on:
        apilink = urlopen("https://www.camras.nl/pointing.php")
        pointingdata = json.loads(apilink.read().decode())

Thomas Telkamp's avatar
Thomas Telkamp committed
72
        global_meta["camras:pointing:source"] = "https://www.camras.nl/pointing.php"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
73
74
        global_meta["camras:pointing:tracking"] = pointingdata[
            'setpoint'].strip('"')
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
75
76
        global_meta[
            "camras:pointing:az_deg"] = f"{(pointingdata['az'] + 180) % 360:.4f}"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
77
        global_meta["camras:pointing:el_deg"] = f"{pointingdata['el']:.4f}"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
78
79
80
81
82
83
84
85
86
        if pointingdata['offset'].strip() == "":
            offset_az_deg = 0
            offset_el_deg = 0
        else:
            offset_az_str, offset_el_str = pointingdata['offset'].split(',')
            offset_az_str = offset_az_str.strip().rstrip('°')
            offset_el_str = offset_el_str.strip().rstrip('°')
            global_meta["camras:pointing:offset:az_deg"] = offset_az_str
            global_meta["camras:pointing:offset:el_deg"] = offset_el_str
Thomas Telkamp's avatar
Thomas Telkamp committed
87
        global_meta["camras:pointing:datetime"] = Time.now(
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
88
        ).iso[:19]  # Pointing is only accurate to the second
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
89
    else:
Thomas Telkamp's avatar
Thomas Telkamp committed
90
        global_meta["camras:pointing:source"] = "DT controller"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
91
92
        tracker = dt.tracker.replace("console/", "")
        global_meta["camras:pointing:tracking"] = dt.tracker
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
93
94
        global_meta[
            "camras:pointing:az_deg"] = f"{(dt.az.value + 180) % 360:.4f}"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
95
        global_meta["camras:pointing:el_deg"] = f"{dt.el.value:.4f}"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
96
        global_meta[
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
97
            "camras:pointing:offset:az_deg"] = f"{dt.offset_az.value:+.4f}"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
98
        global_meta[
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
99
100
            "camras:pointing:offset:el_deg"] = f"{dt.offset_el.value:+.4f}"
        global_meta["camras:focusbox_position_m"] = f"{dt.focusbox_pos:.3f}"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
101

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
102
103
104
105
106
107
108
        global_meta["camras:pointing:datetime"] = Time.now(
        ).datetime.isoformat()

        if tracker == 'j2000tracker':
            sky = dt.getRaDec()
            global_meta["camras:pointing:ra_deg"] = f"{dt.radec.ra.deg:.4f}"
            global_meta["camras:pointing:dec_deg"] = f"{dt.radec.dec.deg:.4f}"
109
            global_meta["camras:pointing:radec_hmsdms"] = sky.to_string('hmsdms')
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
110
111
            objects = Table.read('camras_objects.ecsv')

Thomas Telkamp's avatar
Thomas Telkamp committed
112
113
            catalog = SkyCoord(objects["coord"])
            names = objects["name"]
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
114
115
116
117
118
119
120
            idx, d2d, d3d = sky.match_to_catalog_sky(catalog)
            separation = sky.separation(catalog[idx])
            if separation < 6 * u.deg:
                global_meta["camras:pointing:nearest_object"] = names[
                    idx].strip('"')
                global_meta[
                    "camras:pointing:nearest_object_separation_deg"] = f"{separation.deg:.4f}"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
121
122
123
124
        elif tracker == 'sattracker':
            global_meta["camras:pointing:satname"] = dt.satname
            global_meta["camras:pointing:tle1"] = dt.tle1
            global_meta["camras:pointing:tle2"] = dt.tle2
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
125

Thomas Telkamp's avatar
Thomas Telkamp committed
126
        if tracker in ('j2000tracker', 'moontracker', 'suntracker',
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
127
128
129
130
131
                          'sattracker'):
            global_meta[
                "camras:pointing:model_enabled"] = f"{dt.model_enabled}"
            global_meta[
                "camras:pointing:refraction_enabled"] = f"{dt.refraction_enabled}"
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
132
133
134
135
136
137
138

    global_meta["camras:rx_gain"] = rx_gain
    global_meta["camras:bandwidth"] = bandwidth
    global_meta["camras:reference"] = reference.strip('"')
    global_meta["camras:time_source"] = time_source.strip('"')
    global_meta["camras:antenna"] = antenna.strip('"')
    global_meta["camras:channel"] = channel
Thomas Telkamp's avatar
Thomas Telkamp committed
139
140
141

    with open(sigmfname_meta, "w") as sigmfmeta:
        json.dump(meta, sigmfmeta, indent=4)
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
142

143
    return sigmfname_meta
Thomas Telkamp's avatar
Thomas Telkamp committed
144

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
145
146
147
148
149
150
151
152

def is_valid_file(parser, arg):
    if not os.path.exists(arg):
        parser.error(f"The file {arg} does not exist!")
    else:
        return arg


Thomas Telkamp's avatar
Thomas Telkamp committed
153
if __name__ == "__main__":
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
154
155
156
    parser = ArgumentParser(
        description="Make SIGMF metadata out of IQ dump, "
        "metadata CSV and a connection to the telescope console")
157
    parser.add_argument("metadatafile",
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
158
                        type=lambda x: is_valid_file(parser, x))
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
159
160
161
162
163
164
    parser.add_argument(
        "-n",
        "--no-rename",
        help="Dry-run: do not rename files, just write the metadata",
        action="store_true")

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
165
166
    args = parser.parse_args()

167
    make_sigmf(args.metadatafile, no_rename=args.no_rename)