added capture time for every sweep
This commit is contained in:
@@ -332,10 +332,15 @@ class MultiDeviceLibreVnaService:
|
||||
assert self._sweep_configuration is not None
|
||||
|
||||
self._controller.configure_continuous_sweep(self._sweep_configuration)
|
||||
# Bound the sweep itself rather than reusing `capture_start_ns`: the latter
|
||||
# is taken before any retry/recovery, so it would overstate how long the
|
||||
# traces below took to measure.
|
||||
sweep_start_ns = time.monotonic_ns()
|
||||
result = self._controller.collect_running_sweep_cycles(
|
||||
1,
|
||||
datapoint_timeout_seconds=LIBREVNA_NATIVE_SWEEP_TIMEOUT_SECONDS,
|
||||
)
|
||||
sweep_end_ns = time.monotonic_ns()
|
||||
normalized_s_parameters = {
|
||||
str(name).lower(): np.asarray(values, dtype=np.complex64)
|
||||
for name, values in result.s_parameters.items()
|
||||
@@ -356,6 +361,11 @@ class MultiDeviceLibreVnaService:
|
||||
frequency_hz=frequencies,
|
||||
s11=reflection,
|
||||
s21=self._required_s_parameter(normalized_s_parameters, s_parameter_name),
|
||||
# Every combo comes out of the same synchronized cycle, so
|
||||
# they all share one window — no combo was measured earlier
|
||||
# or later than another here.
|
||||
capture_start_ns=sweep_start_ns,
|
||||
capture_end_ns=sweep_end_ns,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -368,6 +378,7 @@ class MultiDeviceLibreVnaService:
|
||||
|
||||
def _acquire_mock_collection(self, collection_id: int, capture_start_ns: int) -> SweepCollection:
|
||||
assert self._sweep_configuration is not None
|
||||
mock_sweep_start_ns = time.monotonic_ns()
|
||||
points = int(self._sweep_configuration.points)
|
||||
frequencies = np.linspace(
|
||||
self._sweep_configuration.start_hz,
|
||||
@@ -393,6 +404,8 @@ class MultiDeviceLibreVnaService:
|
||||
frequency_hz=frequencies,
|
||||
s11=s11,
|
||||
s21=s21,
|
||||
capture_start_ns=mock_sweep_start_ns,
|
||||
capture_end_ns=time.monotonic_ns(),
|
||||
)
|
||||
)
|
||||
self._mock_phase += 0.05
|
||||
|
||||
@@ -183,7 +183,11 @@ class Sn9000Service:
|
||||
capture_start_ns = time.monotonic_ns()
|
||||
|
||||
s_parameters = self._query_sweep_s_parameters(points)
|
||||
traces = self._assemble_traces(s_parameters)
|
||||
traces = self._assemble_traces(
|
||||
s_parameters,
|
||||
sweep_start_ns=capture_start_ns,
|
||||
sweep_end_ns=time.monotonic_ns(),
|
||||
)
|
||||
|
||||
return SweepCollection(
|
||||
collection_id=int(collection_id),
|
||||
@@ -256,7 +260,13 @@ class Sn9000Service:
|
||||
def _uses_pyvisa_py_backend(self) -> bool:
|
||||
return self.visa_library == "@py" or self.visa_library.endswith("@py")
|
||||
|
||||
def _assemble_traces(self, s_parameters: dict[str, np.ndarray]) -> list[TraceData]:
|
||||
def _assemble_traces(
|
||||
self,
|
||||
s_parameters: dict[str, np.ndarray],
|
||||
*,
|
||||
sweep_start_ns: int,
|
||||
sweep_end_ns: int,
|
||||
) -> list[TraceData]:
|
||||
frequency_hz = self._require_frequency_axis()
|
||||
traces: list[TraceData] = []
|
||||
for output_position, output_port in enumerate(_OUTPUT_PORT_BY_INDEX):
|
||||
@@ -269,6 +279,10 @@ class Sn9000Service:
|
||||
frequency_hz=frequency_hz,
|
||||
s11=reflection,
|
||||
s21=transmission,
|
||||
# One triggered sweep produces every port pair at once, so
|
||||
# all combos share the sweep's window.
|
||||
capture_start_ns=int(sweep_start_ns),
|
||||
capture_end_ns=int(sweep_end_ns),
|
||||
)
|
||||
)
|
||||
return traces
|
||||
|
||||
@@ -140,7 +140,13 @@ class SwitchedMatrixRadarService:
|
||||
)
|
||||
|
||||
def _acquire_step_traces(self, out_k: int, in_k: int, collection_id: int) -> list[TraceData]:
|
||||
"""Drive both switches to one step, settle, and collect its widened traces."""
|
||||
"""Drive both switches to one step, settle, and collect its widened traces.
|
||||
|
||||
Every returned trace carries the monotonic window of the inner collection
|
||||
that produced it, so a consumer can tell when each combo of a switched
|
||||
matrix was really measured instead of only when the whole cycle began and
|
||||
ended. The switch drive and settling are deliberately outside the window.
|
||||
"""
|
||||
step_start_ns = time.monotonic_ns()
|
||||
if self.output_switch is not None:
|
||||
self.output_switch.switch_to(out_k)
|
||||
@@ -178,6 +184,11 @@ class SwitchedMatrixRadarService:
|
||||
input=in_k * self.inner_input_positions + int(trace.combo.input),
|
||||
output=out_k * self.inner_output_positions + int(trace.combo.output),
|
||||
),
|
||||
# Keep the inner service's own per-trace window when it reports one
|
||||
# (it knows its internal port order better than this step does);
|
||||
# otherwise fall back to the window of this inner collection.
|
||||
capture_start_ns=int(trace.capture_start_ns) or settled_ns,
|
||||
capture_end_ns=int(trace.capture_end_ns) or inner_end_ns,
|
||||
)
|
||||
for trace in sub.traces
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user