def set_bandwidth(self, ch, bw): """ Set the bandwidth of the phasemeter. The phasemeter can measure deviations in phase and frequency up to the set bandwidth. :type ch: int; *{1,2}* :param ch: Analog channel number to set bandwidth of. :type bw: float; Hz :param n: Desired bandwidth (will be rounded up to to the nearest multiple 10kHz / 2^N with N = [0,10]) :raises ValueError: If the channel number is invalid. :raises ValueOutOfRangeException: if the bandwidth is not positive-definite or the channel number is invalid """ _utils.check_parameter_valid('set', ch, [1, 2], 'channel') _utils.check_parameter_valid('range', bw, [10, 10e3], 'bandwidth', 'Hz') n = max(min(math.ceil(math.log(10e3 / bw, 2)), 10), 0) if ch == 1: self.bandwidth_ch1 = n elif ch == 2: self.bandwidth_ch2 = n log.info("Bandwidth (Ch %d) set to %.2f Hz", ch, 10e3 / (2**n))
def set_offsets(self, position, offset): """ Set offsets throughout the laser locker. :type position : list; ['pid_input', 'out1', 'out2'] :param position : The desired point to add an offset :type offset : float, [-2.0, 2.0] Volts. :param offset : voltage offset. """ _utils.check_parameter_valid('set', position, ['pid_input', 'out1', 'out2'], 'position') _utils.check_parameter_valid('range', offset, [-2.0, 2.0], desc='offset', units='Volts') if position == 'pid_input': self.fast_offset = (offset / (self._adc_gains()[0] * 2**12) / self.lo_scale_factor) elif position == 'out1': self.output_offset_ch1 = (offset / (self._adc_gains()[0] * 2**12) / self.lo_scale_factor) else: self.output_offset_ch2 = (offset / (self._adc_gains()[0] * 2**12) / self.lo_scale_factor)
def set_gain(self, lia_ch, g): """ Sets the gain stage to be on the specified lock-in channel, and configures its gain. This sets the PID stage to be on the opposite channel. :type lia_ch: string; {'main','aux'} :param lia_ch: Channel name :type g: float; [0, 2^16 - 1] :param g: Gain """ _utils.check_parameter_valid('set', lia_ch, allowed=['main', 'aux'], desc="lock-in channel") _utils.check_parameter_valid('range', g, allowed=[0, 2**16 - 1], desc="gain") # Store selected PID channel locally. Signal select regs are updated # on commit. self._pid_channel = 'main' if lia_ch == 'aux' else 'aux' # Store selected gain locally. Update on commit with correct DAC # scaling. self._gainstage_gain = g
def start_data_log(self, duration=10, ch1=True, ch2=True, use_sd=True, filetype='csv'): """ Start logging instrument data to a file. Progress of the data log may be checked calling `progress_data_log`. All outstanding settings must have been committed before starting the data log. This will always be true if *pymoku.autocommit=True*, the default. .. note:: The Moku's internal filesystem is volatile and will be wiped when the Moku is turned off. If you want your data logs to persist either save to SD card or move them to a permanent storage location prior to powering your Moku off. :type duration: float :param duration: Log duration in seconds :type ch1: bool :param ch1: Enable streaming on Channel 1 :type ch2: bool :param ch2: Enable streaming on Channel 2 :type use_sd: bool :param use_sd: Whether to log to the SD card, else the internal Moku filesystem. :type filetype: string :param filetype: Log file type, one of {'csv','bin','mat','npy'} for CSV, Binary, MATLAB or NPY (Numpy Data) respectively. :raises ValueError: if invalid channel enable parameter :raises ValueOutOfRangeException: if duration is invalid """ _utils.check_parameter_valid('bool', ch1, desc='log channel 1') _utils.check_parameter_valid('bool', ch2, desc='log channel 2') _utils.check_parameter_valid('bool', use_sd, desc='log to SD card') _utils.check_parameter_valid('float', duration, desc='log duration', units='sec') _utils.check_parameter_valid('set', filetype, ['csv', 'mat', 'bin', 'npy'], 'log filetype') if self.check_uncommitted_state(): raise UncommittedSettings("Can't start a logging session due to" " uncommitted device settings.") self._stream_start(start=0, duration=duration, ch1=ch1, ch2=ch2, use_sd=use_sd, filetype=filetype)
def set_precision_mode(self, state): """ Change aquisition mode between downsampling and decimation. Precision mode, a.k.a Decimation, samples at full rate and applies a low-pass filter to the data. This improves precision. Normal mode works by direct downsampling, throwing away points it doesn't need. :param state: Select Precision Mode :type state: bool """ _utils.check_parameter_valid('bool', state, desc='precision mode enable') self.ain_mode = _OSC_AIN_DECI if state else _OSC_AIN_DDS
def _set_source(self, ch, source): """ Sets the source of the channel data to either the analog input or internally looped-back digital output. """ # TODO: Add loopback mode parameter _utils.check_parameter_valid('set', ch, [1, 2], 'channel') if ch == 1: self.source_ch1 = source elif ch == 2: self.source_ch2 = source else: raise ValueOutOfRangeException("Incorrect channel number %d", ch)
def get_bandwidth(self, ch): """ Get the bandwidth of the phasemeter. :type ch: int; *{1,2}* :param ch: Analog channel number to get bandwidth of. :rtype: float; Hz :return: Bandwidth :raises ValueError: If the channel number is invalid. """ _utils.check_parameter_valid('set', ch, [1, 2], 'channel') return 10e3 / (2**(self.bandwidth_ch1 if ch == 1 else self.bandwidth_ch2))
def set_monitor(self, monitor_ch, source): """ Configures the specified monitor channel to view the desired PID instrument signal. There are two 12-bit monitoring channels available, 'a' and 'b'; each of these can be assigned to source signals from any of the internal PID instrument monitoring points. Signals larger than 12-bits must be either truncated or clipped to the allowed size. The source is one of: - **adc1** : Channel 1 ADC input - **in1** : PID Channel 1 input (after mixing, offset and scaling) - **out1** : PID Channel 1 output - **adc2** : Channel 2 ADC Input - **in2** : PID Channel 2 input (after mixing, offset and scaling) - **out2** : PID Channel 2 output :type monitor_ch: str; {'a','b'} :param monitor_ch: Monitor channel :type source: str; {'adc1', 'in1', 'out1', 'adc2', 'in2', 'out2'} :param source: Signal to connect to the monitor channel """ _utils.check_parameter_valid('string', monitor_ch, desc="monitor channel") _utils.check_parameter_valid('string', source, desc="monitor signal") monitor_sources = { 'none': _PID_MON_NONE, 'adc1': _PID_MON_ADC1, 'in1': _PID_MON_IN1, 'out1': _PID_MON_OUT1, 'adc2': _PID_MON_ADC2, 'in2': _PID_MON_IN2, 'out2': _PID_MON_OUT2 } monitor_ch = monitor_ch.lower() source = source.lower() _utils.check_parameter_valid('set', monitor_ch, allowed=['a', 'b'], desc="monitor channel") _utils.check_parameter_valid( 'set', source, allowed=['none', 'adc1', 'in1', 'out1', 'adc2', 'in2', 'out2'], desc="monitor source") if monitor_ch == 'a': self.monitor_a = source self.mon1_source = monitor_sources[source] elif monitor_ch == 'b': self.monitor_b = source self.mon2_source = monitor_sources[source] else: raise ValueOutOfRangeException("Invalid channel %d", monitor_ch)
def set_gains_offsets(self, ch, input_gain=1.0, output_gain=1.0, input_offset=0, output_offset=0): """ Configure pre- and post-filter scales and offsets for a given filter channel. .. note:: The overall output gain of the instrument is the product of the gain of the filter, set by the filter coefficients, and the input/output stage gain set here. :type ch: int, {1,2} :param ch: target filter channel :type input_gain, output_gain: float, [-100,100] scalar :param input_gain, output_gain: channel scalars before and after the FIR filter :type input_offset: float, [-1.0,1.0] Volts :param input_offset: channel offset before the FIR filter :type output_offset: float, [-2.0,2.0] Volts :param output_offset: channel offset after the FIR filter """ _utils.check_parameter_valid('set', ch, [1, 2], 'filter channel') _utils.check_parameter_valid('range', input_gain, [-100, 100], 'input scale', 'linear scalar') _utils.check_parameter_valid('range', output_gain, [-100, 100], 'output scale', 'linear scalar') _utils.check_parameter_valid('range', input_offset, [-1.0, 1.0], 'input offset', 'Volts') _utils.check_parameter_valid('range', output_offset, [-2.0, 2.0], 'output offset', 'Volts') # Calculate input/output offset values if ch == 1: self._input_scale1 = input_gain self._output_scale1 = output_gain self._input_offset1 = input_offset self._output_offset1 = output_offset else: self._input_scale2 = input_gain self._output_scale2 = output_gain self._input_offset2 = input_offset self._output_offset2 = output_offset
def gen_off(self, ch=None): """ Turn off the output sweep. If *ch* is specified, turn off only a single channel, otherwise turn off both. :type ch: int; {1,2} :param ch: Channel number to turn off (None, or leave blank, for both) """ _utils.check_parameter_valid('set', ch, [1, 2, None], 'output sweep channel') if ch is None or ch == 1: self.channel1_en = False if ch is None or ch == 2: self.channel2_en = False
def set_ch_phase(self, ch, phase=0.0): """ set the phase of the measurement with respect to the output signal. :type ch: int; {1, 2} :param ch: selects the channel to apply settings. :type phase: float [0.0, 360.0] deg :param phase: phase difference between channel 1 and channel 2. """ _utils.check_parameter_valid('set', ch, [1, 2], 'channel') _utils.check_parameter_valid('range', phase, [0.0, 360.0], 'phase', 'degrees') if ch == 1: self.ch1_meas_phase = (phase / 360.0) * 2**64 else: self.ch2_meas_phase = (phase / 360.0) * 2**64
def set_pid_enables(self, pid_block, en=True): """ Enable or disable the selected PID controller. :type pid_block : int; [1, 2] :param pid_block : PID controller - 1 = Fast, 2 = Slow :type en : bool; :param en : enable or disable PID controller described in pid_block. """ _utils.check_parameter_valid('set', pid_block, [1, 2], 'PID controller') _utils.check_parameter_valid('set', en, [True, False], 'enable') pid_array = [self.fast_pid, self.slow_pid] pid_array[pid_block - 1].enable = en
def enable_offset(self, ch, en=True): """ Enable/disable output offset on the selected channel. :type ch: int; {1, 2} :param ch: Output channel :type en: bool :param en: Enable offset """ _utils.check_parameter_valid('set', ch, [1, 2], 'output channel') _utils.check_parameter_valid('set', en, [True, False], 'enable offset') if ch == 1: self.channel1_en = en else: self.channel2_en = en
def auto_acquire(self, ch=None): """ Restarts the frequency tracking loop and phase counter for the specified channel, or both if no channel is specified. The initial frequency of the channel's tracking loop is automatically acquired, ignoring the manually set seed frequency by :any:`set_initfreq`. To acquire using the manually set seed frequency, see :any:`reacquire`. :type ch: int; *{1,2}* :param ch: Channel number, or ``None`` for both :raises ValueError: If the channel number is invalid. """ _utils.check_parameter_valid('set', ch, [1, 2, None], 'channel') self._strobe_acquire(ch=ch, auto=True)
def set_monitor(self, monitor_ch, source): """ Select the point inside the lockin amplifier to monitor. There are two monitoring channels available, 'A' and 'B'; you can mux any of the internal monitoring points to either of these channels. The source is one of: - **none**: Disable monitor channel - **in1**, **in2**: Input Channel 1/2 - **main**: Lock-in output (Output Channel 1) - **aux**: Auxillary output (Output Channel 2) - **demod**: Demodulation signal input to mixer - **i**, **q**: Mixer I and Q channels respectively. :type monitor_ch: string; {'A','B'} :param monitor_ch: Monitor channel :type source: string; {'none','in1','in2','main','aux','demod','i','q'} :param source: Signal to monitor """ _utils.check_parameter_valid('string', monitor_ch, desc="monitor channel") _utils.check_parameter_valid('string', source, desc="monitor signal") monitor_ch = monitor_ch.lower() source = source.lower() _utils.check_parameter_valid('set', monitor_ch, allowed=['a', 'b'], desc="monitor channel") _utils.check_parameter_valid( 'set', source, allowed=['none', 'in1', 'in2', 'main', 'aux', 'demod', 'i', 'q'], desc="monitor source") monitor_sources = { 'none': _LIA_MON_NONE, 'in1': _LIA_MON_IN1, 'in2': _LIA_MON_IN2, 'main': _LIA_MON_OUT, 'aux': _LIA_MON_AUX, 'demod': _LIA_MON_DEMOD, 'i': _LIA_MON_I, 'q': _LIA_MON_Q, } if monitor_ch == 'a': self.monitor_a = source self.monitor_select0 = monitor_sources[source] elif monitor_ch == 'b': self.monitor_b = source self.monitor_select1 = monitor_sources[source] else: raise ValueOutOfRangeException("Invalid channel %d", monitor_ch)
def enable_amplitude(self, ch, en=True): """ Enable/disable amplitude on the selected channel. :type ch: int; {1, 2} :param ch: Output channel :type en: bool :param en: Enable amplitude) """ _utils.check_parameter_valid('set', ch, [1, 2], 'output channel') _utils.check_parameter_valid('set', en, [True, False], 'enable amplitude') if ch == 1: self.dac1_en = en else: self.dac2_en = en
def set_output_enables(self, ch, en=True): """ Enable or disable the selected output channel. :type ch : int; [1, 2] :param ch : 1 = Output 1, 2 = Output 2 :type en : bool; :param en : enable or disable channel. """ _utils.check_parameter_valid('set', ch, [1, 2], 'output channel') _utils.check_parameter_valid('set', en, [True, False], 'enable') if ch == 1: self.out1_en = en else: self.out2_en = en
def start_sweep(self, single=False): """ Start sweeping :type single: bool :param single: Enable single sweep (otherwise loop) """ _utils.check_parameter_valid('bool', single, desc='enable single sweep') self.adc1_en = True self.adc2_en = True self.dac1_en = True self.dac2_en = True self.sweep_reset = False self.single_sweep = single self.loop_sweep = not single
def get_initfreq(self, ch): """ Reads the seed frequency register of the phase tracking loop Valid if auto acquire has not been used. :type ch: int; *{1,2}* :param ch: Channel number to read the initial frequency of. :rtype: float; Hz :return: Seed frequency :raises ValueError: If the channel number is invalid. """ _utils.check_parameter_valid('set', ch, [1, 2], 'channel') if ch == 1: return self.init_freq_ch1 elif ch == 2: return self.init_freq_ch2
def set_channel_pid_enables(self, pid_block, en=True): """ Enable or disable connection of the selected PID controller to it's corresponding output channel. Fast = Output 1, Slow = Output 2. :type pid_block : int; [1, 2] :param pid_block : PID controller - 1 = Fast, 2 = Slow :type en : bool; :param en : enable or disable channel. """ _utils.check_parameter_valid('set', pid_block, [1, 2], 'PID controller') _utils.check_parameter_valid('set', en, [True, False], 'enable') if pid_block == 1: self.fast_channel_en = en else: self.slow_channel_en = en
def gen_sinewave(self, ch, amplitude, frequency, phase=0.0, phase_locked=False): """ Generate a sinewave signal on the specified output channel :type ch: int; {1,2} :param ch: Channel number :type amplitude: float; V :param amplitude: Signal peak-to-peak amplitude :type frequency: float; Hz :param frequency: Frequency :type phase: float; degrees :param phase: Phase :type phase_locked: boolean :param phase_locked: Locks the phase of the generated sinewave to the measured phase of the input signal :raises ValueError: if the channel number is invalid :raises ValueOutOfRangeException: if wave parameters are out of range """ _utils.check_parameter_valid('set', ch, [1, 2], 'output channel') _utils.check_parameter_valid('range', amplitude, [0.0, 2.0], 'sinewave amplitude', 'Volts') _utils.check_parameter_valid('range', frequency, [0, 250e6], 'sinewave frequency', 'Hz') _utils.check_parameter_valid('range', phase, [0, 360], 'sinewave phase', 'degrees') _utils.check_parameter_valid('set', phase_locked, [True, False], 'phase locked output', 'boolean') if ch == 1: self.pm_out1_frequency = frequency self.pm_out1_amplitude = amplitude self.pm_out1_phase = phase self.pm_out1_locked_out = phase_locked elif ch == 2: self.pm_out2_frequency = frequency self.pm_out2_amplitude = amplitude self.pm_out2_phase = phase self.pm_out2_locked_out = phase_locked
def set_harmonic_multiplier(self, ch, multiplier=1): """ set the harmonic multiplier to demodulate at integer harmonic of output. :type ch: int; {1, 2} :param ch: selects the channel to apply settings. :type multiplier: int; [0, 15] :param multiplier: multiplier applied to fundemental. """ _utils.check_parameter_valid('set', ch, [1, 2], 'channel') _utils.check_parameter_valid( 'set', multiplier, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 'harmonics select') if ch == 1: self.ch1_harmonic_mult = multiplier elif ch == 2: self.ch2_harmonic_mult = multiplier
def set_samplerate(self, samplerate, trigger_offset=0): """ Manually set the sample rate of the instrument. The sample rate is automatically calculated and set in :any: `set_timebase`. This interface allows you to specify the rate at which data is sampled, and set a trigger offset in number of samples. This interface is useful for datalogging and capturing of data frames. :type samplerate: float; *0 < samplerate <= MAX_SAMPLERATE smp/s* :param samplerate: Target samples per second. Will get rounded to the nearest allowable unit. :type trigger_offset: int; *-2^16 < trigger_offset < 2^31* :param trigger_offset: Number of samples before (-) or after (+) the trigger point to start capturing. :raises ValueOutOfRangeException: if either parameter is out of range. """ _utils.check_parameter_valid( 'range', samplerate, [_OSC_SAMPLERATE_MIN, _OSC_SAMPLERATE_MAX], 'samplerate', 'smp/s') _utils.check_parameter_valid('range', trigger_offset, [-2**16 + 1, 2**31 - 1], 'trigger offset', 'samples') decimation = self._input_samplerate / float(samplerate) self.decimation_rate = decimation self.timestep = 1.0 / (self._input_samplerate / self.decimation_rate) # Ensure the buffer offset is large enough to incorporate the desired # pretrigger/posttrigger data self.pretrigger = -math.ceil(trigger_offset / 4.0) \ if trigger_offset > 0 else -math.floor(trigger_offset / 4.0) # We don't want any rendering as each sample is already at the desired # samplerate self.render_deci = 1 # The render offset needs to be corrected for cubic downsampling # (even with unity decimation) self.offset = -round(trigger_offset) + self.render_deci
def set_input_gain(self, gain=0): """ Set the main input gain (Input Channel 1). :type gain: int; {-20, 0, 24, 48} dB :param gain: Input gain """ _utils.check_parameter_valid('set', gain, allowed=[-20, 0, 24, 48], desc="main input gain", units="dB") front_end_setting = self.get_frontend(1) if gain == 0: self.input_gain_select = 0 self.set_frontend(1, fiftyr=front_end_setting[0], atten=False, ac=front_end_setting[2]) elif gain == 24: self.input_gain_select = 1 self.set_frontend(1, fiftyr=front_end_setting[0], atten=False, ac=front_end_setting[2]) elif gain == 48: self.input_gain_select = 2 self.set_frontend(1, fiftyr=front_end_setting[0], atten=False, ac=front_end_setting[2]) elif gain == -20: self.input_gain_select = 0 self.set_frontend(1, fiftyr=front_end_setting[0], atten=True, ac=front_end_setting[2]) else: raise Exception("Invalid input gain value.")
def set_initfreq(self, ch, f): """ Manually set the initial frequency of the designated channel :type ch: int; *{1,2}* :param ch: Channel number to set the initial frequency of. :type f: int; *2e6 < f < 200e6* :param f: Initial locking frequency of the designated channel :raises ValueError: If the channel number is invalid. :raises ValueOutOfRangeException: If the frequency parameter is out of range. """ _utils.check_parameter_valid('range', f, [_PM_FREQ_MIN, _PM_FREQ_MAX], 'initial frequency') _utils.check_parameter_valid('set', ch, [1, 2], 'channel') if ch == 1: self.init_freq_ch1 = int(f) elif ch == 2: self.init_freq_ch2 = int(f)
def enable_input(self, ch=None, en=True): """ Enable or disable the PID channel input(s). If *ch* is None (the default), both channels will be acted upon, otherwise just the one specified by the argument. :type ch: int; {1,2} or None :param ch: Output channel, or both. :type en: bool :param en: Enable the specified input channel(s). :raises InvalidParameterException: Invalid parameters """ _utils.check_parameter_valid('set', ch, [1, 2, None], 'input channel') _utils.check_parameter_valid('bool', en, desc='enable input') if ch is None or ch == 1: self.ch1_input_en = en if ch is None or ch == 2: self.ch2_input_en = en
def gen_off(self, ch=None): """ Turn Waveform Generator output(s) off. The channel will be turned on when configuring the waveform type but can be turned off using this function. If *ch* is None (the default), both channels will be turned off, otherwise just the one specified by the argument. :type ch: int; {1,2} or *None* :param ch: Channel to turn off or *None* for all channels :raises ValueOutOfRangeException: if the channel number is invalid """ _utils.check_parameter_valid('set', ch, [1, 2], 'output channel', allow_none=True) if (ch is None) or ch == 1: self.pm_out1_amplitude = 0 if (ch is None) or ch == 2: self.pm_out2_amplitude = 0
def set_input_range(self, ch, input_range): """Set the input range for a channel. :type ch: int; {1,2} :param ch: channel :type input_range: {1, 10} :param input_range: the peak to peak voltage (Vpp) range of the inputs. """ _utils.check_parameter_valid('set', ch, [1, 2], 'input channel', allow_none=True) _utils.check_parameter_valid('set', input_range, [1, 10], 'input range', allow_none=False) front_end_setting = self.get_frontend(ch) self.set_frontend(ch, fiftyr=front_end_setting[0], atten=(input_range == 10), ac=front_end_setting[2])
def set_output(self, ch, amplitude, offset=0): """ Set the output sweep amplitude. .. note:: Ensure that the output amplitude is set so as to not saturate the inputs. Inputs are limited to 1.0Vpp with attenuation turned off. :type ch: int; {1, 2} :param ch: Output channel :type amplitude: float; [0.0, 2.0] Vpp :param amplitude: Sweep amplitude :type offset: float; [-1.0, 1.0] Volts :param offset: Sweep offset """ _utils.check_parameter_valid('set', ch, [1, 2], 'output channel') _utils.check_parameter_valid('range', amplitude, [0.001, 2.0], 'sweep amplitude', 'Vpp') _utils.check_parameter_valid('range', offset, [-1.0, 1.0], 'sweep offset', 'volts') # ensure combination of amplitude and offset doesn't cause output # clipping if ((amplitude / 2.0) + abs(offset)) > 1.0: raise ValueOutOfRangeException("Output sweep waveform must not " "exceed +/- 1.0 volts. Reduce " "output amplitude and/or offset.") # Set up the output scaling register but also save the voltage value # away for use in the state dictionary to scale incoming data if ch == 1: self.sweep_amplitude_ch1 = amplitude self.sweep_amp_volts_ch1 = amplitude self.sweep_offset_ch1 = offset self.channel1_en = amplitude > 0 elif ch == 2: self.sweep_amplitude_ch2 = amplitude self.sweep_amp_volts_ch2 = amplitude self.sweep_offset_ch2 = offset self.channel2_en = amplitude > 0
def set_control_matrix(self, ch, scale_in1, scale_in2): """ Configure the input control matrix specifying the input signal mixing for the specified filter channel. Input mixing allows a filter channel to act on a linear combination of the two input signals. :type ch: int, {1, 2} :param ch: target filter channel :type scale_in1: float, [-20, 20] :param scale_in1: linear scale factor of input 1 signal added to target filter channel input. To avoid quantization, use at most one decimal place. :type scale_in2: float, [-20, 20] :param scale_in2: linear scale factor of input 2 signal added to target filter channel input. To avoid quantization, use at most one decimal place. """ _utils.check_parameter_valid('set', ch, [1, 2], 'filter channel') _utils.check_parameter_valid('range', scale_in1, [-20, 20], 'control matrix scale (ch1)', 'linear scalar') _utils.check_parameter_valid('range', scale_in2, [-20, 20], 'control matrix scale (ch2)', 'linear scalar') if (scale_in1 / 0.1) % 1 or (scale_in2 / 0.1) % 1: log.warning("Control matrix scalars should contain one decimal " "place to avoid quantization effects.") if ch == 1: self._matrixscale_ch1_ch1 = scale_in1 self._matrixscale_ch1_ch2 = scale_in2 else: self._matrixscale_ch2_ch1 = scale_in1 self._matrixscale_ch2_ch2 = scale_in2