Beispiel #1
0
def runExperiment():
    global my_SRS

    #Plotting setup, xs is the frequencies, ys is the average intensities for the signal, bys is avg intensities for background
    style.use("fivethirtyeight")
    fig = plt.figure()
    ax1 = fig.add_subplot(1, 1, 1)
    xs = []
    ys = []
    bys = []

    initPB()

    #initiate RF generator with channel and model type; set amplitude
    my_SRS = SRSctl.initSRS(27, 'SG386')
    SRSctl.setSRS_RFAmplitude(my_SRS, .14, units="Vpp")

    #set test frequency and modulation
    SRSctl.setSRS_Freq(my_SRS, config['START_FREQUENCY'], 'GHz')
    SRSctl.setupSRSmodulation(my_SRS, config['sequence_name'])

    #Get the instruction Array
    instructionArray = PBctl.programPB(config['sequence_name'],
                                       [config['t_AOM']])
    print(instructionArray)

    #Program the PulseBlaster
    status = pb_start_programming(PULSE_PROGRAM)
    for i in range(0, len(instructionArray)):
        PBctl.pb_inst_pbonly(instructionArray[i][0], instructionArray[i][1],
                             instructionArray[i][2], instructionArray[i][3])
    pb_stop_programming()

    #Configure the DAQ
    global task
    task = DAQ.configureDAQ(ESR.Nsamples)

    #turn on the microwave excitation - changed the sequence here, zhao, 02/24/2020
    SRSctl.enableSRS_RFOutput(my_SRS)

    global f
    #Set f to be the start frequency
    f = config['START_FREQUENCY']

    #start the pulse blaster  # you can start pulseblaster at the beginning the experiment and turn it off until everything is done -- Zhao, 6/11/2020
    pb_start()

    #Throw away the first NThrow samples to get the photodiode warmed up
    for i in range(NThrow):
        DAQ.readDAQ(task, ESR.Nsamples * 2, 10)

    #Begin the animation - All of the experiment work is done in the animate function. FuncAnimation runs animate in a loop automatically
    ani = animation.FuncAnimation(
        fig, animate, fargs=(xs, ys, bys), interval=200
    )  ## not sure if this is the best approach. maybe try to use the "frames" variable for this function -- Zhao, 6/11/2020
