class DarkCount(Spyrelet): requires = {'srs': SRS900} qutag = None currents = [] darkcountspercurrent = [] @Task() def qutagInit(self): print('qutag successfully initialized') @qutagInit.initializer def initialize(self): from lantz.drivers.qutools import QuTAG self.qutag = QuTAG() devType = self.qutag.getDeviceType() if (devType == self.qutag.DEVTYPE_QUTAG): print("found quTAG!") else: print("no suitable device found - demo mode activated") print("Device timebase:" + str(self.qutag.getTimebase())) return @qutagInit.finalizer def finalize(self): return @Task() def getDarkCounts(self): self.srs.SIM928_voltage[5] = 0 #self.srs.SIM928_voltage[6]=0 #self.srs.module_reset[6] self.srs.module_reset[5] self.srs.wait_time(100000) qutagparams = self.qutag_params.widget.get() start = qutagparams['Start Channel'] stop_1 = qutagparams['Stop Channel 1'] #stop_2 = qutagparams['Stop Channel 2'] ##True = rising edge, False = falling edge. Final value is threshold voltage self.qutag.setSignalConditioning(start, self.qutag.SIGNALCOND_MISC, True, 0.1) #self.qutag.setSignalConditioning(stop_1,self.qutag.SIGNALCOND_MISC,True,0.1) self.qutag.enableChannels((start, stop_1)) biasCurrentParams = self.bias_current.widget.get() qutagParams = self.qutag_params.widget.get() resistance = 10000 startCurrent = biasCurrentParams['Start Current'].to('A').magnitude stepSize = biasCurrentParams['Step Size'].to('A').magnitude stopCurrent = biasCurrentParams['Stop Current'].to('A').magnitude print('start current is' + str(startCurrent)) print('step size is' + str(stepSize)) print('stop current is' + str(stopCurrent)) expParams = self.exp_params.widget.get() currentCurrent = startCurrent self.srs.SIM928_voltage[5] = currentCurrent * resistance self.srs.SIM928_on[5] self.srs.wait_time(100000) points = ((stopCurrent - startCurrent) / stepSize) + (1 + stepSize) print(points) BC = [] DCR_1 = [] for i in range(int(points)): lost = self.qutag.getLastTimestamps(True) time.sleep(expParams['Exposure Time'].magnitude) timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps print(tchannel) darkcounts = values BC.append(currentCurrent) self.currents.append(currentCurrent * resistance) DCR_1.append(darkcounts / expParams['Exposure Time'].magnitude) self.darkcountspercurrent.append( darkcounts / expParams['Exposure Time'].magnitude) currentCurrent += stepSize self.srs.SIM928_voltage[5] = currentCurrent * resistance values = { 'bc': self.currents, 'dc': self.darkcountspercurrent, } self.getDarkCounts.acquire(values) self.srs.SIM928_voltage[5] = 0 self.srs.module_reset[5] datadir = 'D:\Data\\09.09.2019\\' print(BC) print(DCR_1) np.savetxt(datadir + expParams['File Name'] + '.csv', (BC, DCR_1), delimiter=',') print('Data stored under File Name: ' + expParams['File Name']) return @Element(name='Bias Current') def bias_current(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Start Current', { 'type': float, 'default': 2, 'units': 'uA' }), ('Step Size', { 'type': float, 'default': 0.2, 'units': 'uA' }), ('Stop Current', { 'type': float, 'default': 10, 'units': 'uA' }) ] w = ParamWidget(params) return w @Element(name='Experimental Parameters') def exp_params(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Exposure Time', { 'type': int, 'default': 10, 'units': 's' }), ('Points per Bias Current', { 'type': int, 'default': 1.0 }), ('File Name', { 'type': str }) ] w = ParamWidget(params) return w @Element(name='QuTAG Parameters') def qutag_params(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Start Channel', { 'type': int, 'default': 0 }), ('Stop Channel 1', { 'type': int, 'default': 1 }), ('Stop Channel 2', { 'type': int, 'default': 2 }), ('Total Hist Width Multiplier', { 'type': int, 'default': 5 }), ('Bin Count', { 'type': int, 'default': 1000 }) ] w = ParamWidget(params) return w @getDarkCounts.initializer def initialize(self): print('The identification of this instrument is : ' + self.srs.idn) print(self.srs.self_test) return @getDarkCounts.finalizer def finalize(self): return @Element(name='Histogram') def darkcountsplot(self): p = LinePlotWidget() p.plot('Dark Counts vs. Bias Current') return p @darkcountsplot.on(getDarkCounts.acquired) def darkcountsplot_update(self, ev): w = ev.widget bc = np.array(self.currents) cs = np.array(self.darkcountspercurrent) w.set('Dark Counts vs. Bias Current', xs=bc, ys=cs) return
class PLThinFilm(Spyrelet): requires = {'wm': Bristol_771} qutag = None laser = NetworkConnection('1.1.1.1') def configureQutag(self): qutagparams = self.qutag_params.widget.get() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] ##True = rising edge, False = falling edge. Final value is threshold voltage self.qutag.setSignalConditioning(start, self.qutag.SIGNALCOND_MISC, True, 1) self.qutag.setSignalConditioning(stop, self.qutag.SIGNALCOND_MISC, True, 0.1) self.qutag.enableChannels((start, stop)) def homelaser(self, start): current = self.wm.measure_wavelength() with Client(self.laser) as client: while current < start - 0.001 or current > start + 0.001: setting = client.get('laser1:ctl:wavelength-set', float) offset = current - start client.set('laser1:ctl:wavelength-set', setting - offset) time.sleep(3) current = self.wm.measure_wavelength() print(current, start) def createHistogram(self, stoparray, timebase, bincount, period, index, wls): hist = [0] * bincount for stoptime in stoparray: binNumber = int(stoptime * timebase * bincount / (period)) if binNumber >= bincount: continue else: hist[binNumber] += 1 out_name = "D:\\Data\\9.04.2019\\1T" np.savez(os.path.join(out_name, str(index + 59)), hist, wls) #np.savez(os.path.join(out_name,str(index+40)),hist,wls) print('Data stored under File Name: ' + self.exp_parameters.widget.get()['File Name'] + str(index)) @Task() def startpulse(self, timestep=100e-9): ##Qutag Part self.configureQutag() expparams = self.exp_parameters.widget.get() wlparams = self.wl_parameters.widget.get() self.homelaser(wlparams['start']) print('Laser Homed!') qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] for i in range(expparams['# of points']): ##Wavemeter measurements stoparray = [] startTime = time.time() wls = [] lost = self.qutag.getLastTimestamps(True) while time.time( ) - startTime < expparams['Measurement Time'].magnitude: lost = self.qutag.getLastTimestamps(True) time.sleep(5 * 0.1) timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps for k in range(values): # output all stop events together with the latest start event if tchannel[k] == start: synctimestamp = tstamp[k] else: stoptimestamp = tstamp[k] stoparray.append(stoptimestamp) wls.append(str(self.wm.measure_wavelength())) self.createHistogram(stoparray, timebase, bincount, 0.1, i, wls) print(i) with Client(self.laser) as client: setting = client.get('laser1:ctl:wavelength-set', float) client.set('laser1:ctl:wavelength-set', setting - 0.008) time.sleep(1) @Task() def qutagInit(self): print('qutag successfully initialized') @Element(name='Wavelength parameters') def wl_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('start', { 'type': float, 'default': 1535.71 }), ('stop', { 'type': float, 'default': 1535.50 }) ] w = ParamWidget(params) return w @Element(name='Experiment Parameters') def exp_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('# of points', { 'type': int, 'default': 50 }), ('Measurement Time', { 'type': int, 'default': 100, 'units': 's' }), ('File Name', { 'type': str }) ] w = ParamWidget(params) return w @Element(name='QuTAG Parameters') def qutag_params(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Start Channel', { 'type': int, 'default': 0 }), ('Stop Channel', { 'type': int, 'default': 1 }), ('Bin Count', { 'type': int, 'default': 1000 }) ] w = ParamWidget(params) return w @startpulse.initializer def initialize(self): self.wm.start_data() @startpulse.finalizer def finalize(self): self.wm.stop_data() print('Lifetime measurements complete.') return @qutagInit.initializer def initialize(self): from lantz.drivers.qutools import QuTAG self.qutag = QuTAG() devType = self.qutag.getDeviceType() if (devType == self.qutag.DEVTYPE_QUTAG): print("found quTAG!") else: print("no suitable device found - demo mode activated") print("Device timebase:" + str(self.qutag.getTimebase())) return @qutagInit.finalizer def finalize(self): return
class Lifetime(Spyrelet): requires = { 'wm': Bristol_771 } qutag = None conn1 = NetworkConnection('1.1.1.2') #conn1 = conn1 = SerialConnection('COM1') dlc = Client(conn1) def configureQutag(self): qutagparams = self.qutag_params.widget.get() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] ##True = rising edge, False = falling edge. Final value is threshold voltage self.qutag.setSignalConditioning(start,self.qutag.SIGNALCOND_MISC,True,1) self.qutag.setSignalConditioning(stop,self.qutag.SIGNALCOND_MISC,True,0.1) self.qutag.enableChannels((start,stop)) def createHistogram(self,stoparray, timebase, bincount, period, index, wls): hist = [0]*bincount for stoptime in stoparray: binNumber = int(stoptime*timebase*bincount/(period)) if binNumber >= bincount: continue else: hist[binNumber]+=1 out_name = "D:\\Data\\10.9.2019\\film" np.savez(os.path.join(out_name,str(index)),hist,wls) #np.savez(os.path.join(out_name,str(index+40)),hist,wls) print('Data stored under File Name: ' + self.exp_parameters.widget.get()['File Name'] + str(index)) @Task() def startpulse(self, timestep=1e-9): with Client(self.conn1) as dlc: print(dlc.get("laser1:ctl:wavelength")) time.sleep(1000) self.configureQutag() qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] expparams = self.exp_parameters.widget.get() for i in range(expparams['# of points']): ##Wavemeter measurements stoparray = [] startTime = time.time() wls=[] lost = self.qutag.getLastTimestamps(True) while time.time()-startTime < expparams['Measurement Time'].magnitude: lost = self.qutag.getLastTimestamps(True) time.sleep(30*100e-3) timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps for k in range(values): # output all stop events together with the latest start event if tchannel[k] == start: synctimestamp = tstamp[k] else: stoptimestamp = tstamp[k] stoparray.append(stoptimestamp) wls.append(str(self.wm.measure_wavelength())) self.createHistogram(stoparray, timebase, bincount, 100e-3,i, wls) print(i) #self.fungen.voltage[2] = self.fungen.voltage[2].magnitude + 2*dcparams['DC step size'].magnitude #time.sleep(100000) @Task() def qutagInit(self): print('qutag successfully initialized') @Element(name='Pulse parameters') def pulse_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('pulse height', {'type': float, 'default': 3, 'units':'V'}), ('pulse width', {'type': float, 'default': 500e-9, 'units':'s'}), ('period', {'type': float, 'default': 0.1, 'units':'s'}), ] w = ParamWidget(params) return w @Element(name='DC parameters') def DC_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('DC height', {'type': float, 'default': 0, 'units':'V'}), ('DC step size', {'type': float, 'default': 0.1, 'units':'V'}), ] w = ParamWidget(params) return w @Element(name='Experiment Parameters') def exp_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('# of points', {'type': int, 'default': 10}), ('Measurement Time', {'type': int, 'default': 10, 'units':'s'}), ('File Name', {'type': str}) ] w = ParamWidget(params) return w @Element(name='QuTAG Parameters') def qutag_params(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Start Channel', {'type': int, 'default': 0}), ('Stop Channel', {'type': int, 'default': 1}), ('Bin Count', {'type': int, 'default': 1000}) ] w = ParamWidget(params) return w @startpulse.initializer def initialize(self): self.wm.start_data() @startpulse.finalizer def finalize(self): self.wm.stop_data() print('Lifetime measurements complete.') return @qutagInit.initializer def initialize(self): from lantz.drivers.qutools import QuTAG self.qutag = QuTAG() devType = self.qutag.getDeviceType() if (devType == self.qutag.DEVTYPE_QUTAG): print("found quTAG!") else: print("no suitable device found - demo mode activated") print("Device timebase:" + str(self.qutag.getTimebase())) return @qutagInit.finalizer def finalize(self): return
class Lifetime(Spyrelet): requires = {'fungen': Keysight_33622A, 'wm': Bristol_771} qutag = None def configureQutag(self): qutagparams = self.qutag_params.widget.get() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] ##True = rising edge, False = falling edge. Final value is threshold voltage self.qutag.setSignalConditioning(start, self.qutag.SIGNALCOND_MISC, True, 1) self.qutag.setSignalConditioning(stop, self.qutag.SIGNALCOND_MISC, True, 0.1) self.qutag.enableChannels((start, stop)) def createHistogram(self, stoparray, timebase, bincount, period, index, wls): hist = [0] * bincount for stoptime in stoparray: binNumber = int(stoptime * timebase * bincount / (period)) if binNumber >= bincount: continue else: hist[binNumber] += 1 out_name = "D:\\Data\\9.1.2019\\T1" np.savez(os.path.join(out_name, str(index)), hist, wls) #np.savez(os.path.join(out_name,str(index+40)),hist,wls) print('Data stored under File Name: ' + self.exp_parameters.widget.get()['File Name'] + str(index)) @Task() def startpulse(self, timestep=1e-9): self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' self.fungen.clear_mem(1) self.fungen.clear_mem(2) params = self.pulse_parameters.widget.get() pulse = Arbseq_Class('pulse', timestep) pulse.delays = [0] pulse.heights = [1] pulse.widths = [params['pulse width'].magnitude] pulse.totaltime = params['pulse width'].magnitude pulse.nrepeats = 0 pulse.repeatstring = 'once' pulse.markerstring = 'highAtStartGoLow' pulse.markerloc = 0 pulse.create_sequence() dc = Arbseq_Class('dc', timestep) dc.delays = [0] dc.heights = [0] dc.widths = [params['pulse width'].magnitude] dc.totaltime = params['pulse width'].magnitude dc.repeatstring = 'repeat' dc.markerstring = 'lowAtStart' dc.markerloc = 0 period = params['period'].magnitude width = params['pulse width'].magnitude repeats = period / width - 1 dc.nrepeats = repeats dc.create_sequence() dc2 = Arbseq_Class('dc', timestep) dc2.delays = [0] dc2.heights = [1] dc2.widths = [params['pulse width'].magnitude] dc2.totaltime = params['pulse width'].magnitude dc2.repeatstring = 'repeat' dc2.markerstring = 'lowAtStart' dc2.markerloc = 0 period = params['period'].magnitude print(period) width = params['pulse width'].magnitude repeats = period / width dc2.nrepeats = repeats dc2.create_sequence() self.fungen.send_arb(pulse, 1) self.fungen.send_arb(dc, 1) self.fungen.send_arb(dc2, 2) seq1 = [pulse, dc] self.fungen.create_arbseq('pulsetest', seq1, 1) self.fungen.wait() self.fungen.voltage[1] = params['pulse height'] self.fungen.output[1] = 'ON' dcparams = self.DC_parameters.widget.get() self.fungen.create_arbseq('dc2', [dc2], 2) self.fungen.wait() self.fungen.voltage[2] = dcparams['DC height'] self.fungen.output[2] = 'ON' self.configureQutag() qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] expparams = self.exp_parameters.widget.get() for i in range(expparams['# of points']): ##Wavemeter measurements stoparray = [] startTime = time.time() wls = [] lost = self.qutag.getLastTimestamps(True) while time.time( ) - startTime < expparams['Measurement Time'].magnitude: lost = self.qutag.getLastTimestamps(True) time.sleep(30 * period) timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps for k in range(values): # output all stop events together with the latest start event if tchannel[k] == start: synctimestamp = tstamp[k] else: stoptimestamp = tstamp[k] stoparray.append(stoptimestamp) wls.append(str(self.wm.measure_wavelength())) self.createHistogram(stoparray, timebase, bincount, period, i, wls) print(i) self.fungen.voltage[2] = self.fungen.voltage[ 2].magnitude + 2 * dcparams['DC step size'].magnitude time.sleep(100000) self.fungen.output[1] = 'OFF' @Task() def qutagInit(self): print('qutag successfully initialized') @Element(name='Pulse parameters') def pulse_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('pulse height', { 'type': float, 'default': 3, 'units': 'V' }), ('pulse width', { 'type': float, 'default': 500e-9, 'units': 's' }), ('period', { 'type': float, 'default': 0.1, 'units': 's' }), ] w = ParamWidget(params) return w @Element(name='DC parameters') def DC_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('DC height', { 'type': float, 'default': 0, 'units': 'V' }), ('DC step size', { 'type': float, 'default': 0.1, 'units': 'V' }), ] w = ParamWidget(params) return w @Element(name='Experiment Parameters') def exp_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('# of points', { 'type': int, 'default': 10 }), ('Measurement Time', { 'type': int, 'default': 10, 'units': 's' }), ('File Name', { 'type': str }) ] w = ParamWidget(params) return w @Element(name='QuTAG Parameters') def qutag_params(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Start Channel', { 'type': int, 'default': 0 }), ('Stop Channel', { 'type': int, 'default': 1 }), ('Bin Count', { 'type': int, 'default': 1000 }) ] w = ParamWidget(params) return w @startpulse.initializer def initialize(self): self.wm.start_data() self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' self.fungen.clear_mem(1) self.fungen.clear_mem(2) self.fungen.wait() @startpulse.finalizer def finalize(self): self.wm.stop_data() self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' print('Lifetime measurements complete.') return @qutagInit.initializer def initialize(self): from lantz.drivers.qutools import QuTAG self.qutag = QuTAG() devType = self.qutag.getDeviceType() if (devType == self.qutag.DEVTYPE_QUTAG): print("found quTAG!") else: print("no suitable device found - demo mode activated") print("Device timebase:" + str(self.qutag.getTimebase())) return @qutagInit.finalizer def finalize(self): return
class TwoPulsePhotonEcho(Spyrelet): requires = { 'fungen': Keysight_33622A # 'srs': SRS900 } qutag = None xs = np.array([]) ys = np.array([]) hist = [] def configureQutag(self): qutagparams = self.qutag_params.widget.get() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] ##True = rising edge, False = falling edge. Final value is threshold voltage self.qutag.setSignalConditioning(start, self.qutag.SIGNALCOND_MISC, True, 1) self.qutag.setSignalConditioning(stop, self.qutag.SIGNALCOND_MISC, True, 0.1) self.qutag.enableChannels((start, stop)) def createHistogram(self, stoparray, timebase, bincount, totalWidth, tau): lowBound = 1.9 * tau highBound = 2.1 * tau hist = [0] * bincount for stoptime in stoparray: binNumber = int(stoptime * timebase * bincount / (totalWidth)) if binNumber >= bincount: continue print('error') else: hist[binNumber] += 1 out_name = "D:\\Data\\7.31.2019\\250mTSNSPD" x = [] for i in range(bincount): x.append(i * totalWidth / bincount) np.savez(os.path.join(out_name, str(int(round(tau * 1e6, 0)))), hist, x) print('Data stored under File Name: ' + str(tau)) def createPlottingHist(self, stoparray, timebase, bincount, totalWidth): for stoptime in stoparray: binNumber = int(stoptime * timebase * bincount / (totalWidth)) if binNumber >= bincount: continue else: self.hist[binNumber] += 1 def initHist(self, bincount): self.hist = [0] * bincount @Task() def startpulse(self, timestep=1e-9): params = self.pulse_parameters.widget.get() tau = params['start tau'] period = params['period'].magnitude repeat_unit = params['repeat unit'].magnitude pulse_width = params['pulse width'].magnitude buffer_time = params['buffer time'].magnitude shutter_offset = params['shutter offset'].magnitude wholeRange = params['measuring range'].magnitude self.configureQutag() for i in range( int((params['stop tau'] - params['start tau']) / params['step tau']) + 1): xs = np.array([]) ys = np.array([]) hist = [] self.dataset.clear() self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' self.fungen.clear_mem(1) self.fungen.clear_mem(2) self.fungen.wait() # self.srs.module_reset[5] # self.srs.SIM928_voltage[5]=params['srs bias'].magnitude+0.000000001*i # self.srs.SIM928_on[5] ## build pulse sequence for AWG channel 1 chn1buffer = Arbseq_Class('chn1buffer', timestep) chn1buffer.delays = [0] chn1buffer.heights = [0] chn1buffer.widths = [repeat_unit] chn1buffer.totaltime = repeat_unit chn1buffer.nrepeats = buffer_time / repeat_unit chn1buffer.repeatstring = 'repeat' chn1buffer.markerstring = 'lowAtStart' chn1buffer.markerloc = 0 chn1bufferwidth = repeat_unit * chn1buffer.nrepeats chn1buffer.create_sequence() chn1pulse = Arbseq_Class('chn1pulse', timestep) chn1pulse.delays = [0] chn1pulse.heights = [1] chn1pulse.widths = [pulse_width] chn1pulse.totaltime = pulse_width chn1pulse.nrepeats = 0 chn1pulse.repeatstring = 'once' chn1pulse.markerstring = 'highAtStartGoLow' chn1pulse.markerloc = 0 chn1pulsewidth = pulse_width chn1pulse.create_sequence() chn1dc = Arbseq_Class('chn1dc', timestep) chn1dc.delays = [0] chn1dc.heights = [0] chn1dc.widths = [repeat_unit] chn1dc.totaltime = repeat_unit chn1dc.repeatstring = 'repeat' chn1dc.markerstring = 'lowAtStart' chn1dc.markerloc = 0 chn1dcrepeats = int( (tau.magnitude - 1.5 * pulse_width) / repeat_unit) chn1dc.nrepeats = chn1dcrepeats chn1dcwidth = repeat_unit * chn1dcrepeats print(tau.magnitude, pulse_width, chn1dcrepeats) chn1dc.create_sequence() chn1pulse2 = Arbseq_Class('chn1pulse2', timestep) chn1pulse2.delays = [0] chn1pulse2.heights = [1] chn1pulse2.widths = [pulse_width * 2] chn1pulse2.totaltime = pulse_width * 2 chn1pulse2width = pulse_width * 2 chn1pulse2.nrepeats = 0 chn1pulse2.repeatstring = 'once' chn1pulse2.markerstring = 'lowAtStart' chn1pulse2.markerloc = 0 chn1pulse2.create_sequence() chn1pulse3 = Arbseq_Class('chn1pulse3', timestep) chn1pulse3.delays = [0] chn1pulse3.heights = [0] chn1pulse3.widths = [repeat_unit] chn1pulse3.totaltime = repeat_unit chn1pulse3width = shutter_offset chn1pulse3.nrepeats = shutter_offset / repeat_unit chn1pulse3.repeatstring = 'repeat' chn1pulse3.markerstring = 'lowAtStart' chn1pulse3.markerloc = 0 chn1pulse3.create_sequence() chn1dc2 = Arbseq_Class('chn1dc2', timestep) chn1dc2.delays = [0] chn1dc2.heights = [0] chn1dc2.widths = [repeat_unit] chn1dc2.totaltime = repeat_unit chn1dc2.repeatstring = 'repeat' chn1dc2.markerstring = 'lowAtStart' chn1dc2repeats = int( (period - chn1bufferwidth - chn1pulsewidth - chn1dcwidth - chn1pulse2width - chn1pulse3width) / repeat_unit) chn1dc2.nrepeats = chn1dc2repeats chn1dc2.markerloc = 0 #print((chn1dc2repeats*params['repeat unit'].magnitude) + tau.magnitude + params['pulse width'].magnitude) print(params['repeat unit'].magnitude * chn1dc2.nrepeats) chn1dc2.create_sequence() ## build pulse sequence for AWG channel 2 chn2buffer = Arbseq_Class('chn2buffer', timestep) chn2buffer.delays = [0] chn2buffer.heights = [1] chn2buffer.widths = [repeat_unit] chn2buffer.totaltime = repeat_unit chn2buffer.nrepeats = buffer_time / repeat_unit chn2buffer.repeatstring = 'repeat' chn2buffer.markerstring = 'lowAtStart' chn2buffer.markerloc = 0 chn2bufferwidth = repeat_unit * chn2buffer.nrepeats chn2buffer.create_sequence() chn2pulse1 = Arbseq_Class('chn2pulse1', timestep) chn2pulse1.delays = [0] chn2pulse1.heights = [1] chn2pulse1.widths = [pulse_width] chn2pulse1.totaltime = pulse_width chn2pulse1width = pulse_width chn2pulse1.nrepeats = 0 chn2pulse1.repeatstring = 'once' chn2pulse1.markerstring = 'highAtStartGoLow' chn2pulse1.markerloc = 0 chn2pulse1.create_sequence() chn2dc1 = Arbseq_Class('chn2dc1', timestep) chn2dc1.delays = [0] chn2dc1.heights = [1] chn2dc1.widths = [repeat_unit] chn2dc1.totaltime = repeat_unit chn2dc1.repeatstring = 'repeat' chn2dc1.markerstring = 'lowAtStart' chn2dc1.markerloc = 0 chn2dc1repeats = int( (tau.magnitude - 1.5 * pulse_width) / repeat_unit) chn2dc1.nrepeats = chn2dc1repeats chn2dc1width = repeat_unit * chn2dc1repeats chn2dc1.create_sequence() chn2pulse2 = Arbseq_Class('chn2pulse2', timestep) chn2pulse2.delays = [0] chn2pulse2.heights = [1] chn2pulse2.widths = [pulse_width * 2] chn2pulse2.totaltime = pulse_width * 2 chn2pulse2width = pulse_width * 2 chn2pulse2.nrepeats = 0 chn2pulse2.repeatstring = 'once' chn2pulse2.markerstring = 'lowAtStart' chn2pulse2.markerloc = 0 chn2pulse2.create_sequence() chn2pulse3 = Arbseq_Class('chn2pulse3', timestep) chn2pulse3.delays = [0] chn2pulse3.heights = [1] chn2pulse3.widths = [repeat_unit] chn2pulse3.totaltime = repeat_unit chn2pulse3width = shutter_offset chn2pulse3.nrepeats = shutter_offset / repeat_unit chn2pulse3.repeatstring = 'repeat' chn2pulse3.markerstring = 'lowAtStart' chn2pulse3.markerloc = 0 chn2pulse3.create_sequence() chn2dc2 = Arbseq_Class('chn2dc2', timestep) chn2dc2.delays = [0] chn2dc2.heights = [-1] chn2dc2.widths = [repeat_unit] chn2dc2.totaltime = repeat_unit chn2dc2.repeatstring = 'repeat' chn2dc2.markerstring = 'lowAtStart' chn2dc2repeats = int( (period - chn2bufferwidth - chn2pulse1width - chn2dc1width - chn2pulse2width - chn2pulse3width) / repeat_unit) chn2dc2.nrepeats = chn2dc2repeats chn2dc2.markerloc = 0 print(repeat_unit * chn2dc2.nrepeats) chn2dc2.create_sequence() self.fungen.send_arb(chn1buffer, 1) self.fungen.send_arb(chn1pulse, 1) self.fungen.send_arb(chn1dc, 1) self.fungen.send_arb(chn1pulse2, 1) self.fungen.send_arb(chn1pulse3, 1) self.fungen.send_arb(chn1dc2, 1) self.fungen.send_arb(chn2buffer, 2) self.fungen.send_arb(chn2pulse1, 2) self.fungen.send_arb(chn2dc1, 2) self.fungen.send_arb(chn2pulse2, 2) self.fungen.send_arb(chn2pulse3, 2) self.fungen.send_arb(chn2dc2, 2) seq = [ chn1buffer, chn1pulse, chn1dc, chn1pulse2, chn1pulse3, chn1dc2 ] seq2 = [ chn2buffer, chn2pulse1, chn2dc1, chn2pulse2, chn2pulse3, chn2dc2 ] self.fungen.create_arbseq('twoPulse', seq, 1) self.fungen.create_arbseq('shutter', seq2, 2) self.fungen.wait() self.fungen.voltage[ 1] = params['pulse height'].magnitude + 0.000000000001 * i self.fungen.voltage[2] = 7.1 + 0.0000000000001 * i print(self.fungen.voltage[1], self.fungen.voltage[2]) self.fungen.output[2] = 'ON' self.fungen.trigger_delay(1, shutter_offset) self.fungen.sync() time.sleep(1) self.fungen.output[1] = 'ON' #self.fungen.output[2] = 'OFF' ##Qutag Part self.configureQutag() qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] stoparray = [] tempStopArray = [] histCounter = 0 quenchCounter = 0 self.initHist(bincount) for j in range(int( self.exp_parameters.widget.get()['# of Passes'])): lost = self.qutag.getLastTimestamps(True) time.sleep(period) timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps # print(values) for k in range(values): # output all stop events together with the latest start event # if tchannel[k] == start: # synctimestamp = tstamp[k] if tchannel[k] == stop: #stoptimestamp = tstamp[k] # if tstamp[k]*1e-6>2*tau.magnitude-1 and tstamp[k]*1e-6<2*tau.magnitude+2: stoparray.append(tstamp[k]) #tempStopArray.append(stoptimestamp) # histCounter+=1 # if histCounter%20==0: # self.createPlottingHist(tempStopArray, timebase, bincount,qutagparams['Total Hist Width Multiplier']*tau.magnitude) # self.xs = np.asarray(range(len(self.hist))) # self.ys=np.asarray(self.hist) # values = { # 't': np.asarray(range(len(self.hist))), # 'y': np.asarray(self.hist), # } # self.startpulse.acquire(values) # tempStopArray = [] # TODO: quench protection # if self.srs.SIM928_voltage[???] >= qunech threshold and quenchCounter<=10: # self.srs.SIM928_off[6] # time.sleep(period*10) # self.srs.SIM928_on[6] # quenchCounter+=1 # elif quenchCounter>10: # print('quenched more than 10 times') # break # else: # continue self.createHistogram(stoparray, timebase, bincount, wholeRange, tau.magnitude) tau += params['step tau'] #self.fungen.output[1] = 'OFF' @Task() def qutagInit(self): print('qutag successfully initialized') @Element(name='QuTAG Parameters') def qutag_params(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Start Channel', { 'type': int, 'default': 0 }), ('Stop Channel', { 'type': int, 'default': 1 }), ('Total Hist Width Multiplier', { 'type': int, 'default': 5 }), ('Bin Count', { 'type': int, 'default': 1000 }) ] w = ParamWidget(params) return w @Element(name='Experiment Parameters') def exp_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('# of Passes', { 'type': int, 'default': 100 }), # ('File Name', {'type': str}) ] w = ParamWidget(params) return w @Element(name='Histogram') def averaged(self): p = LinePlotWidget() p.plot('Channel 1') return p @averaged.on(startpulse.acquired) def averaged_update(self, ev): w = ev.widget xs = self.xs ys = self.ys w.set('Channel 1', xs=xs, ys=ys) return @Element(name='Pulse parameters') def pulse_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('pulse height', { 'type': float, 'default': 3, 'units': 'V' }), ('pulse width', { 'type': float, 'default': 300e-9, 'units': 's' }), ('period', { 'type': float, 'default': 0.1, 'units': 's' }), ('repeat unit', { 'type': float, 'default': 50e-9, 'units': 's' }), ('start tau', { 'type': float, 'default': 3e-6, 'units': 's' }), ('stop tau', { 'type': float, 'default': 10e-6, 'units': 's' }), ('step tau', { 'type': float, 'default': 1e-6, 'units': 's' }), # ('srs bias', {'type': float, 'default': 1.2, 'units':'V'}), ('shutter offset', { 'type': float, 'default': 500e-9, 'units': 's' }), ('measuring range', { 'type': float, 'default': 70e-6, 'units': 's' }), ('buffer time', { 'type': float, 'default': 100e-6, 'units': 's' }), ] w = ParamWidget(params) return w @qutagInit.initializer def initialize(self): from lantz.drivers.qutools import QuTAG self.qutag = QuTAG() devType = self.qutag.getDeviceType() if (devType == self.qutag.DEVTYPE_QUTAG): print("found quTAG!") else: print("no suitable device found - demo mode activated") print("Device timebase:" + str(self.qutag.getTimebase())) return @qutagInit.finalizer def finalize(self): return @startpulse.initializer def initialize(self): self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' self.fungen.clear_mem(1) self.fungen.clear_mem(2) self.fungen.wait() @startpulse.finalizer def finalize(self): self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' print('Two Pulse measurements complete.') return
class HoleBurningSNSPD(Spyrelet): requires = { 'fungen': Keysight_33622A } qutag = None def configureQutag(self): qutagparams = self.qutag_params.widget.get() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] ##True = rising edge, False = falling edge. Final value is threshold voltage self.qutag.setSignalConditioning(start,self.qutag.SIGNALCOND_MISC,True,1) self.qutag.setSignalConditioning(stop,self.qutag.SIGNALCOND_MISC,True,0.1) self.qutag.enableChannels((start,stop)) def createHistogram(self,stoparray, timebase, bincount, period, index, wls): hist = [0]*bincount for stoptime in stoparray: binNumber = int(stoptime*timebase*bincount/(period)) if binNumber >= bincount: continue else: hist[binNumber]+=1 out_name = "D:\\Data\\8.2.2019\\thinfilm\\holeburning\\test" np.savez(os.path.join(out_name,str(index)),hist,wls) #np.savez(os.path.join(out_name,str(index+40)),hist,wls) print('Data stored under File Name: ' + self.exp_parameters.widget.get()['File Name'] + str(index)) @Task() def startpulse(self, timestep=1e-9): self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' repeat_unit = 50e-9 buffer_time = 100e-6 pulse_width = 500e-9 period = 200e-3 self.fungen.clear_mem(1) self.fungen.clear_mem(2) params = self.pulse_parameters.widget.get() chn1buffer = Arbseq_Class('chn1buffer', timestep) chn1buffer.delays = [0] chn1buffer.heights = [0] chn1buffer.widths = [repeat_unit] chn1buffer.totaltime = repeat_unit chn1buffer.nrepeats = buffer_time/repeat_unit chn1buffer.repeatstring = 'repeat' chn1buffer.markerstring = 'lowAtStart' chn1buffer.markerloc = 0 chn1bufferwidth = repeat_unit*chn1buffer.nrepeats chn1buffer.create_sequence() pulse = Arbseq_Class('pulse', timestep) pulse.delays = [0] pulse.heights = [0] pulse.widths = [repeat_unit] pulse.totaltime = repeat_unit pulserepeat = 400000 pulse.nrepeats = pulserepeat chn1pulsewidth=pulserepeat*repeat_unit pulse.repeatstring = 'repeat' pulse.markerstring = 'lowAtStart' pulse.markerloc = 0 pulse.create_sequence() chn1dc = Arbseq_Class('chn1dc', timestep) chn1dc.delays = [0] chn1dc.heights = [0] chn1dc.widths = [repeat_unit] chn1dc.totaltime = repeat_unit chn1dc.repeatstring = 'repeat' chn1dc.markerstring = 'lowAtStart' chn1dc.markerloc = 0 chn1dcrepeats = 200000 chn1dc.nrepeats = chn1dcrepeats chn1dcwidth = repeat_unit*chn1dcrepeats chn1dc.create_sequence() chn1pulse2 = Arbseq_Class('chn1pulse2', timestep) chn1pulse2.delays = [0] chn1pulse2.heights = [1] chn1pulse2.widths = [pulse_width] chn1pulse2.totaltime = pulse_width chn1pulse2width = pulse_width chn1pulse2.nrepeats = 0 chn1pulse2.repeatstring = 'once' chn1pulse2.markerstring = 'highAtStartGoLow' chn1pulse2.markerloc = 0 chn1pulse2.create_sequence() # chn1pulse3 = Arbseq_Class('chn1pulse3', timestep) # chn1pulse3.delays = [0] # chn1pulse3.heights = [0] # chn1pulse3.widths = [repeat_unit] # chn1pulse3.totaltime = repeat_unit # chn1pulse3width = shutter_offset # chn1pulse3.nrepeats = shutter_offset/repeat_unit # chn1pulse3.repeatstring = 'repeat' # chn1pulse3.markerstring = 'lowAtStart' # chn1pulse3.markerloc = 0 # chn1pulse3.create_sequence() chn1dc2 = Arbseq_Class('chn1dc2', timestep) chn1dc2.delays = [0] chn1dc2.heights = [0] chn1dc2.widths = [pulse_width] chn1dc2.totaltime = pulse_width chn1dc2.repeatstring = 'repeat' chn1dc2.markerstring = 'lowAtStart' chn1dc2repeats = 2e5 ch1dc2width=chn1dc2repeats*pulse_width chn1dc2.nrepeats = chn1dc2repeats chn1dc2.markerloc = 0 #print((chn1dc2repeats*params['repeat unit'].magnitude) + tau.magnitude + params['pulse width'].magnitude) chn1dc2.create_sequence() totalTime=chn1bufferwidth+chn1pulsewidth+chn1dcwidth+chn1pulse2width+ch1dc2width chn2buffer = Arbseq_Class('chn2buffer', timestep) chn2buffer.delays = [0] chn2buffer.heights = [1] chn2buffer.widths = [repeat_unit] chn2buffer.totaltime = repeat_unit chn2buffer.nrepeats = buffer_time/repeat_unit chn2buffer.repeatstring = 'repeat' chn2buffer.markerstring = 'lowAtStart' chn2buffer.markerloc = 0 chn2bufferwidth = repeat_unit*chn2buffer.nrepeats chn2buffer.create_sequence() chn2pulse1 = Arbseq_Class('chn2pulse1', timestep) chn2pulse1.delays = [0] chn2pulse1.heights = [1] chn2pulse1.widths = [repeat_unit] chn2pulse1.totaltime = repeat_unit chn2pulse1.nrepeats = pulserepeat chn2pulse1width = pulse_width chn2pulse1.repeatstring = 'repeat' chn2pulse1.markerstring = 'lowAtStart' chn2pulse1.markerloc = 0 chn2pulse1.create_sequence() chn2dc1 = Arbseq_Class('chn2dc1', timestep) chn2dc1.delays = [0] chn2dc1.heights = [1] chn2dc1.widths = [repeat_unit] chn2dc1.totaltime = repeat_unit chn2dc1.repeatstring = 'repeat' chn2dc1.markerstring = 'lowAtStart' chn2dc1.markerloc = 0 chn2dc1repeats = chn1dcrepeats chn2dc1.nrepeats = chn1dcrepeats chn2dc1width = repeat_unit*chn2dc1repeats chn2dc1.create_sequence() chn2pulse2 = Arbseq_Class('chn2pulse2', timestep) chn2pulse2.delays = [0] chn2pulse2.heights = [-1] chn2pulse2.widths = [pulse_width] chn2pulse2.totaltime = pulse_width chn2pulse2width = pulse_width chn2pulse2.nrepeats = 0 chn2pulse2.repeatstring = 'once' chn2pulse2.markerstring = 'highAtStartGoLow' chn2pulse2.markerloc = 0 chn2pulse2.create_sequence() chn2dc2 = Arbseq_Class('chn2dc2', timestep) chn2dc2.delays = [0] chn2dc2.heights = [-1] chn2dc2.widths = [pulse_width] chn2dc2.totaltime = pulse_width chn2dc2.repeatstring = 'repeat' chn2dc2.markerstring = 'lowAtStart' chn2dc2repeats = chn1dc2repeats chn2dc2.nrepeats = chn2dc2repeats chn2dc2.markerloc = 0 chn2dc2.create_sequence() self.fungen.send_arb(chn1buffer, 1) self.fungen.send_arb(pulse, 1) self.fungen.send_arb(chn1dc, 1) self.fungen.send_arb(chn1pulse2, 1) self.fungen.send_arb(chn1dc2, 1) self.fungen.send_arb(chn2buffer, 2) self.fungen.send_arb(chn2pulse1, 2) self.fungen.send_arb(chn2dc1, 2) self.fungen.send_arb(chn2pulse2, 2) self.fungen.send_arb(chn2dc2, 2) seq = [chn1buffer, pulse, chn1dc, chn1pulse2, chn1dc2] seq2=[chn2buffer,chn2pulse1,chn2dc1,chn2pulse2,chn2dc2] self.fungen.create_arbseq('pulsetest', seq2, 2) self.fungen.wait() self.fungen.voltage[2] = 7.1 self.fungen.output[2] = 'ON' #self.fungen.sync() self.fungen.create_arbseq('pulsetest', seq, 1) self.fungen.wait() self.fungen.voltage[1] = params['pulse height'] self.fungen.sync() self.fungen.output[1] = 'ON' #time.sleep(100000) self.configureQutag() qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] expparams = self.exp_parameters.widget.get() for i in range(expparams['# of points']): ##Wavemeter measurements stoparray = [] startTime = time.time() wls=[] lost = self.qutag.getLastTimestamps(True) while time.time()-startTime < expparams['Measurement Time'].magnitude: lost = self.qutag.getLastTimestamps(True) time.sleep(30*totalTime) timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps for k in range(values): # output all stop events together with the latest start event if tchannel[k] == start: synctimestamp = tstamp[k] else: stoptimestamp = tstamp[k] stoparray.append(stoptimestamp) self.createHistogram(stoparray, timebase, bincount, totalTime,i, wls) print(i) #self.fungen.voltage[2] = self.fungen.voltage[2].magnitude + 2*dcparams['DC step size'].magnitude self.fungen.output[1] = 'OFF' @Task() def qutagInit(self): print('qutag successfully initialized') @Element(name='Pulse parameters') def pulse_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('pulse height', {'type': float, 'default': 3, 'units':'V'}), ('pulse width', {'type': float, 'default': 500e-9, 'units':'s'}), ('period', {'type': float, 'default': 0.1, 'units':'s'}), ] w = ParamWidget(params) return w @Element(name='DC parameters') def DC_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('DC height', {'type': float, 'default': 0, 'units':'V'}), ('DC step size', {'type': float, 'default': 0.1, 'units':'V'}), ] w = ParamWidget(params) return w @Element(name='Experiment Parameters') def exp_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('# of points', {'type': int, 'default': 10}), ('Measurement Time', {'type': int, 'default': 10, 'units':'s'}), ('File Name', {'type': str}) ] w = ParamWidget(params) return w @Element(name='QuTAG Parameters') def qutag_params(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Start Channel', {'type': int, 'default': 0}), ('Stop Channel', {'type': int, 'default': 1}), ('Bin Count', {'type': int, 'default': 1000}) ] w = ParamWidget(params) return w @startpulse.initializer def initialize(self): self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' self.fungen.clear_mem(1) self.fungen.clear_mem(2) self.fungen.wait() @startpulse.finalizer def finalize(self): self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' print('Lifetime measurements complete.') return @qutagInit.initializer def initialize(self): from lantz.drivers.qutools import QuTAG self.qutag = QuTAG() devType = self.qutag.getDeviceType() if (devType == self.qutag.DEVTYPE_QUTAG): print("found quTAG!") else: print("no suitable device found - demo mode activated") print("Device timebase:" + str(self.qutag.getTimebase())) return @qutagInit.finalizer def finalize(self): return
class PLThinFilm(Spyrelet): requires = { 'wm': Bristol_771, 'fungen': Keysight_33622A, 'SRS': SRS900 } qutag = None laser = NetworkConnection('1.1.1.2') xs=np.array([]) ys=np.array([]) hist=[] def configureQutag(self): qutagparams = self.qutag_params.widget.get() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] ##True = rising edge, False = falling edge. Final value is threshold voltage self.qutag.setSignalConditioning(start,self.qutag.SIGNALCOND_MISC,True,1) self.qutag.setSignalConditioning(stop,self.qutag.SIGNALCOND_MISC,True,0.1) self.qutag.enableChannels((start,stop)) def homelaser(self,start): current=self.wm.measure_wavelength() with Client(self.laser) as client: while current<start-0.001 or current>start+0.001: setting=client.get('laser1:ctl:wavelength-set', float) offset=current-start client.set('laser1:ctl:wavelength-set', setting-offset) time.sleep(3) current=self.wm.measure_wavelength() print(current, start) def createHistogram(self,stoparray, timebase, bincount, period, index, wls,out_name,extra_data=False): print('creating histogram') hist = [0]*bincount for stoptime in stoparray: # stoptime=ps # timebase = converts to seconds # bincount: # of bins specified by user # period: measurement time specified by user binNumber = int(stoptime*timebase*bincount/(period)) if binNumber >= bincount: continue print('error') else: hist[binNumber]+=1 if extra_data==False: np.savez(os.path.join(out_name,str(index)),hist,wls) if extra_data!=False: np.savez(os.path.join(out_name,str(index)),hist,wls,extra_data) #np.savez(os.path.join(out_name,str(index+40)),hist,wls) print('Data stored under File Name: ' + out_name +'\\'+str(index)+'.npz') def resetTargets(self,targets,totalShift,i,channel): print('AWG limit exceeded, resetting voltage targets') # get the current wavelength current=self.wm.measure_wavelength() # adjust all targets to be lower again # reset totalShift print('totalShift: '+str(totalShift)) newTargets=[j-totalShift for j in targets] print('newTargets') voltageTargets=newTargets totalShift=0 # bring voltage back to ideal self.fungen.offset[channel]=Q_(voltageTargets[i-1],'V') # drive to last wavelength again self.homelaser(current) wl=self.wm.measure_wavelength() return voltageTargets,totalShift,wl def reset_quench(self): """ A typical quench shows the voltage exceeding 2mV. """ qutagparams = self.qutag_params.widget.get() # vm1=qutagparams['Voltmeter Channel 1'] vm2=qutagparams['Voltmeter Channel 2'] # vs1=qutagparams['Battery Port 1'] vs2=qutagparams['Battery Port 2'] # self.SRS.clear_status() # V1=self.SRS.SIM970_voltage[vm1].magnitude self.SRS.clear_status() V2=self.SRS.SIM970_voltage[vm2].magnitude quenchfix='YES' # i=0 # while (float(V1)>=0.010): # i+=1 # print('Voltage 1 higher than 10mV, resetting') # self.SRS.SIM928_on_off[vs1]='OFF' # self.SRS.SIM928_on_off[vs2]='OFF' # self.SRS.SIM928_on_off[vs1]='ON' # self.SRS.SIM928_on_off[vs2]='ON' # print('checking Voltage 1 again') # self.SRS.clear_status() # time.sleep(1) # V1=self.SRS.SIM970_voltage[vm1].magnitude # print('Voltage 1: '+str(V1)+'V') # if i>10: # self.fungen.output[1]='OFF' # self.fungen.output[2]='OFF' # quenchfix='NO' # break i=0 while (float(V2)>=0.010): i+=1 print('Voltage 2 higher than 10mV, resetting') self.SRS.SIM928_on_off[vs1]='OFF' self.SRS.SIM928_on_off[vs2]='OFF' self.SRS.SIM928_on_off[vs1]='ON' self.SRS.SIM928_on_off[vs2]='ON' print('checking Voltage 2 again') self.SRS.clear_status() time.sleep(1) V2=self.SRS.SIM970_voltage[vm2].magnitude print('Voltage 2: '+str(V2)+'V') if i>10: self.fungen.output[1]='OFF' self.fungen.output[2]='OFF' quenchfix='NO' break return quenchfix @Task() def piezo_scan(self,timestep=100e-9): #self.fungen.output[1]='ON' piezo_params=self.piezo_parameters.widget.get() Vstart=piezo_params['voltage start'] Vstop=piezo_params['voltage end'] pts=piezo_params['scan points'] voltageTargets=np.linspace(Vstart,Vstop,pts) reversedTargets=voltageTargets[::-1] voltageTargets=reversedTargets print('voltageTargets: '+str(voltageTargets)) channel=piezo_params['AWG channel'] # turn off AWG self.fungen.output[channel]='OFF' ##Qutag Part self.configureQutag() expparams = self.exp_parameters.widget.get() wlparams = self.wl_parameters.widget.get() # drive to the offset estimated by the piezo voltage # 1MOhm impedance of laser mismatch with 50Ohm impedance of AWG # multiplies voltage 2x # 140V ~ 40GHz ~ 315pm piezo_range=(Vstop.magnitude-Vstart.magnitude)*0.315/(140)*piezo_params['Scale factor'] #pm print('piezo_range: '+str(piezo_range)+str(' nm')) wl_start=wlparams['start']-piezo_range wl_stop=wlparams['stop']+piezo_range wlpts=np.linspace(wl_start,wl_stop,pts) self.homelaser(wlparams['start']-piezo_range) print('Laser Homed!') qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] PATH="C:\\Data\\"+self.exp_parameters.widget.get()['File Name'] if PATH!="C:\\Data\\": if (os.path.exists(PATH)): print('deleting old directory with same name') os.system('rm -rf '+str(PATH)) print('making new directory') Path(PATH).mkdir(parents=True, exist_ok=True) else: print("Specify a foldername & rerun task.") print("Task will error trying to saving data.") # turn on AWG self.fungen.output[channel]='ON' last_wl=self.wm.measure_wavelength() wls=[] totalShift=0 for i in range(pts): print(i) if (voltageTargets[i]>5) or (voltageTargets[i]<-5): newTargets,newShift,wl=self.resetTargets(voltageTargets,totalShift,i,channel) voltageTargets=newTargets totalShift=newShift self.fungen.offset[channel]=Q_(voltageTargets[i],'V') wl=self.wm.measure_wavelength() counter=0 if len(wls)!=0: last_wl=np.mean(np.array(wls).astype(np.float)) print('i: '+str(i)+', initializing') while ((wl<wlpts[i]-0.0002) or (wl>wlpts[i]+0.0002)): offset=wl-wlpts[i] Voff=offset/0.315*140/(piezo_params['Scale factor']*2) if offset<0: if voltageTargets[i]+Voff<-5: newTargets,newShift,wl=self.resetTargets(voltageTargets,totalShift,i,channel) voltageTargets=newTargets totalShift=newShift print('AWG limit exceeded, resetting voltage targets') else: newTargets=[j+Voff for j in voltageTargets] voltageTargets=newTargets self.fungen.offset[channel]=Q_(newTargets[i],'V') time.sleep(3) wl=self.wm.measure_wavelength() counter+=Voff totalShift+=Voff else: if voltageTargets[i]+Voff>5: newTargets,newShift,wl=self.resetTargets(voltageTargets,totalShift,i,channel) voltageTargets=newTargets totalShift=newShift print('AWG limit exceeded, resetting voltage targets') else: newTargets=[j+Voff for j in voltageTargets] voltageTargets=newTargets self.fungen.offset[channel]=Q_(newTargets[i],'V') time.sleep(3) wl=self.wm.measure_wavelength() counter+=Voff totalShift+=Voff print('taking data') print('current target wavelength: '+str(wlpts[i])) print('current set voltage: '+str(voltageTargets[i])) print('actual wavelength: '+str(self.wm.measure_wavelength())) time.sleep(1) ##Wavemeter measurements stoparray = [] startTime = time.time() wls=[] lost = self.qutag.getLastTimestamps(True) counter2=0 looptime=startTime while looptime-startTime < expparams['Measurement Time'].magnitude: loopstart=time.time() # get the lost timestamps lost = self.qutag.getLastTimestamps(True) # wait half a milisecond time.sleep(5*0.1) # get thte timestamps in the last half milisecond timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps for k in range(values): # output all stop events together with the latest start event if tchannel[k] == start: synctimestamp = tstamp[k] else: stoptimestamp = tstamp[k] stoparray.append(stoptimestamp) wl=self.wm.measure_wavelength() wls.append(str(wl)) looptime+=time.time()-loopstart #print('i: '+str(i)+', looptime-startTime: '+str(looptime-startTime)) quenchfix=self.reset_quench() if quenchfix!='YES': print('SNSPD quenched and could not be reset') self.fungen.output[1]='OFF' self.fungen.output[2]='OFF' endloop while ((wl<wlpts[i]-0.0002) or (wl>wlpts[i]+0.0002)) and (time.time()-startTime < expparams['Measurement Time'].magnitude): offset=wl-wlpts[i] Voff=offset/0.315*140/(piezo_params['Scale factor']*2) if offset<0: if voltageTargets[i]+Voff<-5: break else: newTargets=[j+Voff for j in voltageTargets] voltageTargets=newTargets self.fungen.offset[channel]=Q_(newTargets[i],'V') time.sleep(3) wl=self.wm.measure_wavelength() counter2+=Voff totalShift+=Voff else: if voltageTargets[i]+Voff>5: break else: newTargets=[j+Voff for j in voltageTargets] voltageTargets=newTargets self.fungen.offset[channel]=Q_(newTargets[i],'V') time.sleep(3) wl=self.wm.measure_wavelength() counter2+=Voff totalShift+=Voff print('actual wavelength: '+str(wl)) print('targets shift during measurement: '+str(counter2)+'V') self.createHistogram(stoparray, timebase, bincount, expparams['AWG Pulse Repetition Period'].magnitude,i, wls, "C:\\Data\\"+self.exp_parameters.widget.get()['File Name']) # turn off AWG self.fungen.output[channel]='OFF' @Task() def startpulse(self, timestep=100e-9): self.fungen.output[1]='OFF' #self.fungen.output[2]='OFF' self.SRS.SIMmodule_on[6] ##Turn on the power supply of the SNSPD time.sleep(3) ##wait 1s to turn on the SNSPD ##Qutag Part self.configureQutag() expparams = self.exp_parameters.widget.get() wlparams = self.wl_parameters.widget.get() self.homelaser(wlparams['start']) print('Laser Homed!') qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] self.fungen.frequency[1]=expparams['AWG Pulse Frequency'] self.fungen.voltage[1]=3.5 self.fungen.offset[1]=1.75 self.fungen.phase[1]=0 self.fungen.pulse_width[1]=expparams['AWG Pulse Width'] self.fungen.waveform[1]='PULS' self.fungen.output[1]='ON' #PATH="C:\\Data\\12.18.2020_ffpc\\"+self.exp_parameters.widget.get()['File Name']+"\\motor_scan" PATH="Q:\\Data\\5.28.2021_ffpc\\"+self.exp_parameters.widget.get()['File Name'] print('here') print('PATH: '+str(PATH)) if PATH!="Q:\\Data\\5.28.2021_ffpc\\": if (os.path.exists(PATH)): print('deleting old directory with same name') os.system('rm -rf '+str(PATH)) print('making new directory') Path(PATH).mkdir(parents=True, exist_ok=True) #os.mkdir(PATH) else: print("Specify a foldername & rerun task.") print("Task will error trying to saving data.") wlTargets=np.linspace(wlparams['start'],wlparams['stop'],expparams['# of points']) print('wlTargets: '+str(wlTargets)) for i in range(expparams['# of points']): print(i) with Client(self.laser) as client: setting=client.get('laser1:ctl:wavelength-set', float) client.set('laser1:ctl:wavelength-set', wlTargets[i]) wl=self.wm.measure_wavelength() while ((wl<wlTargets[i]-0.001) or (wl>wlTargets[i]+0.001)): print('correcting for laser drift') self.homelaser(wlTargets[i]) wl=self.wm.measure_wavelength() print('current target wavelength: '+str(wlTargets[i])) print('actual wavelength: '+str(self.wm.measure_wavelength())) time.sleep(1) print('taking data') print('current target wavelength: '+str(wlTargets[i])) print('actual wavelength: '+str(self.wm.measure_wavelength())) time.sleep(1) ##Wavemeter measurements stoparray = [] startTime = time.time() wls=[] lost = self.qutag.getLastTimestamps(True) #counter2=0 looptime=startTime while looptime-startTime < expparams['Measurement Time'].magnitude: loopstart=time.time() # get the lost timestamps lost = self.qutag.getLastTimestamps(True) # wait half a milisecond time.sleep(5*0.1) # # get thte timestamps in the last half milisecond timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps for k in range(values): # output all stop events together with the latest start event if tchannel[k] == start: synctimestamp = tstamp[k] else: stoptimestamp = tstamp[k] stoparray.append(stoptimestamp) wl=self.wm.measure_wavelength() wls.append(str(wl)) looptime+=time.time()-loopstart print('i: '+str(i)+', looptime-startTime: '+str(looptime-startTime)) # quenchfix=self.reset_quench() # if quenchfix!='YES': # print('SNSPD quenched and could not be reset') # # self.fungen.output[1]='OFF' # self.fungen.output[2]='OFF' # endloop while ((wl<wlTargets[i]-0.001) or (wl>wlTargets[i]+0.001)) and (time.time()-startTime < expparams['Measurement Time'].magnitude): print('correcting for laser drift') self.homelaser(wlTargets[i]) wl=self.wm.measure_wavelength() print('actual wavelength: '+str(wl)) #print('I am here') self.createHistogram(stoparray, timebase, bincount, expparams['AWG Pulse Repetition Period'].magnitude,str(i), wls,PATH) # self.createHistogram(stoparray, timebase, bincount,period,str(i), # wls,PATH,savefreqs) self.fungen.output[1]='OFF' self.SRS.SIMmodule_off[6] ##turn off the SNSPD power suppy after the measurement #@Task() #def spectralDiffusion_wRFsource(self): """ Task to measure spectral diffusion on timescales < T1. Assumes that 1 channel of the keysight AWG is sending a sine wave to an EOM. The amplitude of the RF drive for the EOM is set such that the sidebands have an equal amplitude to the pump beam. This tasks sweeps the frequency of the sine wave (separation of the EOM sidebands) while collecting PL, which can be used to determine the spectral diffusion linewidth since the saturation of the ions will be determined by how much the sidebands overlap with the spectral diffusion lineshape. This task is good for modulating between 1MHz and 200MHz. JDSU EOM amplifier has nonlinear performance below 1MHz (amplification increases), but the N5181A works down to 100kHz if desired. """ # get the parameters for the experiment from the widget """ SD_wRFparams=self.SD_wRFparams.widget.get() startFreq=SD_wRFparams['Start frequency'] stopFreq=SD_wRFparams['Stop frequency'] power=SD_wRFparams['RF Power'] runtime=SD_wRFparams['Runtime'] wl=SD_wRFparams['Wavelength'] points=SD_wRFparams['# of points'] period=SD_wRFparams['Period'] foldername=self.SD_wRFparams.widget.get()['File Name'] # convert the period & runtime to floats period=period.magnitude runtime=runtime.magnitude # set the amplitude of the RF signal self.source.set_RF_Power(power) # home the laser self.configureQutag() self.homelaser(wl) print('Laser Homed!') ##Qutag Part qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] PATH="D:\\Data\\"+foldername if PATH!="D:\\Data\\": if (os.path.exists(PATH)): print('deleting old directory with same name') os.system('rm -rf '+str(PATH)) print('making new directory') Path(PATH).mkdir(parents=True, exist_ok=True) # make a vector containing all the frequency setpoints for the EOM freqs=np.linspace(startFreq,stopFreq,points) # now loop through all the set frequencies of the EOM modulation # and record the PL on the qutag # turn on the RF source & set it in CW mode self.source.FM_ON() self.source.set_CW_mode() for i in range(points): #set the frequency on the RF source self.source.set_CW_Freq(freqs[i]) # want to actively stabilize the laser frequency since it can # drift on the MHz scale with Client(self.laser) as client: setting=client.get('laser1:ctl:wavelength-set', float) client.set('laser1:ctl:wavelength-set', wl) currentwl=self.wm.measure_wavelength() while ((currentwl<wl-0.001) or (currentwl>wl+0.001)): print('correcting for laser drift') self.homelaser(wl) currentwl=self.wm.measure_wavelength() print('current target wavelength: '+str(wl)) print('actual wavelength: '+str(currentwl)) time.sleep(1) print('taking data') print('current frequency: '+str(freqs[i])) print('current target wavelength: '+str(wl)) print('actual wavelength: '+str(self.wm.measure_wavelength())) time.sleep(1) stoparray = [] startTime = time.time() wls=[] savefreqs=[] lost = self.qutag.getLastTimestamps(True) looptime=startTime while looptime-startTime < runtime: loopstart=time.time() # get the lost timestamps lost = self.qutag.getLastTimestamps(True) # wait half a milisecond time.sleep(5*0.1) # get thte timestamps in the last half milisecond timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps for k in range(values): # output all stop events together with the latest start event if tchannel[k] == start: synctimestamp = tstamp[k] else: stoptimestamp = tstamp[k] stoparray.append(stoptimestamp) currentwl=self.wm.measure_wavelength() wls.append(str(currentwl)) savefreqs.append(float(freqs[i])) looptime+=time.time()-loopstart while ((currentwl<wl-0.001) or (currentwl>wl+0.001)) and (time.time()-startTime < runtime): print('correcting for laser drift') self.homelaser(wl) currentwl=self.wm.measure_wavelength() print('actual wavelength: '+str(currentwl)) self.createHistogram(stoparray, timebase, bincount,period,str(i), wls,PATH,savefreqs) # turnn off the RF output of the N5181A whenn done self.source.RF_OFF() """ @Task() def spectralDiffusion_wAWG(self): """ Task to measure spectral diffusion on timescales < T1. Uses the Agilent N5181A RF source to send a sine wave to the phase EOM. The amplitude of the RF drive for the EOM is set such that the sidebands have an equal amplitude to the pump beam (Calibrated on 11/19/20 to be 6Vpp for the JDSU phase EOM). This tasks sweeps the frequency of the sine wave (separation of the EOM sidebands) while collecting PL, which can be used to determine the spectral diffusion linewidth since the saturation of the ions will be determined by how much the sidebands overlap with the spectral diffusion lineshape. The Keysight AWG only works up to 80MHz. Could potentially modify code to use Siglent AWG which can go up to 120MHz """ self.fungen.output[1]='OFF' self.fungen.output[2]='OFF' # some initialization of the function generator self.fungen.clear_mem(1) self.fungen.clear_mem(2) self.fungen.wait() #self.fungen.output[1]='ON' self.SRS.SIMmodule_on[6] ##Turn on the power supply of the SNSPD time.sleep(1) ##wait 1s to turn on the SNSPD # get the parameters for the experiment from the widget SD_wAWGparams=self.SD_wAWGparams.widget.get() startFreq=SD_wAWGparams['Start frequency'] stopFreq=SD_wAWGparams['Stop frequency'] EOMvoltage=SD_wAWGparams['EOM voltage'] runtime=SD_wAWGparams['Runtime'] EOMchannel=SD_wAWGparams['EOM channel'] Pulsechannel=SD_wAWGparams['Pulse channel'] Pulsefreq=SD_wAWGparams['Pulse Frequency'] Pulsewidth=SD_wAWGparams['Pulse Width'] period=SD_wAWGparams['Pulse Repetition Period'] wl=SD_wAWGparams['Wavelength'] points=SD_wAWGparams['# of points'] foldername=SD_wAWGparams['File Name'] # convert the period & runtime to floats period=period.magnitude runtime=runtime.magnitude self.fungen.clear_mem(EOMchannel) self.fungen.clear_mem(Pulsechannel) self.fungen.waveform[Pulsechannel]='PULS' self.fungen.waveform[EOMchannel]='SIN' # set the sine wave driving the EOM on the other channel self.fungen.waveform[EOMchannel]='SIN' self.fungen.voltage[EOMchannel]=EOMvoltage self.fungen.offset[EOMchannel]=0 self.fungen.phase[EOMchannel]=0 self.fungen.waveform[Pulsechannel]='PULS' self.fungen.frequency[Pulsechannel]=Pulsefreq self.fungen.voltage[Pulsechannel]=3.5 self.fungen.offset[Pulsechannel]=1.75 self.fungen.phase[Pulsechannel]=0 self.fungen.pulse_width[Pulsechannel]=Pulsewidth self.fungen.output[EOMchannel]='ON' self.fungen.output[Pulsechannel]='ON' # home the laser self.configureQutag() self.homelaser(wl) print('Laser Homed!') ##Qutag Part qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] PATH="C:\\Data\\12.29.2020_ffpc\\SD0.1mW20dBatt195227GHz\\"+str(foldername) print('PATH: '+str(PATH)) if PATH!="C:\\Data\\12.29.2020_ffpc\\SD0.1mW20dBatt195227GHz\\": if (os.path.exists(PATH)): print('deleting old directory with same name') os.system('rm -rf '+str(PATH)) print('PATH: '+str(PATH)) print('making new directory') Path(PATH).mkdir(parents=True, exist_ok=True) else: print("Specify a foldername & rerun task.") print("Task will error trying to saving data.") # make a vector containing all the frequency setpoints for the EOM freqs=np.linspace(startFreq,stopFreq,points) # now loop through all the set frequencies of the EOM modulation # and record the PL on the qutag for i in range(points): self.fungen.frequency[EOMchannel]=freqs[i] # want to actively stabilize the laser frequency since it can # drift on the MHz scale with Client(self.laser) as client: setting=client.get('laser1:ctl:wavelength-set', float) client.set('laser1:ctl:wavelength-set', wl) currentwl=self.wm.measure_wavelength() while ((currentwl<wl-0.001) or (currentwl>wl+0.001)): print('correcting for laser drift') self.homelaser(wl) currentwl=self.wm.measure_wavelength() print('current target wavelength: '+str(wl)) print('actual wavelength: '+str(currentwl)) time.sleep(1) print('taking data') print('current frequency: '+str(freqs[i])) print('current target wavelength: '+str(wl)) print('actual wavelength: '+str(self.wm.measure_wavelength())) time.sleep(1) stoparray = [] startTime = time.time() wls=[] savefreqs=[] lost = self.qutag.getLastTimestamps(True) looptime=startTime while looptime-startTime < runtime: loopstart=time.time() # get the lost timestamps lost = self.qutag.getLastTimestamps(True) # wait half a milisecond time.sleep(5*0.1) # get thte timestamps in the last half milisecond timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps for k in range(values): # output all stop events together with the latest start event if tchannel[k] == start: synctimestamp = tstamp[k] else: stoptimestamp = tstamp[k] stoparray.append(stoptimestamp) currentwl=self.wm.measure_wavelength() wls.append(str(currentwl)) savefreqs.append(float(freqs[i])) looptime+=time.time()-loopstart # quenchfix=self.reset_quench() # if quenchfix!='YES': # print('SNSPD quenched and could not be reset') # self.fungen.output[1]='OFF' # self.fungen.output[2]='OFF' # endloop while ((currentwl<wl-0.001) or (currentwl>wl+0.001)) and (time.time()-startTime < runtime): print('correcting for laser drift') self.homelaser(wl) currentwl=self.wm.measure_wavelength() print('actual wavelength: '+str(currentwl)) self.createHistogram(stoparray, timebase, bincount,period,str(i),wls,PATH,savefreqs) self.fungen.output[EOMchannel]='OFF' ##turn off the AWG for both channels self.fungen.output[Pulsechannel]='OFF' self.SRS.SIMmodule_off[6] ##turn off the SNSPD power suppy after the measurement @Task() def qutagInit(self): print('qutag successfully initialized') @Element(name='Wavelength parameters') def wl_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, # ('start', {'type': float, 'default': 1535.665}), ('start', {'type': float, 'default': 1535.527}), ('stop', {'type': float, 'default': 1535.685}) # ('stop', {'type': float, 'default': 1535.61}) ] w = ParamWidget(params) return w @Element(name='Piezo scan parameters') def piezo_parameters(self): params=[ ('voltage start',{'type': float,'default':-3,'units':'V'}), ('voltage end',{'type': float,'default':3,'units':'V'}), ('scan points',{'type':int,'default':100}), ('AWG channel',{'type':int,'default':0}), ('Scale factor',{'type':float,'default':2}) ] w=ParamWidget(params) return w @Element(name='Experiment Parameters') def exp_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('# of points', {'type': int, 'default': 40}), ('Measurement Time', {'type': int, 'default': 180, 'units':'s'}), ('File Name', {'type': str}), ('AWG Pulse Repetition Period',{'type': float,'default': 2e-3,'units':'s'}), ('AWG Pulse Frequency',{'type': int,'default': 500,'units':'Hz'}), ('AWG Pulse Width',{'type': float,'default': 300e-9,'units':'s'}), ] w = ParamWidget(params) return w @Element(name='QuTAG Parameters') def qutag_params(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Start Channel', {'type': int, 'default': 0}), ('Stop Channel', {'type': int, 'default': 2}), ('Bin Count', {'type': int, 'default': 1000}), # ('Voltmeter Channel 1',{'type':int,'default':1}), ('Voltmeter Channel 2',{'type':int,'default':2}), # ('Battery Port 1',{'type':int,'default':5}), ('Battery Port 2',{'type':int,'default':6}) ] w = ParamWidget(params) return w @Element(name='Spectral diffusion experiment parameters') def SD_wAWGparams(self): """ Widget containing the parameters used in the spectral diffusion experiment. Default EOM voltage calibrated by Christina and Yizhong on 11/19/20. (rough estimate for equal amplitude sidebands) """ params=[ ('Start frequency',{'type':float,'default':3.1e6,'units':'Hz'}), ('Stop frequency',{'type':float,'default':3.3e6,'units':'Hz'}), ('EOM voltage',{'type':float,'default':6,'units':'V'}), ('Runtime',{'type':float,'default':300,'units':'s'}), ('EOM channel',{'type':int,'default':1}), ('Pulse channel',{'type':int,'default':2}), ('Pulse Repetition Period',{'type': float,'default': 0.001,'units':'s'}), ('Pulse Frequency',{'type': int,'default': 1000,'units':'Hz'}), ('Pulse Width',{'type': float,'default': 500e-9,'units':'s'}), ('Wavelength',{'type':float,'default':1535.61}), ('# of points',{'type':int,'default':2}), ('File Name',{'type':str}), ] w=ParamWidget(params) return w #@Element(name='Spectral diffusion experiment parameters') #def SD_wRFparams(self): """ Widget containing the parameters used in the spectral diffusion experiment. Default EOM voltage calibrated by Christina and Yizhong on 11/19/20. (rough estimate for equal amplitude sidebands) """ """ params=[ ('Start frequency',{'type':float,'default':5e6,'units':'Hz'}), ('Stop frequency',{'type':float,'default':200e6,'units':'Hz'}), ('RF Power',{'type':float,'default':-1.30,'units':'dBm'}), ('Runtime',{'type':float,'default':10,'units':'s'}), ('Wavelength',{'type':float,'default':1536.480}), ('Period',{'type':float,'default':100e-3,'units':'s'}), ('# of points',{'type':int,'default':40}), ('File Name',{'type':str}), ] w=ParamWidget(params) return w """ @startpulse.initializer def initialize(self): self.wm.start_data() @startpulse.finalizer def finalize(self): self.wm.stop_data() print('Lifetime measurements complete.') return @qutagInit.initializer def initialize(self): from lantz.drivers.qutools import QuTAG self.qutag = QuTAG() devType = self.qutag.getDeviceType() print('devType: '+str(devType)) if (devType == self.qutag.DEVTYPE_QUTAG): print("found quTAG!") else: print("no suitable device found - demo mode activated") print("Device timebase:" + str(self.qutag.getTimebase())) return @qutagInit.finalizer def finalize(self): return
class Rabi2(Spyrelet): requires = {'fungen': Keysight_33622A} qutag = None def configureQutag(self): qutagparams = self.qutag_params.widget.get() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] ##True = rising edge, False = falling edge. Final value is threshold voltage self.qutag.setSignalConditioning(start, self.qutag.SIGNALCOND_MISC, True, 1) self.qutag.setSignalConditioning(stop, self.qutag.SIGNALCOND_MISC, True, 0.1) self.qutag.enableChannels((start, stop)) def createHistogram(self, stoparray, timebase, bincount, period, index): hist = [0] * bincount for stoptime in stoparray: binNumber = int(stoptime * timebase * bincount / (period)) if binNumber >= bincount: continue else: hist[binNumber] += 1 out_name = "D:\\Data\\5.27.2019\\Rabi2\\Round5" np.savez(os.path.join(out_name, str(index * 50 + 200)), hist) print('Data stored under File Name: ' + self.exp_parameters.widget.get()['File Name'] + str(index)) def makePulse(self, pulse_width, i): timestep = 1e-9 self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' self.fungen.clear_mem(1) self.fungen.clear_mem(2) params = self.pulse_parameters.widget.get() period = params['period'].magnitude repeat_unit = 50e-9 buffer1 = Arbseq_Class('buffer1', timestep) buffer1.delays = [0] buffer1.heights = [0] buffer1.widths = [pulse_width] buffer1.totaltime = pulse_width buffer1.nrepeats = 0 buffer1.repeatstring = 'once' buffer1.markerstring = 'highAtStartGoLow' buffer1.markerloc = 0 buffer1.create_sequence() pulse = Arbseq_Class('pulse', timestep) pulse.delays = [0] pulse.heights = [1] pulse.widths = [pulse_width] pulse.totaltime = pulse_width pulse.nrepeats = 0 pulse.repeatstring = 'once' pulse.markerstring = 'lowAtStart' pulse.markerloc = 0 pulse.create_sequence() offset1 = Arbseq_Class('offset1', timestep) offset1.delays = [0] offset1.heights = [0] offset1.widths = [pulse_width] offset1.totaltime = pulse_width offset1.nrepeats = 0 offset1.repeatstring = 'once' offset1.markerstring = 'lowAtStart' offset1.markerloc = 0 offset1.create_sequence() dc = Arbseq_Class('dc', timestep) dc.delays = [0] dc.heights = [0] dc.widths = [params['pulse width'].magnitude] dc.totaltime = params['pulse width'].magnitude dc.repeatstring = 'repeat' dc.markerstring = 'lowAtStart' dc.markerloc = 0 width = params['pulse width'].magnitude repeats = period / width - 3 dc.nrepeats = repeats dc.create_sequence() buffer2 = Arbseq_Class('buffer2', timestep) buffer2.delays = [0] buffer2.heights = [1] buffer2.widths = [pulse_width] buffer2.totaltime = pulse_width buffer2.nrepeats = 0 buffer2.repeatstring = 'once' buffer2.markerstring = 'lowAtStart' buffer2.markerloc = 0 buffer2.create_sequence() pulse2 = Arbseq_Class('pulse2', timestep) pulse2.delays = [0] pulse2.heights = [1] pulse2.widths = [pulse_width] pulse2.totaltime = pulse_width pulse2.nrepeats = 0 pulse2.repeatstring = 'once' pulse2.markerstring = 'lowAtStart' pulse2.markerloc = 0 pulse2.create_sequence() offset2 = Arbseq_Class('offset2', timestep) offset2.delays = [0] offset2.heights = [1] offset2.widths = [pulse_width] offset2.totaltime = pulse_width offset2.nrepeats = 0 offset2.repeatstring = 'once' offset2.markerstring = 'lowAtStart' offset2.markerloc = 0 offset2.create_sequence() dc2 = Arbseq_Class('dc2', timestep) dc2.delays = [0] dc2.heights = [-1] dc2.widths = [params['pulse width'].magnitude] dc2.totaltime = params['pulse width'].magnitude dc2.repeatstring = 'repeat' dc2.markerstring = 'lowAtStart' dc2.markerloc = 0 period2 = params['period'].magnitude width2 = params['pulse width'].magnitude repeats = period2 / width2 - 3 dc2.nrepeats = repeats dc2.create_sequence() self.fungen.send_arb(buffer1, 1) self.fungen.send_arb(pulse, 1) self.fungen.send_arb(offset1, 1) self.fungen.send_arb(dc, 1) self.fungen.send_arb(buffer2, 2) self.fungen.send_arb(pulse2, 2) self.fungen.send_arb(offset2, 2) self.fungen.send_arb(dc2, 2) seq = [buffer1, pulse, offset1, dc] seq2 = [buffer2, pulse2, offset2, dc2] self.fungen.create_arbseq('twoPulse', seq, 1) self.fungen.create_arbseq('shutter', seq2, 2) self.fungen.wait() self.fungen.voltage[ 1] = params['pulse height'].magnitude + 0.000000000001 * i self.fungen.voltage[2] = 7.1 + 0.000000000001 * i self.fungen.sync() print(self.fungen.voltage[1]) self.fungen.output[2] = 'ON' self.fungen.output[1] = 'ON' @Task() def startpulse(self, timestep=1e-9): self.configureQutag() qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] pulse_width = 200e-9 expparams = self.exp_parameters.widget.get() period = self.pulse_parameters.widget.get()['period'].magnitude for i in range(expparams['# of points']): self.makePulse(pulse_width, i) stoparray = [] startTime = time.time() lost = self.qutag.getLastTimestamps(True) while time.time( ) - startTime < expparams['Measurement Time'].magnitude: time.sleep(10 * period) timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps print(values) for k in range(values): # output all stop events together with the latest start event # if tchannel[k] == start: # synctimestamp = tstamp[k] # else: # stoptimestamp = tstamp[k] stoparray.append(tstamp[k]) self.createHistogram(stoparray, timebase, bincount, period, i) pulse_width += 50e-9 self.fungen.output[1] = 'OFF' @Task() def qutagInit(self): print('qutag successfully initialized') @Element(name='Pulse parameters') def pulse_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('pulse height', { 'type': float, 'default': 3, 'units': 'V' }), ('pulse width', { 'type': float, 'default': 300e-9, 'units': 's' }), ('period', { 'type': float, 'default': 0.1, 'units': 's' }), ] w = ParamWidget(params) return w @Element(name='Experiment Parameters') def exp_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('# of points', { 'type': int, 'default': 20 }), ('Measurement Time', { 'type': int, 'default': 10, 'units': 's' }), ('File Name', { 'type': str }) ] w = ParamWidget(params) return w @Element(name='QuTAG Parameters') def qutag_params(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Start Channel', { 'type': int, 'default': 0 }), ('Stop Channel', { 'type': int, 'default': 1 }), ('Bin Count', { 'type': int, 'default': 1000 }) ] w = ParamWidget(params) return w @startpulse.initializer def initialize(self): self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' self.fungen.clear_mem(1) self.fungen.clear_mem(2) self.fungen.wait() @startpulse.finalizer def finalize(self): self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' print('Lifetime measurements complete.') return @qutagInit.initializer def initialize(self): from lantz.drivers.qutools import QuTAG self.qutag = QuTAG() devType = self.qutag.getDeviceType() if (devType == self.qutag.DEVTYPE_QUTAG): print("found quTAG!") else: print("no suitable device found - demo mode activated") print("Device timebase:" + str(self.qutag.getTimebase())) return @qutagInit.finalizer def finalize(self): return
class Lifetimewithshutter(Spyrelet): requires = {'fungen': Keysight_33622A, 'wm': Bristol_771, 'srs': SRS900} qutag = None def configureQutag(self): qutagparams = self.qutag_params.widget.get() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] ##True = rising edge, False = falling edge. Final value is threshold voltage self.qutag.setSignalConditioning(start, self.qutag.SIGNALCOND_MISC, True, 1) self.qutag.setSignalConditioning(stop, self.qutag.SIGNALCOND_MISC, True, 0.1) self.qutag.enableChannels((start, stop)) def createHistogram(self, stoparray, timebase, bincount, period, index, wls): hist = [0] * bincount for stoptime in stoparray: binNumber = int(stoptime * timebase * bincount / (period)) if binNumber >= bincount: print('lost: ' + str(stoptime)) else: hist[binNumber] += 1 out_name = "D:\\Data\\5.15.2019\\T1" np.savez( os.path.join( out_name, self.exp_parameters.widget.get()['File Name'] + str(index)), hist, wls) print('Data stored under File Name: ' + self.exp_parameters.widget.get()['File Name'] + str(index)) @Task() def startpulse(self, timestep=1e-9): self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' self.fungen.clear_mem(1) self.fungen.clear_mem(2) self.fungen.wait() params = self.pulse_parameters.widget.get() tau = params['start tau'] period = params['period'].magnitude chn1pulse = Arbseq_Class('chn1pulse', timestep) chn1pulse.delays = [0] chn1pulse.heights = [1] chn1pulse.widths = [params['pulse width'].magnitude] chn1pulse.totaltime = params['pulse width'].magnitude chn1pulse.nrepeats = 0 chn1pulse.repeatstring = 'once' chn1pulse.markerstring = 'highAtStartGoLow' chn1pulse.markerloc = 0 chn1pulsewidth = params['pulse width'].magnitude chn1pulse.create_sequence() chn1dc = Arbseq_Class('chn1dc', timestep) chn1dc.delays = [0] chn1dc.heights = [0] chn1dc.widths = [params['repeat unit'].magnitude] chn1dc.totaltime = params['repeat unit'].magnitude chn1dc.repeatstring = 'repeat' chn1dc.markerstring = 'lowAtStart' chn1dc.markerloc = 0 chn1dcrepeats = int((tau.magnitude - params['pulse width'].magnitude) / (params['repeat unit'].magnitude)) chn1dc.nrepeats = chn1dcrepeats chn1dcwidth = (params['repeat unit'].magnitude) * chn1dcrepeats print(tau.magnitude, params['pulse width'].magnitude, chn1dcrepeats) chn1dc.create_sequence() chn1pulse2 = Arbseq_Class('chn1pulse2', timestep) chn1pulse2.delays = [0] chn1pulse2.heights = [1] chn1pulse2.widths = [params['pulse width'].magnitude] chn1pulse2.totaltime = params['pulse width'].magnitude chn1pulse2width = params['pulse width'].magnitude chn1pulse2.nrepeats = 0 chn1pulse2.repeatstring = 'once' chn1pulse2.markerstring = 'lowAtStart' chn1pulse2.markerloc = 0 chn1pulse2.create_sequence() chn1pulse3 = Arbseq_Class('chn1pulse3', timestep) chn1pulse3.delays = [0] chn1pulse3.heights = [0] chn1pulse3.widths = [params['repeat unit'].magnitude] chn1pulse3.totaltime = params['repeat unit'].magnitude chn1pulse3width = 400e-9 chn1pulse3.nrepeats = 400e-9 / params['repeat unit'].magnitude chn1pulse3.repeatstring = 'repeat' chn1pulse3.markerstring = 'lowAtStart' chn1pulse3.markerloc = 0 chn1pulse3.create_sequence() chn1dc2 = Arbseq_Class('chn1dc2', timestep) chn1dc2.delays = [0] chn1dc2.heights = [0] chn1dc2.widths = [params['repeat unit'].magnitude] chn1dc2.totaltime = params['repeat unit'].magnitude chn1dc2.repeatstring = 'repeat' chn1dc2.markerstring = 'lowAtStart' chn1dc2repeats = int( (params['period'].magnitude - tau.magnitude - params['pulse width'].magnitude - chn1pulse3width) / (params['repeat unit'].magnitude)) chn1dc2.nrepeats = chn1dc2repeats chn1dc2.markerloc = 0 print((chn1dc2repeats * params['repeat unit'].magnitude) + tau.magnitude + params['pulse width'].magnitude) chn1dc2.create_sequence() chn2pulse1 = Arbseq_Class('chn2pulse1', timestep) chn2pulse1.delays = [0] chn2pulse1.heights = [1] # chn2pulse1width = pulsewidth+pulse2width+dcwidth chn2pulse1.widths = [params['pulse width'].magnitude] chn2pulse1.totaltime = params['pulse width'].magnitude chn2pulse1.nrepeats = 0 chn2pulse1.repeatstring = 'once' chn2pulse1.markerstring = 'highAtStartGoLow' chn2pulse1.markerloc = 0 chn2pulse1.create_sequence() chn2dc1 = Arbseq_Class('chn2dc1', timestep) chn2dc1.delays = [0] chn2dc1.heights = [1] chn2dc1.widths = [params['repeat unit'].magnitude] chn2dc1.totaltime = params['repeat unit'].magnitude chn2dc1.repeatstring = 'repeat' chn2dc1.markerstring = 'lowAtStart' chn2dc1.markerloc = 0 chn2dc1repeats = int( (tau.magnitude - params['pulse width'].magnitude) / (params['repeat unit'].magnitude)) chn2dc1.nrepeats = chn2dc1repeats chn2dc1width = (params['repeat unit'].magnitude) * chn2dc1repeats chn2dc1.create_sequence() chn2pulse2 = Arbseq_Class('chn2pulse2', timestep) chn2pulse2.delays = [0] chn2pulse2.heights = [1] chn2pulse2.widths = [params['pulse width'].magnitude] chn2pulse2.totaltime = params['pulse width'].magnitude chn2pulse2width = params['pulse width'].magnitude chn2pulse2.nrepeats = 0 chn2pulse2.repeatstring = 'once' chn2pulse2.markerstring = 'lowAtStart' chn2pulse2.markerloc = 0 chn2pulse2.create_sequence() chn2pulse3 = Arbseq_Class('chn2pulse3', timestep) chn2pulse3.delays = [0] chn2pulse3.heights = [1] chn2pulse3.widths = [params['repeat unit'].magnitude] chn2pulse3.totaltime = params['repeat unit'].magnitude chn2pulse3width = 400e-9 chn2pulse3.nrepeats = 400e-9 / params['repeat unit'].magnitude chn2pulse3.repeatstring = 'repeat' chn2pulse3.markerstring = 'lowAtStart' chn2pulse3.markerloc = 0 chn2pulse3.create_sequence() chn2dc2 = Arbseq_Class('chn2dc2', timestep) chn2dc2.delays = [0] chn2dc2.heights = [-1] chn2dc2.widths = [params['repeat unit'].magnitude] chn2dc2.totaltime = params['repeat unit'].magnitude chn2dc2.repeatstring = 'repeat' chn2dc2.markerstring = 'lowAtStart' chn2dc2repeats = int( (params['period'].magnitude - tau.magnitude - params['pulse width'].magnitude - chn2pulse3width) / (params['repeat unit'].magnitude)) chn2dc2.nrepeats = chn2dc2repeats chn2dc2.markerloc = 0 print((chn2dc2repeats * params['repeat unit'].magnitude) + tau.magnitude + params['pulse width'].magnitude) chn2dc2.create_sequence() self.fungen.send_arb(chn1pulse, 1) self.fungen.send_arb(chn1dc, 1) self.fungen.send_arb(chn1pulse2, 1) self.fungen.send_arb(chn1pulse3, 1) self.fungen.send_arb(chn1dc2, 1) self.fungen.send_arb(chn2pulse1, 2) self.fungen.send_arb(chn2dc1, 2) self.fungen.send_arb(chn2pulse2, 2) self.fungen.send_arb(chn2pulse3, 2) self.fungen.send_arb(chn2dc2, 2) seq = [chn1pulse, chn1dc, chn1pulse2, chn1pulse3, chn1dc2] seq2 = [chn2pulse1, chn2dc1, chn2pulse2, chn2pulse3, chn2dc2] self.fungen.create_arbseq('twoPulse', seq, 1) self.fungen.create_arbseq('shutter', seq2, 2) self.fungen.wait() self.fungen.voltage[ 1] = params['pulse height'].magnitude + 0.000000000001 self.fungen.voltage[2] = 7.0 + 0.0000000000001 print(self.fungen.voltage[1], self.fungen.voltage[2]) self.fungen.output[1] = 'ON' self.fungen.output[2] = 'ON' #self.fungen.output[2] = 'OFF' self.fungen.trigger_delay(1, 400e-9) self.fungen.sync() self.srs.module_reset[5] self.srs.SIM928_voltage[5] = params['srs bias'].magnitude self.srs.SIM928_on[5] self.configureQutag() qutagparams = self.qutag_params.widget.get() lost = self.qutag.getLastTimestamps(True) # clear Timestamp buffer stoptimestamp = 0 synctimestamp = 0 bincount = qutagparams['Bin Count'] timebase = self.qutag.getTimebase() start = qutagparams['Start Channel'] stop = qutagparams['Stop Channel'] expparams = self.exp_parameters.widget.get() for i in range(expparams['# of points']): ##Wavemeter measurements stoparray = [] startTime = time.time() wls = [] lost = self.qutag.getLastTimestamps(True) while time.time( ) - startTime < expparams['Measurement Time'].magnitude: lost = self.qutag.getLastTimestamps(True) time.sleep(30 * period) timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps for k in range(values): # output all stop events together with the latest start event if tchannel[k] == start: synctimestamp = tstamp[k] else: stoptimestamp = tstamp[k] stoparray.append(stoptimestamp) wls.append(str(self.wm.measure_wavelength())) self.createHistogram(stoparray, timebase, bincount, period, i, wls) print('Approx. ' + str( int((expparams['# of points'] - i) / expparams['Measurement Time'].magnitude)) + ' min left') #self.fungen.voltage[2] = self.fungen.voltage[2].magnitude + 2*dcparams['DC step size'].magnitude self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' startTime = time.time() startWl = self.wm.measure_wavelength() stoparray = [] lastwls = [] while time.time( ) - startTime < expparams['Measurement Time'].magnitude: time.sleep(period) timestamps = self.qutag.getLastTimestamps(True) tstamp = timestamps[0] # array of timestamps tchannel = timestamps[1] # array of channels values = timestamps[2] # number of recorded timestamps for k in range(values): # output all stop events together with the latest start event if tchannel[k] == start: synctimestamp = tstamp[k] else: stoptimestamp = tstamp[k] stoparray.append(stoptimestamp) lastwls.append(str(self.wm.measure_wavelength())) self.createHistogram(stoparray, timebase, bincount, period, 'bg', lastwls) @Task() def qutagInit(self): print('qutag successfully initialized') @Element(name='Pulse parameters') def pulse_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('pulse height', { 'type': float, 'default': 3, 'units': 'V' }), ('pulse width', { 'type': float, 'default': 1000e-9, 'units': 's' }), ('period', { 'type': float, 'default': 0.1, 'units': 's' }), ('repeat unit', { 'type': float, 'default': 50e-9, 'units': 's' }), ('start tau', { 'type': float, 'default': 2e-6, 'units': 's' }), ('stop tau', { 'type': float, 'default': 10e-6, 'units': 's' }), ('step tau', { 'type': float, 'default': 1e-6, 'units': 's' }), ('srs bias', { 'type': float, 'default': 1.2, 'units': 'V' }) ] w = ParamWidget(params) return w @Element(name='Experiment Parameters') def exp_parameters(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('# of points', { 'type': int, 'default': 10 }), ('Measurement Time', { 'type': int, 'default': 300, 'units': 's' }), ('File Name', { 'type': str }) ] w = ParamWidget(params) return w @Element(name='QuTAG Parameters') def qutag_params(self): params = [ # ('arbname', {'type': str, 'default': 'arbitrary_name'}),, ('Start Channel', { 'type': int, 'default': 0 }), ('Stop Channel', { 'type': int, 'default': 1 }), ('Bin Count', { 'type': int, 'default': 1000 }) ] w = ParamWidget(params) return w @startpulse.initializer def initialize(self): self.wm.start_data() self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' self.fungen.clear_mem(1) self.fungen.clear_mem(2) self.fungen.wait() @startpulse.finalizer def finalize(self): self.wm.stop_data() self.fungen.output[1] = 'OFF' self.fungen.output[2] = 'OFF' print('Lifetime measurements complete.') return @qutagInit.initializer def initialize(self): from lantz.drivers.qutools import QuTAG self.qutag = QuTAG() devType = self.qutag.getDeviceType() if (devType == self.qutag.DEVTYPE_QUTAG): print("found quTAG!") else: print("no suitable device found - demo mode activated") print("Device timebase:" + str(self.qutag.getTimebase())) return @qutagInit.finalizer def finalize(self): return