11# All manual references are to R&S RTO Digital Oscilloscope User Manual
22# for firmware 3.65, 2017
3-
43import logging
54import time
65import warnings
1211
1312import qcodes .validators as vals
1413from qcodes .instrument import (
14+ ChannelList ,
15+ ChannelTuple ,
1516 Instrument ,
1617 InstrumentBaseKWArgs ,
1718 InstrumentChannel ,
2627log = logging .getLogger (__name__ )
2728
2829
29- class ScopeTrace (ArrayParameter ):
30+ class ScopeTrace (ArrayParameter [ npt . NDArray , "RohdeSchwarzRTO1000ScopeChannel" ] ):
3031 def __init__ (
31- self , name : str , instrument : InstrumentChannel , channum : int , ** kwargs : Any
32+ self ,
33+ name : str ,
34+ instrument : "RohdeSchwarzRTO1000ScopeChannel" ,
35+ channum : int ,
36+ ** kwargs : Any ,
3237 ) -> None :
3338 """
3439 The ScopeTrace parameter is attached to a channel of the oscilloscope.
@@ -53,6 +58,12 @@ def __init__(
5358 self .channum = channum
5459 self ._trace_ready = False
5560
61+ @property
62+ def root_instrument (self ) -> "RohdeSchwarzRTO1000" :
63+ root_instrument = super ().root_instrument
64+ assert isinstance (root_instrument , RohdeSchwarzRTO1000 )
65+ return root_instrument
66+
5667 def prepare_trace (self ) -> None :
5768 """
5869 Prepare the scope for returning data, calculate the setpoints
@@ -452,7 +463,7 @@ def __init__(
452463ScopeMeasurement = RohdeSchwarzRTO1000ScopeMeasurement
453464
454465
455- class RohdeSchwarzRTO1000ScopeChannel (InstrumentChannel ):
466+ class RohdeSchwarzRTO1000ScopeChannel (InstrumentChannel [ "RohdeSchwarzRTO1000" ] ):
456467 """
457468 Class to hold an input channel of the scope.
458469
@@ -462,7 +473,7 @@ class RohdeSchwarzRTO1000ScopeChannel(InstrumentChannel):
462473
463474 def __init__ (
464475 self ,
465- parent : Instrument ,
476+ parent : "RohdeSchwarzRTO1000" ,
466477 name : str ,
467478 channum : int ,
468479 ** kwargs : "Unpack[InstrumentBaseKWArgs]" ,
@@ -631,12 +642,12 @@ def __init__(
631642 def _set_range (self , value : float ) -> None :
632643 self .scale .cache .set (value / 10 )
633644
634- self ._parent .write (f"CHANnel{ self .channum } :RANGe { value } " )
645+ self .parent .write (f"CHANnel{ self .channum } :RANGe { value } " )
635646
636647 def _set_scale (self , value : float ) -> None :
637648 self .range .cache .set (value * 10 )
638649
639- self ._parent .write (f"CHANnel{ self .channum } :SCALe { value } " )
650+ self .parent .write (f"CHANnel{ self .channum } :SCALe { value } " )
640651
641652
642653ScopeChannel = RohdeSchwarzRTO1000ScopeChannel
@@ -966,15 +977,31 @@ def __init__(
966977 """Parameter error_next"""
967978
968979 # Add the channels to the instrument
980+ scope_channels = ChannelList (
981+ self , "scope_channels" , RohdeSchwarzRTO1000ScopeChannel
982+ )
983+ """ChannelTuple holding the scope channels.
984+ """
969985 for ch in range (1 , self .num_chans + 1 ):
970986 chan = RohdeSchwarzRTO1000ScopeChannel (self , f"channel{ ch } " , ch )
987+ scope_channels .append (chan )
971988 self .add_submodule (f"ch{ ch } " , chan )
972-
989+ self .scope_channels : ChannelTuple [RohdeSchwarzRTO1000ScopeChannel ] = (
990+ self .add_submodule ("scope_channels" , scope_channels .to_channel_tuple ())
991+ )
992+ measurements = ChannelList (
993+ self , "measurements" , RohdeSchwarzRTO1000ScopeMeasurement
994+ )
973995 for measId in range (1 , self .num_meas + 1 ):
974996 measCh = RohdeSchwarzRTO1000ScopeMeasurement (
975997 self , f"measurement{ measId } " , measId
976998 )
999+ measurements .append (measCh )
9771000 self .add_submodule (f"meas{ measId } " , measCh )
1001+ self .measurements : ChannelTuple [RohdeSchwarzRTO1000ScopeMeasurement ] = (
1002+ self .add_submodule ("measurements" , measurements .to_channel_tuple ())
1003+ )
1004+ """ChannelTuple holding the scope measurements."""
9781005
9791006 self .add_function ("stop" , call_cmd = "STOP" )
9801007 self .add_function ("reset" , call_cmd = "*RST" )
@@ -1055,10 +1082,8 @@ def _make_traces_not_ready(self) -> None:
10551082 """
10561083 Make the scope traces be not ready.
10571084 """
1058- self .ch1 .trace ._trace_ready = False
1059- self .ch2 .trace ._trace_ready = False
1060- self .ch3 .trace ._trace_ready = False
1061- self .ch4 .trace ._trace_ready = False
1085+ for chan in self .scope_channels :
1086+ chan .trace ._trace_ready = False
10621087
10631088 def _set_trigger_level (self , value : float ) -> None :
10641089 """
@@ -1071,7 +1096,7 @@ def _set_trigger_level(self, value: float) -> None:
10711096 source = trans [self .trigger_source .get ()]
10721097 if source != 5 :
10731098 submodule = self .submodules [f"ch{ source } " ]
1074- assert isinstance (submodule , InstrumentChannel )
1099+ assert isinstance (submodule , RohdeSchwarzRTO1000ScopeChannel )
10751100 v_range = submodule .range ()
10761101 offset = submodule .offset ()
10771102
0 commit comments