8-ID
  8-ID Beamline logbook mirror  Not logged in ELOG logo
Message ID: 609     Entry time: Wed Dec 5 10:04:22 2018
Author: Joe Strzalka 
Type: 8-ID-E 
Category: Controls 
Subject: Keithley 2400 sourcemeter sweep scan support 
For description of use and EPICS support see entry 528/ mirror 528.

In October 2018, the Nie group (LANL) wanted to apply linear staircase sweep scans on their samples with in situ GIWAXS measurements (see the Keithley 2400 Series Sourcemeter manual, Chapter 10, Sweep Operation, especially Table 10-4, "Staircase sweep programming example"). Initial support and asyn communications were inadequate for sweep scan operations, because it limited readout of the output to 40 characters at a time. Max Wyman of BCDA modified the support on ioc8idd to support waveform output while continuing to support the existing GUI. Attachment 1 is Max's documentation of this effort and some description of how to use the new support. Max's comment in email (2018.12.04):
"I've updated my documentation -- the only thing to note is that when getting the data, you must wait until the scan is complete, i.e. you'll need a delay between setting the PV's PROC to 1 and the caget of the PV.
In your python script, you might be able to check PV's timestamp as an indicator of when the scan is complete.

"I also found another function for automatically turning on/off the output ("SOUR:CLE:AUTO ON"), I've added it to the script to replace the ":OUTP ON" command. I've attached an updated setup script."

Our operating mode for the sweep scans is to execute a shell script that executes a series of caput commands to the asyn communications to set the parameters of the sweep scan (attachment 2 -- slightly modified from the setup script Max mentioned in his comments). Then we execute a shell script (attachment 3 -- changed extension from .py to .txt for convenience) to execute python code to run the sweep scan and save the data as 2-column ascii data to the filename given as the command line argument.
Usage:
testnewsweep.py testfilename

When different resistors are applied as loads, the two scripts generate data plotted in Attachment 4.

Future work:
* User experiment will require signal averaging over many cycles of sweep scans -- see attachment 5, a shell script that sets parameters for the Keithely's built-in filtering capabilities for signal averaging
* Update script to check PV timestamp so that PV data read does not happen until sweep is complete -- see attachment 6
* Extend python code to plot the data
* Include some metadata into the file?
Attachment 1: ioc8idd_update_181203.pdf  52 kB
Attachment 2: sweepsetup_newer  1 kB  | Hide | Hide all
#! /bin/csh
alias sleep1 'sleep 1'
caput 8ide:asyn_17.TMOD "Write"
sleep1    

caput 8ide:asyn_17.AOUT "*RST"
sleep1    
caput 8ide:asyn_17.AOUT ":SENS:FUNC:CONC OFF"
sleep1
caput 8ide:asyn_17.AOUT ":SOUR:FUNC VOLT"
sleep1
caput 8ide:asyn_17.AOUT ":SENS:FUNC 'CURR:DC'"
sleep1
caput 8ide:asyn_17.AOUT ":SENS:CURR:PROT 100E-6"
sleep1
caput 8ide:asyn_17.AOUT ":SOUR:VOLT:START -4.0"
sleep1
caput 8ide:asyn_17.AOUT ":SOUR:VOLT:STOP 4.0"
sleep1
caput 8ide:asyn_17.AOUT ":SOUR:VOLT:STEP 10E-2"
sleep1
caput 8ide:asyn_17.AOUT ":SOUR:VOLT:MODE SWE"
sleep1
caput 8ide:asyn_17.AOUT ":SOUR:SWE:RANG AUTO"
sleep1
caput 8ide:asyn_17.AOUT ":SOUR:SWE:SPAC LIN"
sleep1
caput 8ide:asyn_17.AOUT ":SOUR:SWE:POIN 81"
sleep1
caput 8ide:asyn_17.AOUT ":TRIG:COUN 81"
sleep1
caput 8ide:asyn_17.AOUT ":SOUR:DEL 0.1"
sleep1
#caput 8ide:asyn_17.AOUT ":OUTP ON"
# The following line should turn the output on/off automatically 
# when a sweep is initiated and is meant to replace the ":OUTP ON" command
caput 8ide:asyn_17.AOUT "SOUR:CLE:AUTO ON"     
sleep1 
caput 8ide:asyn_17.AOUT ":FORM:ELEM VOLT,CURR"
sleep1


Attachment 3: testnewsweep_py.txt  1 kB  | Hide | Hide all
#!/APSshare/anaconda3/x86_64/bin/python

import epics
from time import sleep
import sys
arg2 = sys.argv
outpath = "/home/8-id-g/2018-3/tsai201810p/device/"
outfile = outpath + arg2[1]

sweepit = 1
plotit = 0


if sweepit : 
	epics.caput("8ide:2400:ReadArray.PROC", 1)
	# wait for sweep to complete -- hack with fixed delay. Is there a condition to test so we know when sweep is complete?
	print('sweep in progress')
	sleep(20)
	# close fast shutter
	epics.caput("8idg:Unidig1Bo13",1)