def runExperiment(expConfigFile):
# This function runs the experiment with input parameters configured by the user in the experiment config file (e.g. ESRconfig, Rabiconfig, etc) and plots and saves the data.
	try:
		'''Runs the experiment.'''
		expCfg = import_module(expConfigFile)
		expCfg.N_scanPts = len(expCfg.scannedParam) #protection against non-integer user inputs for N_scanPts.
		validateUserInput(expCfg)
		#Check if save directory exists, and, if not, creates a "Saved Data" folder in the current directory, where all data will be saved.
		if not (isdir(expCfg.savePath)):
			 makedirs(expCfg.savePath)
			 print('Warning: Save directory did not exist, creating folder named Saved_Data in the working directory. Data will be saved to this directory.')
		
		#Initialise SRS and program PulseBlaster
		SRS = SRSctl.initSRS(conCfg.GPIBaddr,conCfg.modelName)
		SRSctl.setSRS_RFAmplitude(SRS,expCfg.microwavePower)
		SRSctl.setupSRSmodulation(SRS,expCfg.sequence)
		sequenceArgs = expCfg.updateSequenceArgs()
		expParamList = expCfg.updateExpParamList()
		if expCfg.sequence != 'ESRseq':
			SRSctl.setSRS_Freq(SRS, expCfg.microwaveFrequency)
			#Program PB
			seqArgList = [expCfg.scannedParam[-1]]
			seqArgList.extend(sequenceArgs)
			instructionArray=PBctl.programPB(expCfg.sequence,seqArgList)
		else:
			SRSctl.setSRS_Freq(SRS, expCfg.scannedParam[0])
			#Program PB
			instructionArray=PBctl.programPB(expCfg.sequence,sequenceArgs)
		SRSctl.enableSRS_RFOutput(SRS)
					
		#Configure DAQ
		DAQclosed = False
		DAQtask = DAQctl.configureDAQ(expCfg.Nsamples)
			
		if expCfg.plotPulseSequence:
		# Plot sequence
			plt.figure(0)
			[t_us,channelPulses,yTicks]=seqCtl.plotSequence(instructionArray,expCfg.PBchannels)
			for channel in channelPulses:
				plt.plot(t_us, list(channel))
				plt.yticks(yTicks)
				plt.xlabel('time (us)')
				plt.ylabel('channel')
				# If we are plotting a Rabi with pulse length <5*t_min, warn the user in the sequence plot title that the instructions sent to the PulseBlaster microwave channel are for a 5*t_min pulse, but that the short pulse flags are simultaneously pulsed to produce the desired pulse length
				if expCfg.sequence == 'RabiSeq' and (seqArgList[0]<(5*t_min)):
					plt.title('Pulse Sequence plot (at last scan point). Close to proceed with experiment...\n(note: we plot the instructions sent to the PulseBlaster (PB) for each channel. For microwave pulses<',5*t_min,'ns, the microwave\nchannel (PB_MW) is instructed to pulse for',5*t_min,'ns, but the short-pulse flags of the PB are pulsed simultaneously (not shown) to\nproduce the desired output pulse length at PB_MW. This can be verified on an oscilloscope.)', fontsize=7)
				else:
					plt.title('Pulse Sequence plot (at last scan point)\n close to proceed with experiment...')
			plt.show()
		
		#Initialize data arrays
		meanSignalCurrentRun = np.zeros(expCfg.N_scanPts)
		meanBackgroundCurrentRun = np.zeros(expCfg.N_scanPts)
		contrastCurrentRun = np.zeros(expCfg.N_scanPts)
		signal = np.zeros([expCfg.N_scanPts,expCfg.Navg])
		background = np.zeros([expCfg.N_scanPts,expCfg.Navg])
		contrast = np.zeros([expCfg.N_scanPts,expCfg.Navg])

		#Run experiment
		for i_run in range (0,expCfg.Navg):
			print('Run ',i_run+1,' of ',expCfg.Navg)
			if expCfg.randomize:
				if i_run>0:
					shuffle(expCfg.scannedParam)
			for i_scanPoint in range (0, expCfg.N_scanPts):
				#setup next scan iteration (e.g. for ESR experiment, change microwave frequency; for T2 experiment, reprogram pulseblaster with new delay)
				if expCfg.sequence == 'ESRseq':
					SRSctl.setSRS_Freq(SRS, expCfg.scannedParam[i_scanPoint])
				else:
					seqArgList[0] = expCfg.scannedParam[i_scanPoint]
					instructionArray= PBctl.programPB(expCfg.sequence,seqArgList)
				print('Scan point ',i_scanPoint+1,' of ',expCfg.N_scanPts)
				
				#read DAQ
				cts=DAQctl.readDAQ(DAQtask,2*expCfg.Nsamples,expCfg.DAQtimeout)
		
				#Extract signal and background counts
				sig = cts[0::2]
				bkgnd = cts[1::2]
							
				#Take average of counts
				meanSignalCurrentRun[i_scanPoint] = np.mean(sig)
				meanBackgroundCurrentRun[i_scanPoint] = np.mean(bkgnd)
				if expCfg.shotByShotNormalization:
					contrastCurrentRun[i_scanPoint] = np.mean(calculateContrast(expCfg.contrastMode,sig,bkgnd))
				else:
					contrastCurrentRun[i_scanPoint] = calculateContrast(expCfg.contrastMode,meanSignalCurrentRun[i_scanPoint],meanBackgroundCurrentRun[i_scanPoint])
				if i_run==0:
					if expCfg.livePlotUpdate:
						xValues=expCfg.scannedParam[0:i_scanPoint+1]
						plt.plot([x/expCfg.plotXaxisUnits for x in xValues],contrastCurrentRun[0:i_scanPoint+1], 'b-')
						plt.ylabel('Contrast')
						plt.xlabel(expCfg.xAxisLabel)
						plt.draw()
						plt.pause(0.0001)
					
					# Save data at intervals dictated by saveSpacing_inPulseLengthPts and at final delay point
					if (i_scanPoint%expCfg.saveSpacing_inScanPts == 0) or (i_scanPoint==expCfg.N_scanPts-1):
						data = np.zeros([i_scanPoint+1,3])
						data[:,0] = expCfg.scannedParam[0:i_scanPoint+1]
						data[:,1] = meanSignalCurrentRun[0:i_scanPoint+1]
						data[:,2] = meanBackgroundCurrentRun[0:i_scanPoint+1]
						dataFile = open(expCfg.dataFileName, 'w')
						for line in data:
							dataFile.write("%.0f\t%.8f\t%.8f\n" % tuple(line))
						paramFile = open(expCfg.paramFileName, 'w')
						expParamList[1] = i_scanPoint+1
						paramFile.write(expCfg.formattingSaveString % tuple(expParamList))
						dataFile.close()
						paramFile.close()
					
			#Sort current run counts in order of increasing delay
			dataCurrentRun = np.transpose(np.array([expCfg.scannedParam,meanSignalCurrentRun,meanBackgroundCurrentRun,contrastCurrentRun]))
			sortingIndices = np.argsort(dataCurrentRun[:,0])
			dataCurrentRun = dataCurrentRun[sortingIndices]
			#Fill in current run data:
			sortedScanParam = dataCurrentRun[:,0]
			signal[:,i_run] = dataCurrentRun[:,1]
			background[:,i_run] = dataCurrentRun[:,2]
			contrast[:,i_run] = dataCurrentRun[:,3]
			
			#Update quantities for plotting
			updatedSignal = np.mean(signal[:,0:i_run+1],1)
			updatedBackground = np.mean(background[:,0:i_run+1],1)
			updatedContrast = np.mean(contrast[:,0:i_run+1],1)
			
			#Update plot:
			if expCfg.livePlotUpdate: 
				plt.clf()
			plt.plot([x/expCfg.plotXaxisUnits for x in sortedScanParam] ,updatedContrast,'b-')
			plt.ylabel('Contrast')
			plt.xlabel(expCfg.xAxisLabel)
			plt.draw()
			plt.pause(0.001)
			
			# Save data at intervals dictated by saveSpacing_inAverages and after final scan
			if (i_run%expCfg.saveSpacing_inAverages == 0) or (i_run==expCfg.Navg-1):
				data = np.zeros([expCfg.N_scanPts,3])
				data[:,0] = sortedScanParam
				data[:,1] = updatedSignal
				data[:,2] = updatedBackground
				dataFile = open(expCfg.dataFileName, 'w')
				for item in data:
					dataFile.write("%.0f\t%.8f\t%.8f\n" % tuple(item))
				paramFile = open(expCfg.paramFileName, 'w')
				expParamList[3] = i_run+1
				paramFile.write(expCfg.formattingSaveString % tuple(expParamList))
				dataFile.close()
				paramFile.close()
		
		#Turn off SRS output
		SRSctl.disableSRS_RFOutput(SRS)

		#Close DAQ task:
		DAQctl.closeDAQTask(DAQtask)
		DAQclosed=True
		plt.show()
	except	KeyboardInterrupt:
		print('User keyboard interrupt. Quitting...')
		sys.exit()
	finally:
		if 'SRS' in vars():	
			#Turn off SRS output
			SRSctl.disableSRS_RFOutput(SRS)
		if ('DAQtask' in vars()) and  (not DAQclosed):
			#Close DAQ task:
			DAQctl.closeDAQTask(DAQtask)
			DAQclosed=True
