class SweepBaseProcedure(MKIDProcedure): """Procedure class to subclass when making a custom MKID sweep procedure.""" # mandatory parameters directory = DirectoryParameter("Data Directory") attenuation = FloatParameter("DAC Attenuation", units="dB") field = FloatParameter("Auxiliary Field", units="V") temperature = FloatParameter("Temperature", units="mK")
class IVProcedure(Procedure): max_current = FloatParameter('Maximum Current', units='mA', default=10) min_current = FloatParameter('Minimum Current', units='mA', default=-10) current_step = FloatParameter('Current Step', units='mA', default=0.1) delay = FloatParameter('Delay Time', units='ms', default=20) voltage_range = FloatParameter('Voltage Range', units='V', default=10) DATA_COLUMNS = ['Current (A)', 'Voltage (V)', 'Resistance (Ohm)'] def startup(self): log.info("Setting up instruments") self.meter = Keithley2000("GPIB::25") self.meter.measure_voltage() self.meter.voltage_range = self.voltage_range self.meter.voltage_nplc = 1 # Integration constant to Medium self.source = Keithley2400("GPIB::1") self.source.apply_current() self.source.source_current_range = self.max_current * 1e-3 # A self.source.compliance_voltage = self.voltage_range self.source.enable_source() sleep(2) def execute(self): currents_up = np.arange(self.min_current, self.max_current, self.current_step) currents_down = np.arange(self.max_current, self.min_current, -self.current_step) currents = np.concatenate((currents_up, currents_down)) # Include the reverse currents *= 1e-3 # to mA from A steps = len(currents) log.info("Starting to sweep through current") for i, current in enumerate(currents): log.debug("Measuring current: %g mA" % current) self.source.source_current = current # Or use self.source.ramp_to_current(current, delay=0.1) sleep(self.delay * 1e-3) voltage = self.meter.voltage if abs(current) <= 1e-10: resistance = np.nan else: resistance = voltage / current data = { 'Current (A)': current, 'Voltage (V)': voltage, 'Resistance (Ohm)': resistance } self.emit('results', data) self.emit('progress', 100. * i / steps) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): self.source.shutdown() log.info("Finished")
class IVProcedure(Procedure): max_current = FloatParameter('Maximum Current', units='mA', default=10) min_current = FloatParameter('Minimum Current', units='mA', default=-10) current_step = FloatParameter('Current Step', units='mA', default=0.1) delay = FloatParameter('Delay Time', units='ms', default=20) voltage_range = FloatParameter('Voltage Range', units='V', default=10) DATA_COLUMNS = ['Current (A)', 'Voltage (V)', 'Resistance (Ohm)'] def startup(self): log.info("Setting up instruments") self.meter = K2000("GPIB::25") # Number of power line cycles (NPLC) # Medium = 1 NPLC, 20 ms self.meter.config_measure_voltage(self.voltage_range, nplc=1) self.source = Yokogawa7651("GPIB::4") self.source.config_current_source(self.max_current * 1e-3) sleep(1) def execute(self): currents_up = np.arange(self.min_current, self.max_current, self.current_step) currents_down = np.arange(self.max_current, self.min_current, -self.current_step) currents = np.concatenate( (currents_up, currents_down)) # Include the reverse currents *= 1e-3 # to mA from A steps = len(currents) log.info("Starting to sweep through current") for i, current in enumerate(currents): log.debug("Measuring current: %g mA" % current) self.source.current = current sleep(self.delay * 1e-3) voltage = self.meter.voltage if abs(current) <= 1e-10: resistance = np.nan else: resistance = voltage / current data = { 'Current (A)': current, 'Voltage (V)': voltage, 'Resistance (Ohm)': resistance } self.emit('results', data) self.emit('progress', 100. * i / steps) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): self.source.current = 0 log.info("Finished")
class TestProcedure(Procedure): iterations = IntegerParameter('Loop Iterations', default=100) gate = FloatParameter('Gate Time', units='s', default=0.2) source_voltage = FloatParameter('Source Voltage', units='V', default=0.0) source_current = FloatParameter('Source Current', units='A', default=0.0) DATA_COLUMNS = [ 'Iteration', 'Frequency', 'Usour', 'Isour', 'Umeas', 'Uref' ] def startup(self): log.info("Setting up instruments") self.f_meter = Agilent5313xA( VXI11Adapter("10.23.68.217", name="gpib0,26")) self.f_meter.reset() self.usour_meter = HP34401A( VXI11Adapter("10.23.68.217", name="gpib0,22")) self.usour_meter.reset() self.uref_meter = HP34401A( VXI11Adapter("10.23.68.217", name="gpib0,15")) self.uref_meter.reset() self.source = HP66312A(VXI11Adapter("10.23.68.217", name="gpib0,4")) self.source.reset() # Setup instruments self.f_meter.measure_freq = 1 self.f_meter.arming_time(self.gate) self.source.sour_voltage = self.source_voltage self.source.sour_current = self.source_current self.source.output = True def execute(self): log.info("Starting to log data") for i in range(self.iterations): self.f_meter.measure_start() data = { 'Iteration': i, 'Frequency': self.f_meter.fetch_frequency, 'Usour': self.source.meas_voltage_dc, 'Isour': self.source.meas_current_dc, 'Umeas': self.usour_meter.voltage_dc, 'Uref': self.uref_meter.voltage_dc } log.debug("Produced numbers: %s" % data) self.emit('results', data) self.emit('progress', 100 * i / self.iterations) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): self.source.output = False log.info("Finished")
def _setup_ui(self): self.rows = [] for label in self.labels: self.rows.append([ inputs.FloatInput( FloatParameter("left", units="%", minimum=0, maximum=100)), inputs.FloatInput( FloatParameter("right", units="%", minimum=0, maximum=100)) ]) for row in self.rows: for input in row: input.setAlignment(QtCore.Qt.AlignRight)
def _setup_ui(self): self.take_noise = inputs.BooleanInput(BooleanParameter("Take Data")) self.take_noise.stateChanged.connect(self.noise_state) self.integration = inputs.ScientificInput( FloatParameter("Integration Time", units="s")) self.n_int = inputs.IntegerInput(IntegerParameter("# of Integrations")) if self._populate_off_resonance: self.off_resonance = inputs.BooleanInput( BooleanParameter("Take Off Resonance Data")) self.off_resonance.stateChanged.connect(self.off_resonance_state) self.offset = inputs.ScientificInput( FloatParameter("Frequency Offset", units="MHz")) self.n_off = inputs.IntegerInput(IntegerParameter("# of Points"))
class tempControlProcedure(Procedure): """ Procedure for calibrating the voltage to field strength relationship on Daedalus. Assumes that the center calibration has already ran. """ # control parameters calib_name = Parameter("Calibration Name", default='') temp_start = FloatParameter("Temperature start", units="C", default=-30.) temp_stop = FloatParameter("Temperature stop", units="C", default=100.) temp_step = FloatParameter("Temperature step", units="C", default=0.1) #heating_time = FloatParameter("Heating time", units="s", default=60.) #queued_time = Parameter("Queued Time") DATA_COLUMNS = ["set_temp","act_temp","elapsed_time"] def startup(self): log.info("Connecting and configuring the instruments") self.heatcontrol = ThorlabsTC200USB('/dev/ttyUSB0') self.heatcontrol.toggleenable() def execute(self): start_time = time() temp_points = np.arange(self.temp_start, self.temp_stop, self.temp_step) if self.temp_stop not in temp_points: temp_points = np.append(temp_points, self.temp_stop) temp_points = np.concatenate((temp_points, temp_points[::-1])) num_progress = temp_points.size for progress_iterator, t in enumerate(temp_points): log.info("Setting temperature %f C"%t) self.heatcontrol.set_temp = t sleep(1) self.emit('progress', int(100*progress_iterator/num_progress)) self.emit('results', { "set_temp": self.heatcontrol.get_temp(), "act_temp": self.heatcontrol.act_temp(), "elapsed_time": time()-start_time }) if self.should_stop(): log.warning("Caught stop flag in procedure.") break def shutdown(self): log.info("Done with scan. Shutting down instruments") self.heatcontrol.toggleenable()
class IVProcedure(Procedure): data_points = IntegerParameter('Data points', default=10) averages = IntegerParameter('Averages', default=5) initial_x = FloatParameter('Maximum Current', unit='A', default=0.01) min_current = FloatParameter('Minimum Current', unit='A', default=-0.01) DATA_COLUMNS = ['Current (A)', 'Voltage (V)', 'Voltage Std (V)'] def startup(self): log.info("Connecting and configuring the instrument") self.sourcemeter = Keithley2400("GPIB::4") self.sourcemeter.reset() self.sourcemeter.use_front_terminals() self.sourcemeter.measure_voltage() self.sourcemeter.config_current_source() sleep(0.1) # wait here to give the instrument time to react self.sourcemeter.set_buffer(averages) def execute(self): currents = np.arange(self.min_current, self.max_current, num=self.data_points) # Loop through each current point, measure and record the voltage for current in currents: log.info("Setting the current to %g A" % current) self.sourcemeter.current = current self.sourcemeter.reset_buffer() sleep(0.1) self.sourcemeter.start_buffer() log.info("Waiting for the buffer to fill with measurements") self.sourcemeter.wait_for_buffer() self.emit( 'results', { 'Current (A)': current, 'Voltage (V)': self.sourcemeter.means, 'Voltage Std (V)': self.sourcemeter.standard_devs }) sleep(0.01) if self.should_stop(): log.info("User aborted the procedure") break def shutdown(self): self.sourcemeter.shutdown() log.info("Finished measuring")
class TestProcedure(Procedure): iterations = IntegerParameter('Loop Iterations', default=100) delay = FloatParameter('Delay Time', units='s', default=0.2) seed = Parameter('Random Seed', default='12345') iteration = Measurable('Iteration', default=0) random_number = Measurable('Random Number', random.random) offset = Measurable('Random Number + 1', default=0) def startup(self): log.info("Setting up random number generator") random.seed(self.seed) def measure(self): data = self.get_datapoint() data['Random Number + 1'] = data['Random Number'] + 1 log.debug("Produced numbers: %s" % data) self.emit('results', data) self.emit('progress', 100. * self.iteration.value / self.iterations) def execute(self): log.info("Starting to generate numbers") for self.iteration.value in range(self.iterations): self.measure() sleep(self.delay) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): log.info("Finished")
class TestProcedure(Procedure): iterations = IntegerParameter('Loop Iterations', default=100) gate = FloatParameter('Gate Time', units='s', default=0.2) DATA_COLUMNS = ['Iteration', 'Frequency'] def startup(self): log.info("Setting up counter") self.meter = Agilent5313xA( VXI11Adapter("10.23.68.217", name="gpib0,26")) self.meter.reset() # Setup instrument self.meter.measure_freq = 1 self.meter.arming_time(self.gate) def execute(self): log.info("Starting to log data") for i in range(self.iterations): self.meter.measure_start() data = {'Iteration': i, 'Frequency': self.meter.fetch_frequency} log.debug("Produced numbers: %s" % data) self.emit('results', data) self.emit('progress', 100 * i / self.iterations) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): log.info("Finished")
class TestProcedure(Procedure): iterations = IntegerParameter('Loop Iterations', default=100) delay = FloatParameter('Delay Time', units='s', default=0.2) seed = Parameter('Random Seed', default='12345') DATA_COLUMNS = ['Iteration', 'Random Number'] def startup(self): log.info("Setting up random number generator") random.seed(self.seed) def execute(self): log.info("Starting to generate numbers") for i in range(self.iterations): data = {'Iteration': i, 'Random Number': random.random()} log.debug("Produced numbers: %s" % data) self.emit('results', data) self.emit('progress', 100 * i / self.iterations) sleep(self.delay) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): log.info("Finished")
class TestProcedure(Procedure): iterations = IntegerParameter('Loop Iterations', default=100) delay = FloatParameter('Delay Time', units='s', default=0.2) DATA_COLUMNS = ['Iteration', 'Voltage'] def startup(self): log.info("Setting up instrument") self.meter = HP34401A(VXI11Adapter("10.23.68.217", name="gpib0,22")) #self.meter.reset() def execute(self): log.info("Starting to log data") for i in range(self.iterations): data = {'Iteration': i, 'Voltage': self.meter.voltage_dc} log.debug("Produced numbers: %s" % data) self.emit('results', data) self.emit('progress', 100 * i / self.iterations) sleep(self.delay) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): log.info("Finished")
class Measuringproc(Procedure): iterations = IntegerParameter('Loop Iterations') delay = FloatParameter('Delay Time', units='s', default=0.2) # seed = Parameter('Random Seed', default='12345') # DATA_COLUMNS = ['Iteration', 'Random Number'] def startup(self): log.info("Setting the seed of the random number generator") # random.seed(self.seed) self.lockin1 = SR830('GPIB::9') def execute(self): # log.info("Starting the loop of %d iterations" % self.iterations) # while True: for _ in self.iterations: data = {'voltage 1': self.lockin1.x, 'voltage 2': self.lockin1.y} self.emit('results', data) log.debug("Emitting results: %s" % data) sleep(self.delay) if self.should_stop(): log.warning("Caught the stop flag in the procedure") break
class RandomProcedure(Procedure): iterations = IntegerParameter('Loop Iterations') delay = FloatParameter('Delay Time', units='s', default=0.2) seed = Parameter('Random Seed', default='12345') DATA_COLUMNS = ['Iteration', 'Random Number'] def startup(self): log.info("Setting the seed of the random number generator") random.seed(self.seed) def execute(self): log.info("Starting the loop of %d iterations" % self.iterations) for i in range(self.iterations): data = { 'Iteration': i, 'Random Number': random.random() } self.emit('results', data) log.debug("Emitting results: %s" % data) sleep(self.delay) if self.should_stop(): log.warning("Caught the stop flag in the procedure") break
class Retention(ProcedureWithInstruments): # retention here # paramet averages = IntegerParameter('Averages', default=50) set_voltage = FloatParameter('SET Voltage', units='V', default=1) read_voltage = FloatParameter('READ Voltage', units='V', default=1) set_duration = FloatParameter('Duration SET Pulse', units='ms', default=1) read_duration = FloatParameter('Duration READ Pulse', units='ms', default=1) read_delay = FloatParameter('WRITE-READ Delay', units='s', default=1) cycles = IntegerParameter('#Cycles', default=1) DATA_COLUMNS = ['Voltage (V)', 'Current (A)', 'Current Std (A)', 'Cycle'] def execute(self): log.info("Retention Procedure Running") def shutdown(self): self.sourcemeter.shutdown() log.info("Finished measuring")
class tempProcedure(Procedure): sample_name = Parameter("Sample Name", default='undefined') save_dir = Parameter("Save Directory", default=r"\junk") stop_temp = FloatParameter("Target Temperature", units="C", default=20) ramp_time = IntegerParameter("Ramp Time", units="min", default=1) hold_time = IntegerParameter("Hold Time", units="min", default=1) DATA_COLUMNS = ["global_time", "temperature", "heating_time"] def startup(self): log.info("Stop, Ramp, Hold: %.1f, %d, %d" % (self.stop_temp, self.ramp_time, self.hold_time)) log.info("Connecting temperature controller") self.tempcontrol = ThorlabsTC200USB('COM3') self.tempcontrol.set_temp(self.tempcontrol.act_temp()) if self.tempcontrol.get_stat(): self.tempcontrol.toggleenable() self.tempcontrol.set_mode('cycle') self.tempcontrol.set_cycle_num(1) self.tempcontrol.set_stop_temp(self.stop_temp) self.tempcontrol.set_ramp_time(self.ramp_time) self.tempcontrol.set_hold_time(self.hold_time) self.tempcontrol.toggleenable() self.duration = (self.ramp_time + self.hold_time) * 60. def execute(self): num_progress = np.floor(self.duration / 0.05) start_time = time() end_time = start_time + self.duration progress_iterator = 0 while time() < end_time: self.emit("progress", int(100 * progress_iterator / num_progress)) progress_iterator += 1 log.info("Recording results") self.emit( 'results', { "global_time": time(), "heating_time": time() - start_time, "temperature": self.tempcontrol.act_temp() }) if self.should_stop(): log.warning("Caught stop flag in procedure.") break sleep(0.05) def shutdown(self): log.info("Finished with scan. Shutting down instruments.") if self.tempcontrol.get_stat(): self.tempcontrol.toggleenable() self.tempcontrol.adapter.connection.close( ) #close serial port to avoid port already open error
class tempProcedure(Procedure): sample_name = Parameter("Sample Name", default='undefined') save_dir = Parameter("Save Directory", default=r"\junk") stop_temperature = FloatParameter("Set Temperature", units="C", default=20) ramp_time = IntegerParameter("Ramp Time", units="min", default=1) hold_time = IntegerParameter("Hold Time", units="min", default=1) DATA_COLUMNS = ["global_time", "temperature", "heating_time"] def startup(self): self.duration = (self.ramp_time + self.hold_time) * 60. log.info(self.duration) log.info("Connecting temperature controller") self.tempcontrol = ThorlabsTC200USB('/dev/ttyUSB0') if self.tempcontrol.get_stat(): self.tempcontrol.toggleenable() self.tempcontrol.set_mode('cycle') self.tempcontrol.set_cycle_num(1) self.tempcontrol.set_stop_temp(self.stop_temperature) self.tempcontrol.set_ramp_time(self.ramp_time) self.tempcontrol.set_hold_time(self.hold_time) self.tempcontrol.toggleenable() #log.info('Heater enabled, heating to:%.1f in %d minutes and holding for %d minutes' % (self.stop_temperature, self.ramp_time, self.hold_time)) def execute(self): num_progress = np.floor(self.duration / 0.05) start_time = time.time() end_time = start_time + self.duration progress_iterator = 0 while time.time() < end_time: #self._update_parameters() self.emit("progress", int(100 * progress_iterator / num_progress)) progress_iterator += 1 log.info("Recording results") self.emit( 'results', { "global_time": time.time(), "temperature": self.tempcontrol.act_temp(), "heating_time": time.time() - start_time }) if self.should_stop(): log.warning("Caught stop flag in procedure.") break sleep(0.05) def shutdown(self): log.info("Finished with scan. Shutting down instruments.") if self.tempcontrol.get_stat(): self.tempcontrol.toggleenable()
class RandomProcedure(Procedure): iterations = IntegerParameter('Loop Iterations', default=100) delay = FloatParameter('Delay Time', units='s', default=0.001) seed = Parameter('Random Seed', default='12345') DATA_COLUMNS = ['Iteration', 'Random Number'] def startup(self): random.seed(self.seed) def execute(self): for i in range(self.iterations): data = {'Iteration': i, 'Random Number': random.random()} self.emit('results', data) self.emit('progress', 100. * i / self.iterations) sleep(self.delay) if self.should_stop(): break
class TestImageProcedure(Procedure): # We will be using X and Y as coordinates for our images. We must have # parameters called X_start, X_end and X_step and similarly for Y. X and # Y can be replaced with other names, but the suffixes must remain. X_start = FloatParameter("X Start Position", units="m", default=0.) X_end = FloatParameter("X End Position", units="m", default=2.) X_step = FloatParameter("X Scan Step Size", units="m", default=0.1) Y_start = FloatParameter("Y Start Position", units="m", default=-1.) Y_end = FloatParameter("Y End Position", units="m", default=1.) Y_step = FloatParameter("Y Scan Step Size", units="m", default=0.1) delay = FloatParameter("Delay", units="s", default=0.01) # There must be two special data columns which correspond to the two things # which will act as coordinates for our image. If X and Y are changed # in the parameter names, their names must change in DATA_COLUMNS as well. DATA_COLUMNS = ["X", "Y", "pixel_data"] def startup(self): log.info("starting up...") def execute(self): xs = np.arange(self.X_start,self.X_end,self.X_step) ys = np.arange(self.Y_start,self.Y_end,self.Y_step) nprog = xs.size * ys.size progit = 0 for x in xs: for y in ys: self.emit('progress', int(100*progit/nprog)) progit += 1 self.emit("results",{ 'X': x, 'Y': y, 'pixel_data': np.random.rand(1)[0] }) sleep(self.delay) if self.should_stop(): break if self.should_stop(): break def shutdown(self): log.info('shutting down')
class SweepGUIProcedure2(Procedure): """Procedure class for holding the mandatory sweep input arguments""" TOOLTIPS = {} ordering = { "directory_inputs": "directory", "frequency_inputs": [["frequency1", "frequencies1"], ["span1", "spans1"], ["frequency2", "frequencies2"], ["span2", "spans2"]], "sweep_inputs": [["attenuation", "start_atten", "stop_atten", "n_atten"], ["field", "start_field", "stop_field", "n_field"], ["temperature", "start_temp", "stop_temp", "n_temp"]] } directory = DirectoryParameter("Data Directory") frequencies1 = TextEditParameter("F1 List [GHz]", default=[4.0, 5.0]) spans1 = TextEditParameter("Span1 List [MHz]", default=[2.0]) frequencies2 = TextEditParameter("F2 List [GHz]", default=[6.0]) spans2 = TextEditParameter("Span2 List [MHz]", default=[2.0]) start_atten = FloatParameter("Start", units="dB", default=70) stop_atten = FloatParameter("Stop", units="dB", default=70) n_atten = IntegerParameter("# of Points", default=1, minimum=1, maximum=1000) start_field = FloatParameter("Start", units="V", default=0) stop_field = FloatParameter("Stop", units="V", default=0) n_field = IntegerParameter("# of Points", default=1, minimum=1, maximum=1000) start_temp = FloatParameter("Start", units="mK", default=100) stop_temp = FloatParameter("Stop", units="mK", default=100) n_temp = IntegerParameter("# of Points", default=1, minimum=1, maximum=1000)
class SS9Procedure(Procedure): your_name = Parameter("Your Name", default='') field_strength = FloatParameter("Field Strength", units='T', default=0) delay = FloatParameter('Delay Time', units='s', default=20) T_max = IntegerParameter('Maximum Temp.', units='K', default=350) num_averages = IntegerParameter('Number of Averages', default=5) mm1_measurement = BooleanParameter('Voltage', default=True) mm1_range = FloatParameter('Range', units='SI', default=1) mm1_address = Parameter("MM1 Address", default='') mm2_measurement = BooleanParameter('Voltage', default=True) mm2_range = FloatParameter('Range', units='SI', default=1) mm2_address = Parameter("MM2 Address", default='') mm3_measurement = BooleanParameter('Voltage', default=True) mm3_range = FloatParameter('Range', units='SI', default=1) mm3_address = Parameter("MM3 Address", default='') mm4_measurement = BooleanParameter('Voltage', default=True) mm4_range = FloatParameter('Range', units='SI', default=1) mm4_address = Parameter("MM4 Adress", default='') DATA_COLUMNS = [ 'elapsed_time', 'T', 'T_err', 'MM1_reading', 'MM1_error', 'MM2_reading', 'MM2_error', 'MM3_reading', 'MM3_error', 'MM4_reading', 'MM4_error' ] def startup(self): log.info("Setting up Multimeters") self.mm1 = Keithley2000(self.mm1_address) self.mm2 = Keithley2000(self.mm2_address) self.mm3 = Keithley2000(self.mm3_address) self.mm4 = Keithley2000(self.mm4_address) if self.mm1_measurement: self.mm1.measure_voltage(self.mm1_range) else: self.mm1.measure_current(self.mm1_range) if self.mm2_measurement: self.mm2.measure_voltage(self.mm2_range) else: self.mm2.measure_current(self.mm2_range) if self.mm3_measurement: self.mm3.measure_voltage(self.mm3_range) else: self.mm3.measure_current(self.mm3_range) if self.mm4_measurement: self.mm4.measure_voltage(self.mm4_range) else: self.mm4.measure_current(self.mm4_range) log.info("Setting up Thermocouple") self.mm2.voltage_nplc = 1 # Integration constant to Medium self.mm3.voltage_nplc = 1 # Integration constant to Medium self.mm4.voltage_nplc = 1 # Integration constant to Medium sleep(2) def execute(self): log.info("Starting Measurement") #prev_T = read_T T_min = ul.t_in(0, 0, TempScale.KELVIN) T = [T_min] start_time = time.time() while np.mean(T) < self.T_max: log.info("Temperature is at %d, waiting for it to reach %d" % \ (np.mean(T), self.T_max)) sleep(self.delay) elapsed_time = time.time() - start_time T, M1, M2, M3, M4 = [], [], [], [], [] for i in range(self.num_averages): log.info("Doing average %d of %d" % (i, self.num_averages)) if self.mm1_measurement: M1.append(self.mm1.voltage) else: M1.append(self.mm1.current) if self.mm2_measurement: M2.append(self.mm2.voltage) else: M2.append(self.mm2.current) if self.mm3_measurement: M3.append(self.mm3.voltage) else: M3.append(self.mm3.current) if self.mm4_measurement: M4.append(self.mm4.voltage) else: M4.append(self.mm4.current) T.append(ul.t_in(0, 0, TempScale.KELVIN)) sleep(self.delay / (self.num_averages + 1)) prog = int(100 * np.abs( (np.mean(T) - T_min) / (self.T_max - T_min))) self.emit("progress", prog) data = { 'elapsed_time': elapsed_time, 'T': np.mean(T), 'T_err': np.std(T), 'MM1_reading': np.mean(M1), 'MM1_error': np.std(M1), 'MM2_reading': np.mean(M2), 'MM2_error': np.std(M2), 'MM3_reading': np.mean(M3), 'MM3_error': np.std(M3), 'MM4_reading': np.mean(M4), 'MM4_error': np.std(M4) } self.emit('results', data) if self.should_stop(): log.warning("Catch stop command in procedure") break else: continue def shutdown(self): log.info("Finished") log.info("Please shut off heater, magnet and other instruments")
class FakeProcedure(Procedure): str_param = Parameter("String Parameter") bool_param = BooleanParameter("Boolean Parameter") float_param = FloatParameter("Float Parameter")
class TestProcedure(Procedure): iterations = IntegerParameter('Loop Iterations', default=100) delay = FloatParameter('Delay Time', units='s', default=0.2) seed = Parameter('Random Seed', default='12345') DATA_COLUMNS = ['Iteration', 'Random Number'] def startup(self): log.info("Setting up random number generator") random.seed(self.seed) def execute(self): log.info("Starting to generate numbers") for i in range(self.iterations): data = {'Iteration': i, 'Random Number': random.random()} log.debug("Produced numbers: %s" % data) self.emit('results', data) self.emit('progress', 100 * i / self.iterations) sleep(self.delay) if self.should_stop(): log.warning("Catch stop command in procedure") break def get_estimates(self, sequence_length=None, sequence=None): """ Function that returns estimates for the EstimatorWidget. If this function is implemented (and does not return a NotImplementedError) the widget is automatically activated. The function is expected to return an int or float, or a list of tuples. If an int or float is returned, it should represent the duration in seconds.If a list of tuples is returned, each tuple containing two strings, a label and the estimate itself: estimates = [ ("label 1", "estimate 1"), ("label 2", "estimate 2"), ] The length of the number of estimates is not limited but has to remain unchanged after initialisation. Note that also the label can be altered after initialisation. The keyword arguments `sequence_length` and `sequence` are optional and return (if asked for) the length of the current sequence (of the `SequencerWidget`) or the full sequence. """ duration = self.iterations * self.delay """ A simple implementation of the get_estimates function immediately returns the duration in seconds. """ # return duration estimates = list() estimates.append(("Duration", "%d s" % int(duration))) estimates.append(("Number of lines", "%d" % int(self.iterations))) estimates.append(("Sequence length", str(sequence_length))) estimates.append( ('Measurement finished at', str(datetime.now() + timedelta(seconds=duration))[:-7])) estimates.append( ('Sequence finished at', str(datetime.now() + timedelta(seconds=duration * sequence_length))[:-7])) return estimates def shutdown(self): log.info("Finished")
class IVSweepProcedure(Procedure): # Number of sweeps to perform test_num = IntegerParameter('Sweep Number', default=1) start = FloatParameter('Start Voltage', minimum=0, units='V', default=0.0) stop = FloatParameter('Stop Voltage', minimum=0, units='V', default=8.0) step = FloatParameter('Step Voltage', minimum=0.001, units='V', default=0.1) delay = FloatParameter('Trigger Delay', units='ms', default=10) polarity = ListParameter('Polarity', choices=['Anode', 'Cathode'], default='Anode') dev_num = IntegerParameter('DUT', minimum=1) pd_type = ListParameter('Type', choices=['APD', 'PIN'], default='APD') pd_size = ListParameter('Size', choices=['10um', '100um', '500um'], default='10um') DATA_COLUMNS = [ 'Reverse Voltage', 'Reverse Current', 'Timestamp', 'Status' ] def __init__(self): super().__init__() self.picoammeter = None def startup(self): """ Connect to source and configure voltage sweep :return: """ log.info("Connecting and configuring the instrument ...") adapter = VISAAdapter("GPIB0::22::INSTR", query_delay=0.1) self.picoammeter = Keithley6487(adapter) self.picoammeter.reset() self.picoammeter.configure_sweep(self.start, self.stop, self.step, self.delay, 1, self.polarity) log.info("Configuration complete.") def execute(self): """ Initiate an IV sweep on a Keithley 6487 Picoammeter :return: """ log.info("Initiating sweep") self.picoammeter.start_sweep() log.info("Sweep started") in_progress = 1 sleep(2) log.info("Waiting for sweep to complete") while in_progress: # Check status of sweep every 100msec in_progress = self.picoammeter.sweep_state() # print(in_progress) # in_progress = 0 if self.should_stop(): self.picoammeter.write('SOUR:VOLT:SWE:ABOR') break sleep(1) log.info("Sweep completed, retrieving data") trace_data_dark = self.picoammeter.ask(':TRAC:DATA?').replace('A', '') n_samples = int(self.picoammeter.buffer_size) trace_data_dark = np.fromstring(trace_data_dark, sep=',').reshape( (n_samples, 4)) [ self.emit( 'results', { 'Reverse Voltage': abs(trace_data_dark[i, 3]), 'Reverse Current': abs(trace_data_dark[i, 0]), 'Timestamp': trace_data_dark[i, 1], 'Status': trace_data_dark[i, 2] }) for i in range(n_samples) ] log.info("Data emitted")
class PhotoCurrentSweepProcedure(Procedure): # Number of sweeps to perform test_num = IntegerParameter('Sweep Number', default=1) start = FloatParameter('Start Voltage', minimum=0, units='V', default=0.0) stop = FloatParameter('Stop Voltage', minimum=0, units='V', default=8.0) step = FloatParameter('Step Voltage', minimum=0.001, units='V', default=0.1) delay = FloatParameter('Trigger Delay', units='ms', default=10) nplc = IntegerParameter('Integration Time', units='NPLC', maximum=10, minimum=0.1, default=1) polarity = ListParameter('Polarity', choices=['Anode', 'Cathode'], default='Anode') dev_num = IntegerParameter('DUT', minimum=1) pd_type = ListParameter('Type', choices=['APD', 'PIN'], default='APD') pd_size = ListParameter('Size', choices=['10um', '100um', '500um'], default='10um') source_current = FloatParameter('Optical Source Current', units='mA', maximum=1000) DATA_COLUMNS = [ 'Reverse Voltage Dark', 'Reverse Current Dark', 'Timestamp Dark', 'Status Dark', 'Reverse Voltage Light', 'Reverse Current Light', 'Timestamp Light', 'Status Light' ] def __init__(self): super().__init__() self.picoammeter = None self.power_supply = None def startup(self): """ Connect to source and configure voltage sweep :return: """ log.info("Connecting and configuring the picoammeter ...") adapter = VISAAdapter("GPIB0::22::INSTR", visa_library='@py', query_delay=0.1) self.picoammeter = Keithley6487(adapter) self.picoammeter.reset() self.picoammeter.configure_sweep(self.start, self.stop, self.step, self.delay, self.nplc, self.polarity) log.info("Picoammeter configuration complete.") log.info("Connecting to power supply and configuring") adapter = VISAAdapter("GPIB0::6::INSTR", visa_library='@py') self.power_supply = E364A(adapter) self.power_supply.reset() self.power_supply.apply(5, self.source_current / 1e3) self.power_supply.enabled = "OFF" def execute(self): """ Initiate an IV sweep on a Keithley 6487 Picoammeter :return: """ log.info("Initiating dark current sweep") self.picoammeter.start_sweep() log.info("Sweep started") in_progress = 1 sleep(2) log.info("Waiting for sweep to complete") while in_progress: # Check status of sweep every 100msec in_progress = self.picoammeter.sweep_state() if self.should_stop(): self.picoammeter.write('SOUR:VOLT:SWE:ABOR') break sleep(1) log.info("Dark current sweep completed, retrieving data") trace_data_dark = self.picoammeter.ask(':TRAC:DATA?').replace('A', '') n_samples = int(self.picoammeter.buffer_size) trace_data_dark = np.fromstring(trace_data_dark, sep=',').reshape( (n_samples, 4)) log.debug(trace_data_dark) # Enable light source and wait for it to warm up log.info("Enabling and triggering power supply") self.power_supply.enabled = "ON" self.power_supply.trigger() warm_up = 1 while warm_up: # Allow light source to warm up for 30sec, triggering every sec to update voltage sleep(1) self.power_supply.trigger() warm_up += 1 if warm_up > 30: warm_up = 0 # Perform photo current sweep log.info("Initiating dark current sweep") self.picoammeter.start_sweep() log.info("Sweep started") in_progress = 1 sleep(2) log.info("Waiting for sweep to complete") while in_progress: # Check status of sweep every 1sec in_progress = self.picoammeter.sweep_state() if self.should_stop(): self.picoammeter.write('SOUR:VOLT:SWE:ABOR') break sleep(1) log.info("Photo current sweep completed, retrieving data") trace_data_light = self.picoammeter.ask(':TRAC:DATA?').replace('A', '') n_samples = int(self.picoammeter.buffer_size) trace_data_light = np.fromstring(trace_data_light, sep=',').reshape( (n_samples, 4)) log.debug(trace_data_light) [ self.emit( 'results', { 'Reverse Voltage Dark': abs(trace_data_dark[i, 3]), 'Reverse Current Dark': abs(trace_data_dark[i, 0]), 'Timestamp Dark': trace_data_dark[i, 1], 'Status Dark': trace_data_dark[i, 2], 'Reverse Voltage Light': abs(trace_data_light[i, 3]), 'Reverse Current Light': abs(trace_data_light[i, 0]), 'Timestamp Light': trace_data_light[i, 1], 'Status Light': trace_data_light[i, 2] }) for i in range(n_samples) ] log.info("Current data emitted") log.info("Turning off light source") self.power_supply.enabled = "OFF" log.info("Waiting for 30sec in between test.") sleep(30)
class DepProcedure(Procedure): plate_current = FloatParameter('Plating Current', units='A', minimum=-1, maximum=1, default=0.000268055577) pulse = FloatParameter('Pulse length', units='s', maximum=1e8, default=0.1) delay = FloatParameter('Delay Time', units='s', maximum=1e8, default=5.9) repeats = IntegerParameter('Cycles', units=None, minimum=1, maximum=1e8, default=500) deltat = FloatParameter('Measurement Frequency', units='Hz', default=20) voltage_range = FloatParameter('Potential Range', units='V', default=10) directory = Parameter('Working Directory', default='C:/Data/') filename = Parameter('Filename', default=unique_filename(str(directory), prefix='Plate_')) DATA_COLUMNS = ['Current (A)', 'Potential (V)', 'Time (s)'] def startup(self): log.info("Setting up instruments") """ To use the Nanovoltmeter instead of the Sourcemeter to measure potential, uncomment the following section and change the corresponding section in execute routine to measure from meter instead of source """ # self.meter = Keithley2182("GPIB::7::INSTR") # self.meter.measure_voltage() # self.meter.voltage_range = self.voltage_range # self.meter.voltage_nplc = 1 # Integration constant to Medium self.source = Keithley2400("GPIB::24::INSTR") self.source.apply_current() self.source.measure_voltage() self.source.source_current_range = self.plate_current * 1.1 # Current range is 10% over target self.source.compliance_voltage = self.voltage_range self.source.enable_source() sleep(2) def execute(self): pulses = np.repeat(self.plate_current, (self.pulse) * 1 // (1 / self.deltat)) rest = np.repeat(0, (self.delay) * 1 // (1 / self.deltat)) currents = np.concatenate((pulses, rest)) currents = np.tile(currents, np.int(self.repeats)) # currents *= 1e-3 # to mA from A steps = len(currents) log.info("Starting Pulsed electrodeposition") for i, current in enumerate(currents): log.debug("Applying current: %g A" % current) self.source.source_current = current # Or use self.source.ramp_to_current(current, delay=0.1) sleep(1 / self.deltat) voltage = self.source.voltage time = i / self.deltat data = { 'Current (A)': current, 'Potential (V)': voltage, 'Time (s)': time } self.emit('results', data) self.emit('progress', 100. * i / steps) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): self.source.shutdown() self.source.beep(783.991, 0.1) sleep(0.125) self.source.beep(1046.50, 0.1) sleep(0.125) self.source.beep(1318.51, 0.1) sleep(0.125) self.source.beep(1567.98, 0.22) sleep(0.25) self.source.beep(1318.51, 0.1) sleep(0.125) self.source.beep(1567.98, 0.25) log.info("Finished")
class MagFieldProcedure(Procedure): #Magnetic Field calibration (input field, get current) pA = -6.78951587e-06 #Constant pB = 3.27549922e-03 #First order term def IfromB(self,B): if B < 0: return 0 elif B >= self.pA: return self.pA + (B)*self.pB + (B*B)*self.pC + (B*B*B)*self.pD #Calculating the current to produce a given H else: return 0.0 fileroot = Parameter('File Root',default='.') filename = Parameter('File Prepend',default='2ndHarm') field = FloatParameter('Applied Field', units='T', default=.1) lockinamp = FloatParameter('Lockin Amplitude', units='V', default = 1.0) lockinfreq = FloatParameter('Lockin Reference', units='Hz', default = 1337.7) start_angle = FloatParameter('Start Angle', units='degrees', default=0) stop_angle = FloatParameter('Stop Angle', units='degrees', default=270) angle_step = FloatParameter('Angle Step', units='degrees', default=1) delay = FloatParameter('Delay Time', units='ms', default=100) inverse_spacing = BooleanParameter('Inverse Spacing') field_start = FloatParameter('Start Field', units='T', default=.05) field_stop = FloatParameter('Stop Field', units='T', default=.3) field_steps = IntegerParameter('Field Steps', default=10) shutdown_after = BooleanParameter('Shutdown Field After?') DATA_COLUMNS = ['Angle (deg)','Current (A)', 'Magnetic Field (T)', '1X Voltage (V)', '1Y Voltage (V)', '2X Voltage (V)', '2Y Voltage (V)'] def inmotion(self,rotator): moving = -1 success = False while not success: try: moving=int(rotator.query('LOC?')) except pyvisa.VisaIOError: pass except ValueError: moving = 0 success = True else: success = True if moving > -1: moving = 0 else: moving = -1 sleep(0.1) return moving def homeangle(self, rotator): success = False while not success: try: rotator.write('HOME') except pyvisa.VisaIOError: pass else: success = True moving = -1 while moving ==-1: moving = self.inmotion(self.rotator) sleep(1) def setangle(self, rotator,angle): success = False while not success: try: rotator.write('GOTO %f' % angle) except pyvisa.VisaIOError: pass else: success = True def getangle(self, rotator): moving = -1 while moving == -1: moving = self.inmotion(rotator) sleep(0.1) success = False while not success: try: angle = float(rotator.query('LOC?')) except pyvisa.VisaIOError: pass except ValueError: pass else: success = True sleep(0.1) return angle def startup(self): log.info("Setting up instruments") self.source = Sorensen30035E(7) self.lockin1 = DSP7265(27) self.lockin2 = DSP7265(12) self.rm = pyvisa.ResourceManager() self.rotator = self.rm.open_resource('ASRL4::INSTR') sleep(2) self.rotator.clear() sleep(1) self.homeangle(self.rotator) def execute(self): #Defining the current values angles_up = np.arange(self.start_angle, self.stop_angle+self.angle_step, self.angle_step) steps_up = len(angles_up) ###Ramping up the magnet current to minimum current log.info("Ramping to field value.") self.current = self.IfromB(self.field) if self.current > 0 : self.source.ramp_to_current(self.current, self.current/1e-1) self.source.ramp_to_current(self.current) sleep(1) log.info('Setting Lockin Parameters') self.lockin1.voltage = self.lockinamp self.lockin1.frequency = self.lockinfreq log.info("Starting to sweep through angle.") for i, angle in enumerate(angles_up): log.debug("Setting angle: %g degrees" % angle) self.setangle(self.rotator,angle) true_angle = self.getangle(self.rotator) sleep(self.delay*1e-3) magfield = self.field lockinX1 = self.lockin1.x lockinY1 = self.lockin1.y lockinX2 = self.lockin2.x lockinY2 = self.lockin2.y data = { 'Angle (deg)' : true_angle, 'Current (A)': self.current, 'Magnetic Field (T)': magfield, '1X Voltage (V)': lockinX1, '1Y Voltage (V)': lockinY1, '2X Voltage (V)': lockinX1, '2Y Voltage (V)': lockinY1,, } self.emit('results', data) self.emit('progress', 100.*i/steps_up) if self.should_stop(): log.warning("Catch stop command in procedure") return def shutdown(self): log.info("Shutting down.") #Ramping down the magnetic field if self.shutdown_after: now = self.current self.source.ramp_to_current(0.0,now/1e-1) sleep(1) sleep(1) self.rotator.close() #Turning off the RF source #self.RFsource.power = -100 log.info("Finished")
class IVProcedure(Procedure): current = FloatParameter('Current', units='mA', default=10) delay = FloatParameter('Delay Time', units='ms', default=20) voltage_range = FloatParameter('Voltage Range', units='V', default=10) directory = Parameter('Working Directory', default='C:/Data/') filename = Parameter('Filename', default=unique_filename(str(directory), prefix='SourceI_')) DATA_COLUMNS = ['Current (A)', 'Voltage (V)', 'Resistance (Ohm)'] def startup(self): log.info("Setting up instruments") # self.meter = Keithley2182("GPIB::7::INSTR") # self.meter.measure_voltage() # self.meter.voltage_range = self.voltage_range # self.meter.voltage_nplc = 1 # Integration constant to Medium self.source = Keithley2400(instr) self.source.apply_current() self.source.source_current_range = self.max_current * 1e-3 # A self.source.measure_voltage() self.source.complinance_voltage = self.voltage_range self.source.enable_source() sleep(2) def execute(self): currents_up = np.arange(self.min_current, self.max_current, self.current_step) currents_down = np.arange(self.max_current, self.min_current, -self.current_step) currents = np.concatenate( (currents_up, currents_down)) # Include the reverse currents *= 1e-3 # to mA from A steps = len(currents) log.info("Starting to sweep through current") for i, current in enumerate(currents): log.debug("Measuring current: %g mA" % current) self.source.source_current = current # Or use self.source.ramp_to_current(current, delay=0.1) sleep(self.delay * 1e-3) voltage = self.source.voltage if abs(current) <= 1e-10: resistance = np.nan else: resistance = voltage / current data = { 'Current (A)': current, 'Voltage (V)': voltage, 'Resistance (Ohm)': resistance } self.emit('results', data) self.emit('progress', 100. * i / steps) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): self.source.shutdown() self.source.beep(783.991, 0.1) sleep(0.125) self.source.beep(1046.50, 0.1) sleep(0.125) self.source.beep(1318.51, 0.1) sleep(0.125) self.source.beep(1567.98, 0.22) sleep(0.25) self.source.beep(1318.51, 0.1) sleep(0.125) self.source.beep(1567.98, 0.25) log.info("Finished")
class DepProcedure(Procedure): plate_e = FloatParameter('Plating Potential', units='V', minimum=-5, maximum=5, default=-1.5) pulse = FloatParameter('Pulse length', units='s', default=0.1) delay = FloatParameter('Delay Time', units='s', default=5.9) repeats = IntegerParameter('Cycles', units=None, default=50) deltat = FloatParameter('Measurement Frequency', units='Hz', default=20) current_range = FloatParameter('Current Range', units='A', default=0.1) directory = Parameter('Working Directory', default='C:/Data/') filename = Parameter('Filename', default=unique_filename(str(directory), prefix='Plate_')) DATA_COLUMNS = ['Current (A)', 'Potential (V)', 'Time (s)'] def startup(self): # log.info("Setting up instruments") # self.meter = Keithley2182("GPIB::7::INSTR") # self.meter.measure_voltage() # self.meter.voltage_range = self.voltage_range # self.meter.voltage_nplc = 1 # Integration constant to Medium self.source = Keithley2400("GPIB::24::INSTR") self.source.apply_voltage() self.source.measure_current() self.source.voltage_nplc = 1 # Integration constant to Medium self.source.complinance_current = self.current_range self.source.enable_source() sleep(2) def execute(self): pulses = np.repeat(self.plate_e, (self.pulse) * 1 // (1 / self.deltat)) rest = np.repeat(0, (self.delay) * 1 // (1 / self.deltat)) potentials = np.concatenate((pulses, rest)) potentials = np.tile(potentials, np.int(self.repeats)) # currents *= 1e-3 # to mA from A steps = len(potentials) log.info("Starting Pulsed electrodeposition") for i, potential in enumerate(potentials): log.debug("Applying potential: %g V" % potential) self.source.source_voltage = potential # Or use self.source.ramp_to_current(current, delay=0.1) sleep(1 / self.deltat) current = self.source.current time = i / self.deltat data = { 'Current (A)': current, 'Potential (V)': potential, 'Time (s)': time } self.emit('results', data) self.emit('progress', 100. * i / steps) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): self.source.shutdown() self.source.beep(783.991, 0.1) sleep(0.125) self.source.beep(1046.50, 0.1) sleep(0.125) self.source.beep(1318.51, 0.1) sleep(0.125) self.source.beep(1567.98, 0.22) sleep(0.25) self.source.beep(1318.51, 0.1) sleep(0.125) self.source.beep(1567.98, 0.25) log.info("Finished")
class PotentiostaticProcedure(Procedure): potential = FloatParameter('Potential', units='V', default=0.1) max_current = FloatParameter('Maximum Current', units='mA', default=10) time = FloatParameter('Experiment Length', units='s', default=5) dt = FloatParameter('Measurement frequency', units='Hz', default=5) voltage_range = FloatParameter('Voltage Range', units='V', default=10) directory = Parameter('Working Directory', default='C:/Data/') filename = Parameter('Filename', default=unique_filename(str(directory), prefix='StaticE')) DATA_COLUMNS = ['Time (s)', 'Current (A)', 'Potential (V)'] def startup(self): self.source = Keithley2400("GPIB::24::INSTR") self.source.apply_voltage(voltage_range=None, compliance_current=0.1) self.source.measure_current(nplc=1, current=self.max_current, auto_range=True) # self.source.apply_current() # self.source.source_current_range = self.max_current*1e-3 # A # self.source.complinance_voltage = self.voltage_range self.source.enable_source() sleep(2) def execute(self): potential = self.potential times = np.arange(0, self.time, 1 / self.dt) steps = len(times) log.info("Applying potential of %f V" % potential) self.source.source_voltage = potential for i, time in enumerate(times): # self.source.source_current = potential sleep(1 / self.dt) # sleep between current measurements (Hz -> s) current = self.source.current data = { # 'Time (s)': time, 'Potential (V)': potential, 'Current': current } self.emit('results', data) self.emit('progress', 100. * i / steps) if self.should_stop(): log.warning("Catch stop command in procedure") break def shutdown(self): self.source.shutdown() self.source.beep(783.991, 0.1) sleep(0.125) self.source.beep(1046.50, 0.1) sleep(0.125) self.source.beep(1318.51, 0.1) sleep(0.125) self.source.beep(1567.98, 0.22) sleep(0.25) self.source.beep(1318.51, 0.1) sleep(0.125) self.source.beep(1567.98, 0.25) log.info("Finished")