# read in the sweep data
indata = epics.caget("8ide:2400:ReadArray");
# read in number of non-zero elements.  
num2pts = epics.caget("8ide:2400:ReadArray.NORD");
print(num2pts);  # development
# Why doesn't this agree?   For 41 pts (82 values), returns 752.
print(sys.getsizeof(indata))  # development

print(indata)  # development

f = open(outfile,"w")
counter = 0
for i in indata :

	#print(i)
	counter=counter+1;
	if (counter % 2 == 1):
		try:
			VOLT = float(i)
		except:
			VOLT = "NaN"
			print("Error converting string to float./n")
	else :
		try:
			CURR = float(i)
		except:
			CURR = "NaN"
			print("Error converting string to float./n")

		print("VOLTAGE=",VOLT," CURRENT=",CURR)
		f.write('{0:>6} {1}\n'.format(VOLT ,CURR))

f.close()
print(arg2[1])

if plotit :
		print("Plot the data here.")
Attachment 4: Keithley2400output.png  29 kB  | Hide | Hide all
Keithley2400output.png
Attachment 5: sweepsetup_filter  760 Bytes  Uploaded Fri Dec 7 11:45:07 2018  | Hide | Hide all
#! /bin/csh
# Set up filter (singal averaging) for sweep scan of Keithely 2400 sourcemeter
# see Keithley 2400 Series Sourcemeter manual, Table 10-4, Staircase Sweep Programming example
# delay will be needed to process each asyn input
alias sleep1 'sleep 1'
# Put asyn comms in Write mode
caput 8ide:asyn_17.TMOD "Write"
sleep1    
# next line chooses filter: REPeating filter averages signal value for each source value
#                           MOVing filter averages together signal for different source values
caput 8ide:asyn_17.AOUT ":SENS:AVER:TCON REP"
sleep1
# next line sets how many values to average together
caput 8ide:asyn_17.AOUT ":SENS:AVER:COUN 10"
sleep1
# next line turns averaging ON or OFF
caput 8ide:asyn_17.AOUT ":SENS:AVER ON"
sleep1
Attachment 6: sweep_testdelay.py  1 kB  Uploaded Fri Dec 7 11:46:25 2018  | Hide | Hide all
#!/APSshare/anaconda3/x86_64/bin/python

import epics
from time import sleep
import sys
arg2 = sys.argv
outpath = "/home/8-id-g/2018-3/tsai201810p/device/"
outfile = outpath + arg2[1]

sweepit = 1
plotit = 0
verbose = 0
countup = 1

# see documentation for PyEpics release 3.2.4
# https://www.slac.stanford.edu/grp/ssrl/spear/epics/extensions/pyepics/pyepics.pdf
# section 3.1 "The PV class", 3.1.1 for the get() method and 3.1.2 for the timestamp attribute
numelem = epics.PV("8ide:2400:ReadArray.NORD");
data2400 = epics.PV("8ide:2400:ReadArray");

print( data2400.get()[1] )
print( data2400.timestamp)

oldtime = data2400.timestamp;
print("oldtime : ", oldtime)

if sweepit :
	
	data2400.get();
	checktime = data2400.timestamp;
	 
	epics.caput("8ide:2400:ReadArray.PROC", 1)
	# wait for sweep to complete -- hack with fixed delay. Is there a condition to test so we know when sweep is complete?
	print('sweep in progress')
	
	sweepct = 0;
	while (checktime == oldtime) :
		sleep(0.5);
		sweepct=sweepct+1;
		print('waiting for sweep: ', sweepct)
		data2400.get()
		checktime = data2400.timestamp;
		if countup:
			print('checktime: ', checktime);	
	
	# close fast shutter
	epics.caput("8idg:Unidig1Bo13",1)

# read in the sweep data
indata = epics.caget("8ide:2400:ReadArray");
# read in number of non-zero elements.  
num2pts = epics.caget("8ide:2400:ReadArray.NORD");
print(num2pts);  # development
# Why doesn't this agree?   For 41 pts (82 values), returns 752.
print(sys.getsizeof(indata))  # development

if verbose:
	print(indata)  # development

f = open(outfile,"w")
counter = 0
for i in indata :

	#print(i)
	counter=counter+1;
	if (counter % 2 == 1):
		try:
			VOLT = float(i)
		except:
			VOLT = "NaN"
			print("Error converting string to float./n")
	else :
		try:
			CURR = float(i)
		except:
			CURR = "NaN"
			print("Error converting string to float./n")
		if verbose :
			print("VOLTAGE=",VOLT," CURRENT=",CURR)
		f.write('{0:>6} {1}\n'.format(VOLT ,CURR))

f.close()
print(arg2[1])

if plotit :
		print("Plot the data here.")
ELOG V3.1.4-395e101