# Configure the core clock
pb_core_clock(500.0)

#Get the first instruction Array
instructionArray = PBctl.programPB(sequence_name, sequenceArgs)
print(instructionArray)

#Program the PulseBlaster
status = pb_start_programming(PULSE_PROGRAM)
for i in range(0, len(instructionArray)):
    PBctl.pb_inst_pbonly(instructionArray[i][0], instructionArray[i][1],
                         instructionArray[i][2], instructionArray[i][3])
pb_stop_programming()

#Configure the DAQ
task = DAQ.configureDAQ(RABI.Nsamples)

#turn on the microwave excitation - changed the sequence here, zhao, 02/24/2020
#SRSctl.enableSRS_RFOutput(my_SRS) UNCOMMENT THIS!

#Set t to be the start time and initalize the average variable to 0
t = START_LENGTH
average = 0

#Throw away the first NThrow samples to get the photodiode warmed up
for i in range(NThrow):
    pb_start()
    DAQ.readDAQ(task, RABI.Nsamples * 2, 10)
    pb_stop()

Beispiel #4
0
		print('Error: startDelay is too short. Please set startDelay>',5*t_min,'ns.')
		sys.exit()
	if startDelay%(t_min):
		startDelay = t_min*round(startDelay/t_min)
		print('Warning: startDelay is not a multiple of',t_min,'ns. Rounding...\nstartDelay now set to:',startDelay,'ns.')
		t_readoutDelay = np.linspace(startDelay,endDelay, N_scanPts, endpoint=True) 
	stepSize = t_readoutDelay[1]-t_readoutDelay[0]
	if (stepSize%t_min):
				roundedStepSize = t_min*round(stepSize/t_min)
				endDelay  = (N_scanPts-1)*roundedStepSize + startDelay 
				print('Warning: requested time step is ',stepSize,'ns, which is not an integer multiple of ',t_min,'ns. Rounding step size to the nearest multiple of ',t_min,':\nStep size is now',roundedStepSize,'.\nstartDelay=',startDelay,' and \nendDelay=',endDelay)
				t_readoutDelay = np.linspace(startDelay,endDelay, N_scanPts, endpoint=True)

	#Configure DAQ
	DAQclosed = False
	DAQtask = DAQctl.configureDAQ(Nsamples)

	fluorescence = np.zeros(N_scanPts)
	if plotPulseSequence:
		instructionArray= PBctl.programPB('optimReadoutSeq', [t_readoutDelay[-1],t_AOM])
		[t_us,channelPulses,yTicks]=seqCtl.plotSequence(instructionArray,PBchannels)
		plt.figure(0)
		for channel in channelPulses:
			plt.plot(t_us, list(channel))
		plt.yticks(yTicks)
		plt.xlabel('time (us)')
		plt.ylabel('channel')
		plt.title('Pulse Sequence plot (at last scan point)')

	#Run readout delay scan:
	for i in range (0, N_scanPts):