def test_create_on_off_val_mapping_for(on_val, off_val): """ Explicitly test ``create_on_off_val_mapping`` function by covering some of the edge cases of ``on_val`` and ``off_val`` """ val_mapping = create_on_off_val_mapping(on_val=on_val, off_val=off_val) values_list = list(set(val_mapping.values())) assert len(values_list) == 2 assert on_val in values_list assert off_val in values_list assert val_mapping[1] is on_val assert val_mapping[True] is on_val assert val_mapping['1'] is on_val assert val_mapping['ON'] is on_val assert val_mapping['On'] is on_val assert val_mapping['on'] is on_val assert val_mapping[0] is off_val assert val_mapping[False] is off_val assert val_mapping['0'] is off_val assert val_mapping['OFF'] is off_val assert val_mapping['Off'] is off_val assert val_mapping['off'] is off_val from qcodes.instrument.parameter import invert_val_mapping inverse = invert_val_mapping(val_mapping) assert inverse[on_val] is True assert inverse[off_val] is False
def test_its_inverse_maps_only_to_booleans(self): from qcodes.instrument.parameter import invert_val_mapping inverse = invert_val_mapping( create_on_off_val_mapping(on_val='666', off_val='000')) self.assertDictEqual(inverse, {'666': True, '000': False})
def test_with_default_arguments(self): """ Due to the fact that `hash(True) == hash(1)`/`hash(False) == hash( 0)`, in this case of `on_val is True`/`off_val is False` the values of `1`/`0` are not added to the `val_mapping`. But this test only ensures that the inverted value mapping is equivalent to "passing boolean values through". """ val_mapping = create_on_off_val_mapping() values_set = set(list(val_mapping.values())) self.assertEqual(values_set, {True, False}) from qcodes.instrument.parameter import invert_val_mapping inverse = invert_val_mapping(val_mapping) assert inverse[True] is True assert inverse[False] is False
class Buffer7510(InstrumentChannel): """ Treat the reading buffer as a submodule, similar to Sense. """ default_buffer = {"defbuffer1", "defbuffer2"} buffer_elements = { "date": "DATE", "measurement_formatted": "FORMatted", "fractional_seconds": "FRACtional", "measurement": "READing", "relative_time": "RELative", "seconds": "SEConds", "measurement_status": "STATus", "time": "TIME", "timestamp": "TSTamp", "measurement_unit": "UNIT" } inverted_buffer_elements = invert_val_mapping(buffer_elements) def __init__( self, parent: 'Keithley7510', name: str, size: Optional[int] = None, style: str = '' ) -> None: super().__init__(parent, name) self._size = size self.style = style if self.short_name not in self.default_buffer: # when making a new buffer, the "size" parameter is required. if size is None: raise TypeError( "buffer() missing 1 required positional argument: 'size'" ) self.write( f":TRACe:MAKE '{self.short_name}', {self._size}, {self.style}" ) else: # when referring to default buffer, "size" parameter is not needed. if size is not None: self.log.warning( f"Please use method 'size()' to resize default buffer " f"{self.short_name} size to {self._size}." ) self.add_parameter( "size", get_cmd=f":TRACe:POINts? '{self.short_name}'", set_cmd=f":TRACe:POINts {{}}, '{self.short_name}'", get_parser=int, docstring="The number of readings a buffer can store." ) self.add_parameter( "number_of_readings", get_cmd=f":TRACe:ACTual? '{self.short_name}'", get_parser=int, docstring="Get the number of readings in the reading buffer." ) self.add_parameter( "last_index", get_cmd=f":TRACe:ACTual:END? '{self.short_name}'", get_parser=int, docstring="Get the last index of readings in the reading buffer." ) self.add_parameter( "first_index", get_cmd=f":TRACe:ACTual:STARt? '{self.short_name}'", get_parser=int, docstring="Get the starting index of readings in the reading " "buffer." ) self.add_parameter( "data_start", initial_value=1, get_cmd=None, set_cmd=None, docstring="First index of the data to be returned." ) self.add_parameter( "data_end", initial_value=1, get_cmd=None, set_cmd=None, docstring="Last index of the data to be returned." ) self.add_parameter( "elements", get_cmd=None, get_parser=self._from_scpi_to_name, set_cmd=None, set_parser=self._from_name_to_scpi, vals=Lists(Enum(*list(self.buffer_elements.keys()))), docstring="List of buffer elements to read." ) self.add_parameter( "setpoints_start", label="start value for the setpoints", source=None, parameter_class=DelegateParameter ) self.add_parameter( "setpoints_stop", label="stop value for the setpoints", source=None, parameter_class=DelegateParameter ) self.add_parameter( "n_pts", label="total n for the setpoints", get_cmd=self._get_n_pts ) self.add_parameter( "setpoints", parameter_class=GeneratedSetPoints, start=self.setpoints_start, stop=self.setpoints_stop, n_points=self.n_pts, vals=Arrays(shape=(self.n_pts.get_latest,)) ) self.add_parameter( "t_start", label="start time", unit="s", initial_value=0, get_cmd=None, set_cmd=None, set_parser=float ) self.add_parameter( "t_stop", label="stop time", unit="s", initial_value=1, get_cmd=None, set_cmd=None, set_parser=float ) self.add_parameter( "fill_mode", get_cmd=f":TRACe:FILL:MODE? '{self.short_name}'", set_cmd=f":TRACe:FILL:MODE {{}}, '{self.short_name}'", vals=Enum('CONT', 'continuous', 'ONCE', 'once'), docstring="if a reading buffer is filled continuously or is filled" " once and stops" ) def _from_name_to_scpi(self, element_names: List[str]) -> List[str]: return [self.buffer_elements[element] for element in element_names] def _from_scpi_to_name(self, element_scpis: List[str]) -> List[str]: if element_scpis is None: return [] return [ self.inverted_buffer_elements[element] for element in element_scpis ] def _get_n_pts(self) -> int: return self.data_end() - self.data_start() + 1 def set_setpoints(self, start: Parameter, stop: Parameter, label: Optional[str] = None) -> None: self.setpoints_start.source = start self.setpoints_stop.source = stop self.setpoints.unit = start.unit if label is not None: self.setpoints.label = label def __enter__(self) -> "Buffer7510": return self def __exit__(self, exception_type: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[TracebackType]) -> None: self.delete() @property def available_elements(self) -> set: return set(self.buffer_elements.keys()) @property def n_elements(self) -> int: return max(1, len(self.elements())) @property def data(self) -> DataArray7510: return self._get_data() def get_last_reading(self) -> str: """ This method requests the latest reading from a reading buffer. """ if not self.elements(): return self.ask(f":FETCh? '{self.short_name}'") fetch_elements = [ self.buffer_elements[element] for element in self.elements() ] return self.ask( f":FETCh? '{self.short_name}', {','.join(fetch_elements)}" ) def _get_data(self) -> DataArray7510: """ This command returns the data in the buffer, depends on the user selected elements. """ try: _ = self.setpoints() except NotImplementedError: # if the "setpionts" has not been implemented, use a time series # with parameters "t_start" and "t_stop": self.set_setpoints(self.t_start, self.t_stop) if self.parent.digi_sense_function() == "None": # when current sense is not digitize sense sense_function = self.parent.sense_function() unit = Sense7510.function_modes[sense_function]["unit"] else: # when current sense is digitize sense sense_function = self.parent.digi_sense_function() unit = DigitizeSense7510.function_modes[sense_function]["unit"] elements_units = { "date": "str", "measurement_formatted": "str", "fractional_seconds": "s", "measurement": unit, "relative_time": "s", "seconds": "s", "measurement_status": "", "time": "str", "timestamp": "str", "measurement_unit": "str" } if not self.elements(): raw_data = self.ask(f":TRACe:DATA? " f"{self.data_start()}, " f"{self.data_end()}, " f"'{self.short_name}'") else: elements = \ [self.buffer_elements[element] for element in self.elements()] raw_data = self.ask(f":TRACe:DATA? {self.data_start()}, " f"{self.data_end()}, " f"'{self.short_name}', " f"{','.join(elements)}") all_data = raw_data.split(",") if len(self.elements()) == 0: elements = ['measurement'] else: elements = self.elements() n_elements = len(elements) units = tuple(elements_units[element] for element in elements) processed_data = dict.fromkeys(elements) for i, (element, unit) in enumerate(zip(elements, units)): if unit == 'str': processed_data[element] = np.array(all_data[i::n_elements]) else: processed_data[element] = np.array([ float(v) for v in all_data[i::n_elements] ]) data = DataArray7510( names=tuple(elements), shapes=((self.n_pts(),),) * n_elements, units=units, setpoints=((self.setpoints(),),) * n_elements, setpoint_units=((self.setpoints.unit,),) * n_elements, setpoint_names=((self.setpoints.label,),) * n_elements ) data._data = tuple( tuple(processed_data[element]) for element in elements ) for i in range(len(data.names)): setattr(data, data.names[i], tuple(processed_data[data.names[i]])) return data def clear_buffer(self) -> None: """ Clear the data in the buffer """ self.write(f":TRACe:CLEar '{self.short_name}'") def trigger_start(self) -> None: """ This method makes readings using the active measure function and stores them in a reading buffer. """ self.write(f":TRACe:TRIGger '{self.short_name}'") def delete(self) -> None: if self.short_name not in self.default_buffer: self.parent.submodules.pop(f"_buffer_{self.short_name}") self.parent.buffer_name("defbuffer1") self.write(f":TRACe:DELete '{self.short_name}'")
class Buffer2450(InstrumentChannel): """ Treat the reading buffer as a submodule, similar to Sense and Source """ default_buffer = {"defbuffer1", "defbuffer2"} buffer_elements = { "date": "DATE", "measurement_formatted": "FORMatted", "fractional_seconds": "FRACtional", "measurement": "READing", "relative_time": "RELative", "seconds": "SEConds", "source_value": "SOURce", "source_value_formatted": "SOURFORMatted", "source_value_status": "SOURSTATus", "source_value_unit": "SOURUNIT", "measurement_status": "STATus", "time": "TIME", "timestamp": "TSTamp", "measurement_unit": "UNIT" } inverted_buffer_elements = invert_val_mapping(buffer_elements) def __init__(self, parent: 'Keithley2450', name: str, size: Optional[int] = None, style: str = '') -> None: super().__init__(parent, name) self.buffer_name = name self._size = size self.style = style if self.buffer_name not in self.default_buffer: # when making a new buffer, the "size" parameter is required. if size is None: raise TypeError( "buffer() missing 1 required positional argument: 'size'") self.write( f":TRACe:MAKE '{self.buffer_name}', {self._size}, {self.style}" ) else: # when referring to default buffer, "size" parameter is not needed. if size is not None: self.log.warning( f"Please use method 'size()' to resize default buffer " f"{self.buffer_name} size to {self._size}.") self.add_parameter( "size", get_cmd=f":TRACe:POINts? '{self.buffer_name}'", set_cmd=f":TRACe:POINts {{}}, '{self.buffer_name}'", get_parser=int, docstring="The number of readings a buffer can store.") self.add_parameter( "number_of_readings", get_cmd=f":TRACe:ACTual? '{self.buffer_name}'", get_parser=int, docstring="To get the number of readings in the reading buffer.") self.add_parameter("elements", get_cmd=None, get_parser=self.from_scpi_to_name, set_cmd=None, set_parser=self.from_name_to_scpi, vals=Lists( Enum(*list(self.buffer_elements.keys()))), docstring="List of buffer elements to read.") def from_name_to_scpi(self, element_names: List[str]) -> List[str]: return [self.buffer_elements[element] for element in element_names] def from_scpi_to_name(self, element_scpis: List[str]) -> List[str]: if element_scpis is None: return [] return [ self.inverted_buffer_elements[element] for element in element_scpis ] def __enter__(self) -> "Buffer2450": return self def __exit__(self, exception_type: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[TracebackType]) -> None: self.delete() @property def available_elements(self) -> set: return set(self.buffer_elements.keys()) def get_last_reading(self) -> str: """ This method requests the latest reading from a reading buffer. """ if not self.elements(): return self.ask(f":FETCh? '{self.buffer_name}'") fetch_elements = [ self.buffer_elements[element] for element in self.elements() ] return self.ask( f":FETCh? '{self.buffer_name}', {','.join(fetch_elements)}") def get_data(self, start_idx: int, end_idx: int, readings_only: bool = False) -> list: """ This command returns specified data elements from reading buffer. Args: start_idx: beginning index of the buffer to return end_idx: ending index of the buffer to return readings_only: a flag to temporarily disable the elements and output only the numerical readings Returns: data elements from the reading buffer """ if (not self.elements()) or readings_only: raw_data = self.ask(f":TRACe:DATA? {start_idx}, {end_idx}, " f"'{self.buffer_name}'") return [float(i) for i in raw_data.split(",")] elements = \ [self.buffer_elements[element] for element in self.elements()] raw_data_with_extra = self.ask(f":TRACe:DATA? {start_idx}, " f"{end_idx}, " f"'{self.buffer_name}', " f"{','.join(elements)}") return raw_data_with_extra.split(",") def clear_buffer(self) -> None: """ Clear the data in the buffer """ self.write(f":TRACe:CLEar '{self.buffer_name}'") def trigger_start(self) -> None: """ This method makes readings using the active measure function and stores them in a reading buffer. """ self.write(f":TRACe:TRIGger '{self.buffer_name}'") def delete(self) -> None: if self.buffer_name not in self.default_buffer: self.parent.submodules.pop(f"_buffer_{self.buffer_name}") self.parent.buffer_name("defbuffer1") self.write(f":TRACe:DELete '{self.buffer_name}'")