22Copyright (C) 2025-2025 Pico Technology Ltd. See LICENSE file for terms. 
33""" 
44
5+ # flake8: noqa 
6+ # pylint: skip-file 
57import  ctypes 
68import  os 
79import  platform 
1012import  numpy  as  np 
1113import  numpy .ctypeslib  as  npc 
1214
15+ from  ._classes ._channel_class  import  ChannelClass 
1316from  .error_list  import  ERROR_STRING 
1417from  .constants  import  * 
1518from  . import  constants  as  cst 
@@ -55,15 +58,13 @@ def __init__(self, dll_name, *args, **kwargs):
5558
5659        # Setup class variables 
5760        self .handle  =  ctypes .c_short ()
58-         self .range  =  {}
59-         self .probe_scale  =  {}
61+         self .channel_db : dict [int , ChannelClass ] =  {}
6062        self .resolution  =  None 
6163        self .max_adc_value  =  None 
6264        self .min_adc_value  =  None 
6365        self .over_range  =  0 
6466        self ._actual_interval  =  0 
65- 
66-         self .ylim  =  (0 , 0 )
67+         self .last_used_volt_unit : str  =  'mv' 
6768
6869    def  __exit__ (self ):
6970        self .close_unit ()
@@ -312,7 +313,7 @@ def _get_enabled_channel_flags(self) -> int:
312313            int: Decimal of enabled channels 
313314        """ 
314315        enabled_channel_byte  =  0 
315-         for  channel  in  self .range :
316+         for  channel  in  self .channel_db :
316317            enabled_channel_byte  +=  2 ** channel 
317318        return  enabled_channel_byte 
318319
@@ -831,22 +832,21 @@ def get_minimum_timebase_stateless(self) -> dict:
831832        }
832833
833834    # Data conversion ADC/mV & ctypes/int 
834-     def  mv_to_adc (self , mv : float , channel_range :  int ,  channel : CHANNEL  =  None ) ->  int :
835+     def  mv_to_adc (self , mv : float , channel : CHANNEL  =  None ) ->  int :
835836        """ 
836837        Converts a millivolt (mV) value to an ADC value based on the device's 
837838        maximum ADC range. 
838839
839840        Args: 
840841                mv (float): Voltage in millivolts to be converted. 
841-                 channel_range (int): Range of channel in millivolts i.e. 500 mV. 
842842                channel (CHANNEL, optional): Channel associated with ``mv``. The 
843843                        probe scaling for the channel will be applied if provided. 
844844
845845        Returns: 
846846                int: ADC value corresponding to the input millivolt value. 
847847        """ 
848-         scale  =  self .probe_scale . get ( channel ,  1 ) 
849-         channel_range_mv  =  RANGE_LIST [ channel_range ] 
848+         scale  =  self .channel_db [ channel ]. probe_scale 
849+         channel_range_mv  =  self . channel_db [ channel ]. range_mv 
850850        return  int (((mv  /  scale ) /  channel_range_mv ) *  self .max_adc_value )
851851
852852    def  _adc_conversion (
@@ -857,8 +857,8 @@ def _adc_conversion(
857857    ) ->  float  |  np .ndarray :
858858        """Converts ADC value or array to mV or V using the stored probe scaling.""" 
859859        unit_scale  =  _get_literal (output_unit , OutputUnitV_M )
860-         channel_range_mv  =  RANGE_LIST [ self .range [channel ]] 
861-         channel_scale  =  self .probe_scale [channel ]
860+         channel_range_mv  =  self .channel_db [channel ]. range_mv 
861+         channel_scale  =  self .channel_db [channel ]. probe_scale 
862862        return  (((adc  /  self .max_adc_value ) *  channel_range_mv ) *  channel_scale ) /  unit_scale 
863863
864864    def  _adc_to_ (
@@ -882,6 +882,10 @@ def _adc_to_(
882882        Returns: 
883883            dict | float | np.ndarray: _description_ 
884884        """ 
885+ 
886+         # Update last used 
887+         self .last_used_volt_unit  =  unit 
888+ 
885889        if  isinstance (data , dict ):
886890            for  channel , adc  in  data .items ():
887891                data [channel ] =  self ._adc_conversion (adc , channel , output_unit = unit )
@@ -910,6 +914,7 @@ def adc_to_mv(
910914        Returns: 
911915            dict, int, float, np.ndarray: Data converted into millivolts (mV) 
912916        """ 
917+         self .last_used_volt_unit  =  'mv'   # Update last used 
913918        return  self ._adc_to_ (data , channel , unit = 'mv' )
914919
915920    def  adc_to_volts (
@@ -931,6 +936,7 @@ def adc_to_volts(
931936        Returns: 
932937            dict, int, float, np.ndarray: Data converted into volts (V) 
933938        """ 
939+         self .last_used_volt_unit  =  'v'   # Update last used 
934940        return  self ._adc_to_ (data , channel , unit = 'v' )
935941
936942    def  _thr_hyst_mv_to_adc (
@@ -941,11 +947,12 @@ def _thr_hyst_mv_to_adc(
941947            hysteresis_upper_mv ,
942948            hysteresis_lower_mv 
943949    ) ->  tuple [int , int , int , int ]:
944-         if  channel  in  self .range :
945-             upper_adc  =  self .mv_to_adc (threshold_upper_mv , self .range [channel ], channel )
946-             lower_adc  =  self .mv_to_adc (threshold_lower_mv , self .range [channel ], channel )
947-             hyst_upper_adc  =  self .mv_to_adc (hysteresis_upper_mv , self .range [channel ], channel )
948-             hyst_lower_adc  =  self .mv_to_adc (hysteresis_lower_mv , self .range [channel ], channel )
950+         if  channel  in  self .channel_db :
951+             ch_range  =  self .channel_db [channel ].range 
952+             upper_adc  =  self .mv_to_adc (threshold_upper_mv , channel )
953+             lower_adc  =  self .mv_to_adc (threshold_lower_mv , channel )
954+             hyst_upper_adc  =  self .mv_to_adc (hysteresis_upper_mv , channel )
955+             hyst_lower_adc  =  self .mv_to_adc (hysteresis_lower_mv , channel )
949956        else :
950957            upper_adc  =  int (threshold_upper_mv )
951958            lower_adc  =  int (threshold_lower_mv )
@@ -968,43 +975,39 @@ def _change_power_source(self, state: POWER_SOURCE) -> 0:
968975            state 
969976        )
970977
971-     def  _set_ylim (self , ch_range : RANGE  |  range_literal ) ->  None :
972-         """ 
973-         Update the scope self.ylim with the largest channel range 
974- 
975-         Args: 
976-             ch_range (RANGE | range_literal): Range of current channel 
977-         """ 
978-         # Convert to mv 
979-         ch_range  =  RANGE_LIST [ch_range ]
980- 
981-         # Compare largest value 
982-         max_ylim  =  max (self .ylim [1 ], ch_range )
983-         min_ylim  =  - max_ylim 
984-         self .ylim  =  (min_ylim , max_ylim )
985- 
986-     def  get_ylim (self , unit : OutputUnitV_L  =  'mv' ) ->  tuple [float , float ]:
978+     def  get_ylim (self , unit : str  |  None  |  OutputUnitV_L  =  None ) ->  tuple [float , float ]:
987979        """ 
988-         Returns the ylim of the widest channel range as a tuple. 
980+         Returns the ylim of the widest channel range as a tuple. The unit is taken from 
981+         the last used adc to voltage conversion, but can be overwritten by declaring a 
982+         `unit` variable. 
989983        Ideal for pyplot ylim function. 
990984
991985        Args: 
992-             unit (str): 'mv' or 'v'. Depending on whether your data is in mV  
993-                 or Volts . 
986+             unit (str | None, optional ): Overwrite the ylim unit using ` 'mv'`  or ` 'v'`.  
987+                 If None, The unit will be taken from the last voltage unit conversion . 
994988
995989        Returns: 
996-             tuple[float,  float]: Minium and maximum range values 
990+             tuple[float,float]: Minium and maximum range values 
997991
998992        Examples: 
999993            >>> from matplotlib import pyplot as plt 
1000994            >>> ... 
1001995            >>> plt.ylim(scope.get_ylim()) 
1002996        """ 
997+         if  unit  is  None :
998+             # Collect last used voltage unit 
999+             unit  =  self .last_used_volt_unit 
1000+ 
1001+         # Get largest channel range 
1002+         largest_range_index  =  max (
1003+             self .channel_db ,
1004+             key = lambda  ch : self .channel_db [ch ].range_mv 
1005+             )
10031006        unit  =  unit .lower ()
1004-         if  unit . lower ()  ==  'mv' :
1005-             return  self .ylim 
1006-         elif  unit . lower () :
1007-             return  self .ylim [ 0 ]  /   1000 ,  self . ylim [ 1 ]  /   1000 
1007+         if  unit  ==  'mv' :
1008+             return  self .channel_db [ largest_range_index ]. ylim_mv 
1009+         elif  unit   ==   'v' :
1010+             return  self .channel_db [ largest_range_index ]. ylim_v 
10081011
10091012    def  set_device_resolution (self , resolution : RESOLUTION ) ->  None :
10101013        """Configure the ADC resolution using ``ps6000aSetDeviceResolution``. 
@@ -1054,8 +1057,8 @@ def set_simple_trigger(
10541057        channel  =  _get_literal (channel , channel_map )
10551058        direction  =  _get_literal (direction , trigger_dir_m )
10561059
1057-         if  channel  in  self .range :
1058-             threshold_adc  =  self .mv_to_adc (threshold_mv , self . range [ channel ],  channel )
1060+         if  channel  in  self .channel_db :
1061+             threshold_adc  =  self .mv_to_adc (threshold_mv , channel )
10591062        else :
10601063            threshold_adc  =  int (threshold_mv )
10611064
@@ -1454,12 +1457,12 @@ def set_data_buffer_for_enabled_channels(
14541457        channels_buffer  =  {}
14551458        # Rapid 
14561459        if  captures  >  0 :
1457-             for  channel  in  self .range :
1460+             for  channel  in  self .channel_db :
14581461                np_buffer  =  self .set_data_buffer_rapid_capture (channel , samples , captures , segment , datatype , ratio_mode , action = ACTION .ADD )
14591462                channels_buffer [channel ] =  np_buffer 
14601463        # Single 
14611464        else :
1462-             for  channel  in  self .range :
1465+             for  channel  in  self .channel_db :
14631466                channels_buffer [channel ] =  self .set_data_buffer (channel , samples , segment , datatype , ratio_mode , action = ACTION .ADD )
14641467
14651468        return  channels_buffer 
@@ -1763,6 +1766,9 @@ def run_simple_block_capture(
17631766            >>> buffers = scope.run_simple_block_capture(timebase=3, samples=1000) 
17641767        """ 
17651768
1769+         # Update last used 
1770+         self .last_used_volt_unit  =  output_unit 
1771+ 
17661772        # Create data buffers 
17671773        channel_buffer  =  \
17681774            self .set_data_buffer_for_enabled_channels (samples , segment , datatype , ratio_mode )
@@ -1821,6 +1827,8 @@ def run_simple_rapid_block_capture(
18211827            tuple[dict,np.ndarray]: Dictionary of channel buffers and the time 
18221828                axis (numpy array). 
18231829        """ 
1830+         # Update last used 
1831+         self .last_used_volt_unit  =  output_unit 
18241832
18251833        # Segment set to 0 
18261834        segment  =  0 
0 commit comments