Skip to content

Commit 18c2209

Browse files
Working on R&S converter fixes and updates.
1 parent bd190c0 commit 18c2209

1 file changed

Lines changed: 21 additions & 26 deletions

File tree

sigmf/convert/rohdeschwarz.py

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
# SPDX-License-Identifier: LGPL-3.0-or-later
66
#
7-
# Last Updated: 6-01-2026
7+
# Last Updated: 6-03-2026
88

99
"""Rohde and Schwarz Converter"""
1010

@@ -18,7 +18,7 @@
1818

1919
from datetime import datetime, timedelta, timezone
2020
from pathlib import Path
21-
from typing import List, Optional, Tuple
21+
from typing import Optional, Tuple
2222

2323
import numpy as np
2424

@@ -123,22 +123,19 @@ def validate_rohdeschwarz(xml_path: Path) -> None:
123123
tree = parse(xml_path)
124124
root = tree.getroot()
125125

126-
# validate CenterFrequency
127-
center_freq_raw = _text_of(root, "Clock")
128-
try:
129-
center_frequency = float(center_freq_raw)
130-
except (TypeError, ValueError) as err:
131-
raise SigMFConversionError(f"Invalid or missing CenterFrequency: {center_freq_raw}") from err
132-
133-
# validate SampleRate
126+
# validate (number of) Samples
134127
num_samples_raw = _text_of(root, "Samples")
135128
try:
136-
sample_rate = float(num_samples_raw)
129+
num_samples = float(num_samples_raw)
137130
except (TypeError, ValueError) as err:
138-
raise SigMFConversionError(f"Invalid or missing SampleRate: {num_samples_raw}") from err
131+
raise SigMFConversionError(f"Invalid or missing Number Of SamplesleRate Raw: {num_samples_raw} Converted to Float: {num_samples}" ) from err
139132

140-
if sample_rate <= 0:
141-
raise SigMFConversionError(f"Invalid SampleRate: {sample_rate} (must be > 0)")
133+
# Validate sample rate - "Clock"
134+
sample_rate_raw= _text_of(root, "Clock")
135+
if float(sample_rate_raw) <= 0:
136+
raise SigMFConversionError(f"Invalid SampleRate: {sample_rate_raw} (must be > 0)")
137+
if sample_rate_raw is None:
138+
raise SigMFConversionError("Missing Sammple Rate (Clock) in rohdeschwarz XML")
142139

143140
# validate ScalingFactor, for example, "1"
144141
scaling_factor_raw = _text_of(root, "ScalingFactor")
@@ -167,7 +164,7 @@ def validate_rohdeschwarz(xml_path: Path) -> None:
167164
if numberofchannels_raw is None:
168165
# Missing NumberOfChannels in rohdeschwarz XML so use 1
169166
numberofchannels_raw =1
170-
167+
171168
# validate associated IQ file exists - example IQ file name "File.complex.1ch.float32"
172169
datafilename_raw = _text_of(root, "DataFilename")
173170
if datafilename_raw is None:
@@ -215,9 +212,9 @@ def _build_metadata(xml_path: Path) -> Tuple[dict, dict, list, int]:
215212
# validate required fields and associated IQ file
216213
validate_rohdeschwarz(xml_path)
217214

218-
# extract and convert required fields
215+
# extract and convert required fields that were previously validated
219216

220-
# TODO: R&S files don't seem to have a center frequency field, so maybe add a comment about this being an Oscilloscope capture.
217+
# TODO: R&S files don't have a center frequency field, so maybe add a comment about this being an SA or Oscilloscope capture.
221218
center_frequency = float("0")
222219

223220
numberofchannels_raw = _text_of(root, "NumberOfChannels")
@@ -229,7 +226,6 @@ def _build_metadata(xml_path: Path) -> Tuple[dict, dict, list, int]:
229226
numberofchannels = int(numberofchannels_raw)
230227

231228
sample_rate = float(_text_of(root, "Clock"))
232-
233229
data_type_raw = _text_of(root, "DataType")
234230

235231
# optional EpochNanos field
@@ -265,14 +261,6 @@ def _build_metadata(xml_path: Path) -> Tuple[dict, dict, list, int]:
265261
except ValueError:
266262
log.warning(f"could not parse DataFileName: {datafilename_raw}")
267263

268-
scale_factor = None
269-
scale_factor_raw = _text_of(root, "ScaleFactor")
270-
if scale_factor_raw:
271-
try:
272-
scale_factor = float(scale_factor_raw)
273-
except ValueError:
274-
log.warning(f"could not parse ScaleFactor: {scale_factor_raw}")
275-
276264
# parse optional preview data if present
277265
preview_node = root.find(".//PreviewData")
278266
if preview_node is not None:
@@ -310,10 +298,17 @@ def _build_metadata(xml_path: Path) -> Tuple[dict, dict, list, int]:
310298
elem_size = np.dtype(np.float32).itemsize
311299
frame_bytes = 2 * elem_size # I and Q components
312300

301+
#TODO: Test and validate
302+
sample_count = _text_of(root, "Samples")
303+
log.debug("sample count: %d", sample_count)
304+
313305
# calculate sample count using the original IQ data file size
314306
sample_count_calculated = filesize // frame_bytes
315307
log.debug("sample count: %d", sample_count_calculated)
316308

309+
if sample_count != sample_count_calculated:
310+
log.debug("sample counts not equal")
311+
317312
# convert the datetime object to an ISO 8601 formatted string if EpochNanos is present
318313
iso_8601_string = None
319314
if epoch_nanos is not None:

0 commit comments

Comments
 (0)