def channel_info(self, c, channel): """channel(int channel) Get information on one of the scope channels. OUTPUT Tuple of (probeAtten, termination, scale, position, coupling, bwLimit, invert, units) NOTES The scope's response to 'CH<x>?' is a string of format '1.0E1;1.0E1;2.5E1;0.0E0;DC;OFF;OFF;"V"' These strings represent respectively, probeAttenuation;termination;vertScale;vertPosition;coupling;bandwidthLimit;invert;vertUnit """ dev = self.selectedDevice(c) resp = yield dev.query('CH%d?' % channel) bwLimit, coupling, deskew, offset, invert, position, scale, termination, probeCal, probeAtten, resistance, unit, textID, textSN, extAtten, extUnits, textLabel, xPos, yPos = resp.split( ';') #Convert strings to numerical data when appropriate probeAtten = Value(float(probeAtten), '') termination = Value(float(termination), '') scale = Value(float(scale), '') position = Value(float(position), '') coupling = coupling bwLimit = Value(float(bwLimit), '') invert = invert unit = unit[1:-1] #Get's rid of an extra set of quotation marks returnValue((probeAtten, termination, scale, position, coupling, bwLimit, invert, unit))
def psSetCurrent(self, newCurrent): if newCurrent is not None: if not isinstance(newCurrent, Value): newCurrent = Value(float(newCurrent), 'A') self.psCurrent = newCurrent.inUnitsOf('A') self.psCurrent = max(-CURRENT_LIMIT, min(CURRENT_LIMIT, self.psCurrent)) return self.psCurrent
def current(self, current=None): ''' change the current setpoint. ''' if current is None: return self.setCurrent if not isinstance(current, Value): current = Value(float(current), 'A') self.setCurrent = current.inUnitsOf('A') self.setCurrent = max(-CURRENT_LIMIT, min(CURRENT_LIMIT, self.setCurrent)) return self.setCurrent
def freq_and_settle(self, c, sp, fs, minSettle=Value(0.0, 's')): dev = self.selectedDevice(c) yield dev.write('*CLS\n') sp = yield self.span(c, sp) fs = yield self.start_frequency(c, fs) yield dev.waitForSettling(minSettle) returnValue((sp, fs))
def testUnitTypes(self): """Test flattening with units. The flattening code should not do unit conversion, but should leave that up to the LabRAD manager to handle. Basically, for purposes of flattening, a unit is a unit. """ tests = [ (Value(5.0, 'ft'), ['v[m]'], 'v[ft]'), # real value array (U.ValueArray([1, 2, 3], ''), [], '*v[]'), (U.ValueArray([1, 2, 3], 'm'), ['*v[m]'], '*v[m]'), # complex value array (U.ValueArray([1j, 2j, 3j], ''), [], '*c[]'), (U.ValueArray([1j, 2j, 3j], 'm'), [], '*c[m]') ] for data, hints, tag in tests: self.assertEqual(T.flatten(data, hints)[1], T.parseTypeTag(tag)) # we disallow flattening a float to a value with units, # as this is a major source of bugs try: T.flatten(5.0, 'v[m]') except Exception: pass else: raise Exception('Cannot flatten float to value with units')
def lookupDeviceName(self, server, channel): """Try to send a *IDN? or an alternative query to lookup info about a device. Returns the name of the device and the actual response string to the identification query. If the response cannot be parsed or the query fails, the name will be listed as '<unknown>'. """ for cls_cmd, idn_cmd in [('*CLS', '*IDN?'), ('', 'ID?'), ('CS', 'OI')]: resp = None name = UNKNOWN p = self.client.servers[server].packet() p.address(channel).timeout(Value(1, 's')) p.write(cls_cmd).query(idn_cmd) srv_ch = ''.join([str(server), " ", str(channel)]) print("Sending '%s' to %s" % (idn_cmd, srv_ch)) try: resp = (yield p.send()).query except LRError as e: if 'VisaIOError' in e.msg: resp = '' print("No response to '%s' from %s" % (idn_cmd, srv_ch)) continue except Exception: print("No response to '%s' from %s" % (idn_cmd, srv_ch)) continue # Workaround for old-style devices. if idn_cmd in ('*IDN?', 'ID?') and resp.find(',') == -1: continue name = parseIDNResponse(resp, idn_cmd) if name != UNKNOWN: print("%s '%s' response: '%s'" % (srv_ch, idn_cmd, resp)) print("%s device name: '%s'" % (srv_ch, name)) break returnValue((name, resp))
def testValueArray(self): # Slicing self.assertTrue( (ValueArray([1, 2, 3], 'm')[0:2] == ValueArray([1, 2], 'm')).all()) # Cast to unit self.assertTrue((ValueArray([1.2, 4, 5], 'm')['m'] == np.array([1.2, 4, 5])).all()) # Addition and subtraction of compatible units self.assertTrue( (ValueArray([3, 4], 'm') + ValueArray([100, 200], 'cm') == ValueArray([4, 6], 'm')).all()) self.assertTrue( (ValueArray([2, 3, 4], 'm') - ValueArray([100, 200, 300], 'cm') == ValueArray([1, 1, 1], 'm')).all()) # Division with units remaining self.assertTrue( (ValueArray([3, 4, 5], 'm') / ValueArray([1, 2, 5], 's') == ValueArray([3, 2, 1], 'm/s')).all()) # Division with no units remaining self.assertTrue((ValueArray([3, 4, 5], 'm') / ValueArray([1, 2, 5], 'm') == ValueArray([3, 2, 1], '')).all()) # Powers self.assertTrue( (ValueArray([2, 3], 'm')**2 == ValueArray([4, 9], 'm^2')).all()) self.assertTrue((ValueArray([2, 3], 'GHz') * Value(3, 'ns')).dtype == np.float64) # isfinite self.assertTrue(np.isfinite(ValueArray([1, 2], 'GHz')).all()) self.assertTrue( (np.isfinite(ValueArray([1, float('nan')], 'GHz')) == np.array([True, False])).all())
def bandwidth(self, c, channel, bw=None): """Get or set the bandwidth of a specified channel Bandwidths can be specified as strings. Allowed strings are \n 'TWE' : 20MHz \n 'ONE' : 150MHz \n 'FIV' : 500MHz (*This one doesn't work so I removed it from the allowed list*) \n 'FUL': Remove bandwidth limit \n RETURNS \n Value - bandwidth of this channel COMMENTS \n When setting a bandwidth, no checking is done to ensure that the requested value is actually selected in the device, although the current value is queried and returned """ if (bw is not None) and (bw not in BANDWIDTHS): raise Exception('Bandwidth must be one of the following: %s' % BANDWIDTHS) dev = self.selectedDevice(c) resp = yield dev.channelBandwidth(channel, bw) bw = Value(float(resp), 'Hz') returnValue(bw)
def runSweeper(devices, para_list): freq, bias, zpa, power, mw_power, delay, phase = para_list q['bias'] = Value(bias, 'V') q['readout_amp'] = power * dBm q.power_r = power2amp(power) q['readout_mw_fc'] = (freq - q['demod_freq']) * Hz start = 0 q.z = waveforms.square(amp=zpa) q.xy = [waveforms.square(amp=0), waveforms.square(amp=0)] start += delay start += 100e-9 start += q['qa_start_delay']['s'] for _qb in qubits: _qb['experiment_length'] = start q['do_readout'] = True q.r = readoutPulse(q) set_qubitsDC(qubits, q['experiment_length']) data = runQ([q], devices) _d_ = data[0] amp = np.abs(np.mean(_d_)) / q.power_r phase = np.angle(np.mean(_d_)) Iv = np.real(np.mean(_d_)) Qv = np.imag(np.mean(_d_)) return [amp, phase, Iv, Qv]
def runSweeper(devices, para_list): zpa, df, piamp21, piLen21 = para_list q['piAmp21'] = piamp21 q['piLen21'] = Value(piLen21, 's') q['f21'] = q_copy['f21'] + Value(df, 'Hz') start = 0. q.z = waveforms.square(amp=zpa, start=start, length=q.piLen['s'] + q.piLen21['s']) q['xy'] = XYnothing(q) addXYgate(q, start, theta=np.pi, phi=0.) start += q['piLen']['s'] start += 50e-9 addXYgate(q, start, theta=np.pi, phi=0., piAmp='piAmp21', fq='f21', piLen='piLen21') start += q['piLen21']['s'] start += 100e-9 start += q['qa_start_delay']['s'] q['experiment_length'] = start q['do_readout'] = True set_qubitsDC(qubits, q['experiment_length']) q.r = readoutPulse(q) data = runQ([q], devices) _d_ = data[0] amp = np.abs(np.mean(_d_)) / q.power_r phase = np.angle(np.mean(_d_)) Iv = np.mean(np.real(_d_)) Qv = np.mean(np.imag(_d_)) prob = tunneling([q], [_d_], level=3) # multiply channel should unfold to a list for return result result = [amp, phase, Iv, Qv, prob[0], prob[1], prob[2]] clear_waveforms(qubits) return result
def run_fpga_sequence(self, waveform_jtargs_counters, stats=30, adc_mon0=None, adc_mon1=None): """Run full FPGA sequence using the GHz FPGA server. Args: waveform_jtargs_counters: stats (int): Number of repetitions of the sequence. adc_mon0 (int): Setting for monitor 0 of the ADC adc_mon1 (int): Setting for monitor 1 of the ADC Returns: fpga.run_sequence """ def name_board(dac_num, type='DAC'): return '{} {} {}'.format(self.board_group_name, type, dac_num) master_name = name_board(self.dac_num) slave_names = [name_board(dac_num) for dac_num in self.other_dac_nums] waveform, jump_args, counters = waveform_jtargs_counters sram = np.array(dac.dacify(waveform, waveform, trigger_idx=[16, 17]), dtype='<u4') for board in [master_name] + slave_names: self.fpga.select_device(board) self.fpga.jump_table_clear() for jump_arg in jump_args: opcode, arg = jump_arg self.fpga.jump_table_add_entry(opcode, arg) self.fpga.jump_table_set_counters(counters) self.fpga.sram(sram) self.fpga.start_delay(12) self.fpga.loop_delay(Value(50, 'us')) daisy = [master_name] if self.adc_num is not None: adc_name = name_board(self.adc_num, type='ADC') self.fpga.select_device(adc_name) self.fpga.adc_run_mode('demodulate') # Hard code begins here self.fpga.start_delay(4) self.fpga.adc_trigger_table([(1, 7, 40, 11)]) mixer = 127 * np.ones([512, 2]) mixer[:, 1] *= 0 self.fpga.adc_mixer_table(0, mixer) if adc_mon0 is not None: self.fpga.adc_monitor_outputs(adc_mon0, adc_mon1) self.fpga.timing_order([adc_name + '::0']) daisy.append(adc_name) else: self.fpga.timing_order([]) for ob in slave_names: daisy.append(ob) self.fpga.daisy_chain(daisy) return self.fpga.run_sequence(stats, False)
def testTypeSpecialization(self): """Test specialization of the type during flattening.""" tests = [ # specialization without hints ([([], ), ([5.0], )], '*(*v)'), ([([], ), ([Value(5, 'm')], )], '*(*v[m])'), ] for data, tag in tests: self.assertEqual(T.flatten(data)[1], T.parseTypeTag(tag))
def time_interval(self, c, ti=None): """ Get/set the logging time interval. """ dev = self.selectedDevice(c) if ti is not None: dev.timeInterval = ti['s'] if dev.isLogging: yield dev.logging(False) yield dev.logging(True) returnValue(Value(dev.timeInterval, 's'))
def span(self, c, sp=None): """Get or set the current frequency span. The span is specified by an integer from 0 to 19 or by a labrad Value with frequency units. The allowed integers are: (i, span) (0, 191mHz) (1, 382mHz) (2, 763mHz) (3, 1.5Hz) (4, 3.1Hz) (5, 6.1Hz) (6, 12.2Hz) (7, 24.4Hz) (8, 48.75Hz) (9, 97.5Hz) (10, 195Hz) (11, 390Hz) (12, 780Hz) (13, 1.56KHz) (14, 3.125KHz) (15, 6.25KHz) (16, 12.5KHz) (17, 25KHz) (18, 50KHz) (19, 100KHz) Note that while the input spans can be integers or frequency values, you will always get a frequency value passed back. This is done because I don't expect users to know the conversion between integers and frequency values. """ dev = self.selectedDevice(c) #If the user gave a span, write it to the device if sp is not None: #If span is an integer, check that it's in the allowed range, and get the appropriate value in Hz if isinstance(sp, int): if not (sp > -1 and sp < 20): raise Exception('span must be in [0,19]') #Else if span is a value, check that it's a frequency, and in the allowed range. elif isinstance(sp, Value): if not sp.isCompatible('Hz'): raise Exception( 'Spans specified as Values must be in frequency units') if not sp['Hz'] <= 100000 and sp['Hz'] > 0.191: raise Exception('Frequency span out of range') sp = indexOfClosest(SPANS.values(), sp['Hz']) else: raise Exception( 'Unrecognized span. Span must be an integer or a Value with frequency units' ) yield dev.write('SPAN%d\n' % sp) #Readback span. This comes as an integer code, which we convert to a Value resp = yield dev.query('SPAN?\n') sp = Value(float(SPANS[int(resp)]), 'Hz') returnValue(sp)
def waitForSettling(self, minSettle=Value(0.0,'s')): t = time.time() while 1: done = yield self.doneSettling() if done: yield util.wakeupCall(max(0.0, minSettle['s'] - (time.time() - t))) returnValue(None) #Return None because returnValue needs an argument else: print 'Device waiting for settling. Will check again in %d seconds' %self.SETTLING_TIME['s'] yield util.wakeupCall(self.SETTLING_TIME['s'])
def testDefaultFlatAndBackNonIdentical(self): """ Test flattening/unflattening of objects which change type. No type requirements are given in these tests. In other words, we allow pylabrad to choose a default type for flattening. In this test, we do not expect A == unflatten(*flatten(A)). This is mostly because list of numbers, both with an without units, should unflatten to ndarray or ValueArray, rather than actual python lists. """ def compareValueArrays(a, b): """I check near equality of two ValueArrays""" self.assertTrue(a.allclose(b)) tests = [ ([1, 2, 3], np.array([1, 2, 3], dtype='int32'), np.testing.assert_array_equal), ([1.1, 2.2, 3.3], np.array([1.1, 2.2, 3.3], dtype='float64'), np.testing.assert_array_almost_equal), (np.array([3, 4], dtype='int32'), np.array([3, 4], dtype='int32'), np.testing.assert_array_equal), (np.array([1.2, 3.4]), np.array([1.2, 3.4]), np.testing.assert_array_almost_equal), ([Value(1.0, 'm'), Value(3.0, 'm')], ValueArray([1.0, 3.0], 'm'), compareValueArrays), ([Value(1.0, 'm'), Value(10, 'cm')], ValueArray([1.0, 0.1], 'm'), compareValueArrays), (ValueArray([1, 2], 'Hz'), ValueArray([1, 2], 'Hz'), compareValueArrays), (ValueArray([1.0, 2], ''), np.array([1.0, 2]), np.testing.assert_array_almost_equal), # Numpy scalar types (np.bool8(True), True, self.assertEqual) ] for input, expected, comparison_func in tests: unflat = T.unflatten(*T.flatten(input)) if isinstance(unflat, np.ndarray): self.assertEqual(unflat.dtype, expected.dtype) comparison_func(unflat, expected)
def _tune_freq(sample, dh, Qubit, idx=0, idx_pro=5, plot=True, update=True, _key='f10'): """ Note: xdata is in MHz, e.g., ar[-40:40:2,MHz] """ data = dh.getDataset(idx, None) xdata = data[:, 0] ydata = data[:, idx_pro] n_data = len(xdata) mean0 = 0. sigma0 = sum(ydata * (xdata - mean0)**2) / n_data def gauss(x, a, x0, sigma): return a * np.exp(-(x - x0)**2 / (2 * sigma**2)) freq0 = Qubit[_key] popt, pcov = curve_fit(gauss, xdata, ydata, p0=[1, mean0, sigma0]) freq_shift = np.round(popt[1], 2) freq_new = freq0 + Value(freq_shift, 'MHz') freq_new = Value(freq_new['GHz'], 'GHz') if plot: fig = plt.figure() ax = fig.add_subplot(1, 1, 1) plt.plot(xdata, ydata, 'ko:', label='data') plt.plot(xdata, gauss(xdata, *popt), 'r-', linewidth=2) plt.plot(freq_shift + xdata * 0, ydata, 'b', linewidth=5) plt.grid() title = Qubit._dir[-1] + f': {_key}->{freq_new}' plt.title(title) plt.show() if update: Qubit[_key] = freq_new return
def testFailedFlattening(self): """ Trying to flatten data to an incompatible type should raise an error. """ cases = [ # Simple cases (1, ['s', 'v[Hz]']), ('X', ['i', 'v', 'w']), (5.0, ['s', 'b', 't', 'w', 'i', 'v[Hz]']), # Value (5.0, 'v[Hz]'), (Value(4, 'm'), 'v[]'), (Value(3, 's'), ['v[Hz]', 'i', 'w']), # ndarray (np.array([1, 2, 3], dtype='int32'), '*v[Hz]'), (np.array([1.0, 2.4]), ['*i', '*w']), # ValueArray (U.ValueArray([1, 2, 3], 'm'), '*v[s]'), (U.ValueArray([1, 2], 'm'), '*v[]') ] for data, targetTag in cases: self.assertRaises(T.FlatteningError, T.flatten, data, targetTag)
def start_frequency(self, c, fs=None): """Get or set the start frequency. Must be between 0 and 100kHz""" dev = self.selectedDevice(c) if fs is not None: if isinstance(fs, Value) and fs.isCompatible('Hz'): fs = fs['Hz'] else: raise Exception('Start frequency must be a frequency Value') #Write to the device yield dev.write('STRF%f\n' % float(fs)) #Readback the start frequency resp = yield dev.query('STRF?\n') fs = Value(float(resp), 'Hz') returnValue(fs)
def center_frequency(self, c, cf=None): """Get or set the center frequency.""" dev = self.selectedDevice(c) #If the user specified a center frequency if cf is not None: #Make sure it's a frequency unit if isinstance(cf, Value) and cf.isCompatible('Hz'): cf = cf['Hz'] #Otherwise, error else: raise Exception('Center frequency must be a frequency value') #Send that frequency to the device yield dev.write('CTRF, %f\n' % cf) #Readback current center frequency resp = yield dev.query('CTRF?\n') cf = Value(float(resp), 'Hz') returnValue(cf)
def write_parameters(self): if not len(self.parameters): return if not self.dataset_open: raise ValueError( "Cannot write parameters to a dataset that hasn't been opened." ) if self.ctx_expired: raise ValueError("Tried to use data vault with expired context") done = False while not done: if len(self.parameters) == 0: done = True continue param = self.parameters.pop() self.dv.add_parameter(param[0], Value(param[2], param[1]), context=self.ctx)
def test_basic_run(self): sram_data = np.array(np.linspace(0, 0x3FFF, 256), dtype='<u4') matching_jt = jump_table.JumpTable( start_addr=0, # from_addr offset of -3 for END for this version of the JT jumps=[ jump_table.JumpEntry(256 // 4 + _JUMP_TABLE_END_ADDR_OFFSET, 0, jump_table.END()) ], counters=[0, 0, 0, 0]) matching_packet = np.fromstring(matching_jt.toString(), dtype='u1') s, c = self.server, self.ctx # do this board s.jump_table_clear(c) s.jump_table_add_entry(c, 'END', 256) s.dac_sram(c, sram_data) s.loop_delay(c, Value(50, 'us')) s.start_delay(c, 12) # global settings s.sequence_boards( c, [self.dev.name]) # actually the 'daisy_chain' setting s.sequence_timing_order(c, []) # actually 'timing_order' self._fake_run_sequence() # check the run packet run_pkt = self.run_packets[0] assert run_pkt[0] == 1 # master mode assert run_pkt[1] == 0 # no readback assert run_pkt[13] == self.global_reps & 0xFF # reps low byte assert run_pkt[14] == self.global_reps >> 8 # reps high byte assert run_pkt[15] == 50 # loop delay assert run_pkt[16] == 0 delay = 12 + self.global_board_delay + dac.MASTER_SRAM_DELAY_US assert run_pkt[43] == delay & 0xFF # delay assert run_pkt[44] == delay >> 8 # check the SRAM and JT packets load_writes = self.load_writes[0] assert len(load_writes) == 2 assert np.array_equal(load_writes[0], matching_packet) assert load_writes[1][0] == load_writes[1][1] == 0 assert np.array_equal(load_writes[1][2:], np.fromstring(sram_data.tostring(), dtype='u1'))
def _sendRegisters(self, regs, readback=True, timeout=Value(10, 's')): """ Send a register packet and optionally readback the result. If readback is True, the result packet is returned as a string (of bytes). """ if not isinstance(regs, np.ndarray): regs = np.asarray(regs, dtype='<u1') p = self.makePacket() p.write(regs.tostring()) if readback: p.timeout(timeout) p.read(1) ans = yield p.send() if readback: src, dst, eth, data = ans.read[0] returnValue(data)
def lookupDeviceName(self, server, channel): """Try to send a *IDN? query to lookup info about a device. Returns the name of the device and the actual response string to the identification query. If the response cannot be parsed or the query fails, the name will be listed as '<unknown>'. """ p = self.client.servers[server].packet() p.address(channel).timeout(Value( 1, 's')).write('*CLS').write('*IDN?').read() print 'Sending *IDN? to', server, channel resp = None try: resp = (yield p.send()).read name = parseIDNResponse(resp) except Exception, e: print 'Error sending *IDN? to', server, channel + ':', e name = UNKNOWN
def collect(self, nPackets, timeout, triggerCtx=None): """ Create a direct ethernet server request to collect data on the FPGA. Note that if the collect times out, the triggers are NOT sent. """ p = self.makePacket() # print('fpga.py: collect: timeout = %s, waiting for nPackets: %s'%(timeout,nPackets)) p.timeout(Value(timeout, 's')) p.collect(nPackets) # If a timeout error occurs the remaining records in the direct # ethernet server packet are not executed. In the present case this # means that if the timeout fails the trigger command will not be # sent. This really really REALLY bad programming but I don't want to # learn Delphi to fix the direct ethernet server. Just be happy that I # put this note here so you know what's going on. if triggerCtx is not None: p.send_trigger(triggerCtx) return p
def test_multiple_boards(self): loop_delay = Value(250, 'us') start_delays = [(NUM_DACS - i) * 10 for i in range(NUM_DACS)] sram_data_1 = np.array(np.linspace(0, 0x3FFF, 512), dtype='<u4') sram_data_2 = np.array(np.ones_like(sram_data_1), dtype='<u4') matching_jt = jump_table.JumpTable( start_addr=0, jumps=[ jump_table.JumpEntry( 256 // 4 + _JUMP_TABLE_FROM_ADDR_OFFSET, 0, jump_table.IDLE(1000 // 4 + _JUMP_TABLE_IDLE_OFFSET)), jump_table.JumpEntry(512 // 4 + _JUMP_TABLE_END_ADDR_OFFSET, 0, jump_table.END()) ], counters=[0, 0, 0, 0]) matching_jt_packet = np.fromstring(matching_jt.toString(), dtype='u1') # set up the DACs s, c = self.server, self.ctx daisy_chain = [] for i in range(1, NUM_DACS + 1): s.select_device(c, i) s.jump_table_clear(c) s.jump_table_add_entry(c, 'IDLE', [256, 1000]) s.jump_table_add_entry(c, 'END', 512) if i == 1: s.dac_sram(c, sram_data_1) else: s.dac_sram(c, sram_data_2) s.loop_delay(c, loop_delay) s.start_delay(c, start_delays[i - 1]) daisy_chain.append('Test DAC {}'.format(i)) # global settings s.sequence_boards(c, daisy_chain) # actually the 'daisy_chain' setting s.sequence_timing_order(c, []) # actually 'timing_order' self._fake_run_sequence() for i in range(NUM_DACS): # check register packets p = self.run_packets[i] # first board is master if i == 0: assert p[0] == 1 else: assert p[0] == 3 packet_delay = p[43] + (p[44] >> 8) expected_delay = start_delays[i] + self.global_board_delay if i == 0: expected_delay += dac.MASTER_SRAM_DELAY_US assert packet_delay == expected_delay load_writes = self.load_writes[i] # check SRAM packets assert len(load_writes) == 3 if i == 0: assert load_writes[1][2:].tostring( ) == sram_data_1[:256].tostring() assert load_writes[2][2:].tostring( ) == sram_data_1[256:].tostring() else: assert load_writes[1][2:].tostring( ) == sram_data_2[:256].tostring() assert load_writes[2][2:].tostring( ) == sram_data_2[256:].tostring() # check JT assert np.array_equal(matching_jt_packet, load_writes[0])
def testValueArrayConstruction(self): v1 = ValueArray([Value(1, 'MHz'), Value(1, 'GHz')]) v2 = ValueArray([1, 1000], 'MHz') self.assertTrue((v1 == v2).all())
def testBaseUnitPowers(self): x = Value(1, 'ns^2') self.assertTrue(x.unit.base_unit == units.Unit('s^2')) self.assertTrue(x.inBaseUnits() == Value(1e-18, 's^2'))
def __init__(self, I_c): assert Value(1.0, 'A').isCompatible(I_c) self._I_c = I_c
def __init__(self, L): assert Value(1.0, 'H').isCompatible(L) self._L = L