#%TITLE% FLIP.MAC Flip Magnet
#%NAME%
# Flip magnet polarity during scans.
#%CATEGORY% Other hardware, Tools
#%DESCRIPTION%
# Those macros add to standard scan facility (motor scans and time scan), the possibility of flipping magnet polarity or whatever at counting. The data are plotted in additional windows and saved to standard DATAFILE in additional columns.
#%EXAMPLE%
#%DL%
#%DT%flipsetup; flipcounterselect det; flipstyle 4; fliphdwrelay ID16/Relay/80 %DD% initialisation and setup.
#%DT%flip ascan m0 0 10 10 1 %DD% flip scan command.
#%DT%flipon; ascan m0 0 10 10 1 ; flipoff%DD% almost the same. %B%_flip_usermacro1%B% and %B%2%B% are not called, nor %B%_flip_readpol%B% macro.
#%XDL%
#%SETUP%
#%DL%There is no general setup macro but several ones.
#%DT%flipsetup macro:
#%DD% initialisation, default and general setup: COMPULSORY.
#%DT%flipcounterselect macro:
#%DD% counters selection for plotting.
#%DT%flipsave macro:
#%DD% counters selection for data saving.
#%DT%flipstyle* macros:
#%DD% way of flipping setup. basically, sets the number of countings at each scan steps.
#%DT%fliphdw* macros:
#%DD% installation of the device that will control the flipping. You can add your own device. Check the ones that are already existing (fliphdw* macros) and see how to proceed in %B%%{%<A HREF="#INTERNALS_1">INTERNALS,chapter I</A>%}%%B%.
#%DT%flipcal*/flipcal*off macros:
#%DD% insert or remove some online calculations to/from the flip. You can add your own calculations as well. (%B%%{%<A HREF="#INTERNALS_2">INTERNALS, chapter II</A>%}%%B%).
#%XDL%
#%INTERNALS%
#%{%<A NAME="INTERNALS_1"></A>%}%
#%DL%
#%DT% I - HARDWARE CONTROL.
#%DD%
#%PRE%
# setup macros : %B%fliphdw* flipresetcontrol%B%
# global related : %B%FLPOL%B%
#%PRE%
#%DL%
#%DT% %B%fliphdw*%B% macro %DD% installs the flipping hardware control into flip software by r-def-ing %B%_flip_*%B% macros listed below:
#%DL%
#%DT%_flip_flip%DD%polarity toggling
#%DT%_flip_neg%DD%polarity - setting
#%DT%_flip_pos%DD%polarity + setting
#%DT%_flip_move%DD%whatever to be executed prior to motor move.
#%DT%_flip_get%DD%whatever to be executed after angles reading.
#%DT%_flip_readpol%DD%returns the actual polarity
#%XDL%
#%DT%flipresetcontrol%DD% un-install everything. It is safe to call it at the beginning of any fliphdw* macros.
#%DT%FLPOL%DD%internally given -1/1 values to keep track of the polarity.
#%XDL%
#%BR%
# %B%_flip_move%B% and %B%_flip_get%B% were created to allow "flip scans"
# of a magnet pseudo motor. This sort of scan implies the polarity
# control is disabled from motion commands, so that the absolute intensity of
# the field can vary along the scan, while its polarity is flipped only at
# each scan step.
#%BR%%BR%
#%DL% %B%ATTENTION%B%%BR%%BR%
#%DT% _flip_flip, _flip_neg and _flip_pos %DD% macros must never call each others because of the internal assignment of FLPOL.
#%DT% FLPOL%DD% is always updated %B%at the end%B% of each %B%_flip_flip%B%, %B%_flip_neg%B% and %B%_flip_pos%B% macros.
#%DT% _flip_readpol%DD% is just read once at the beginning of a scan, %B%%{%<a href="flip_src.html#flip">flip</a>%}%%B% command only, in order to read in the actual polarity of the hardware. It will not be called if flipon/flipoff is used rather than the prefix flip.
#%XDL%
#%BR%
#%DL% %B%EXEMPLES%B% %BR%%BR%
#%DT% %{%<a href="flip_src.html#fliphdwsim">fliphdwsim</a>%}% %{%<a href="flip_src.html#fliphdwrelay">fliphdwrelay</a>%}% %{%<a href="flip_src.html#fliphdwpulse">fliphdwpulse</a>%}% %{%<a href="flip_src.html#fliphdwdacpulse">fliphdwdacpulse</a>%}% %{%<a href="flip_src.html#fliphdwdio">fliphdwdio</a>%}% %{%<a href="flip_src.html#fliphdwsd">fliphdwsd</a>%}% %{%<a href="flip_src.html#fliphdwox">fliphdwoxford</a>%}%.
#%DD%
#%XDL%
#%XDL%
#%BR%%BR%
#%{%<A NAME="INTERNALS_2"></A>%}%
#%DL%
#%DT% II - DATA STORAGE AND ONLINE CALCULATIONS.
#%DD%
#%PRE%
# setup macros : %B%flipcal* flipcal*off%B%
# cdef key : free, one per calculation.
# global array related : %B%FLPDAT%B%
#%PRE%
#%DL%
#%DT% flipcal* macro%DD% installs online calculations into flip software by c-def-ing %B%_flip_*%B% macros listed below with macros performing calculations. Several calculations can be installed each having a specific cdef key.
#%DL%
#%DT%_flip_calcs%DD%calculation macros
#%DT%_flip_calcs_splot%DD%related final plotting
#%XDL%
#%DT%flipcal*off%DD%un-install the corresponding calculation.
#%DT%FLPDAT%DD%array holds the scan data. It is filled up in %B%%{%<A HREF="flip_src.html#_flip_count">_flip_count</A>%}%%B% macro, called from %B%scan_count%B%, and always before %B%_flip_calcs%B%. It is formatted the following way:
#%PRE%
#array FLPDAT [4096] [ 1 + FLPSTYLE * COUNTERS]
#
#ie: [scan step] [0] : motor position or whatever x.
# [1:COUNTERS] : 1st counter positions set
# 1st positive polarity counting
# [COUNTERS+1:2*COUNTERS]
# : 2nd counter positions set
# 1st negative polarity counting
# [2*COUNTERS+1:3*COUNTERS]
# : 3rd counter positions set
# 2nd positive polarity counting
# ...
#%PRE%
#%XDL%
#%BR%%BR%
#%DL% %B%EXEMPLES%B%%BR%%BR%
#%DT% %{%<a href="flip_src.html#flipcaldelta">flipcaldelta</a>%}% %{%<a href="flip_src.html#flipcadeltaoff">flipcadeltaoff</a>%}%
#%DD%
#%XDL%
#%XDL%
#%BR%%BR%
#%DL%
#%DT% III - SCAN
#%DD%
#%PRE%
# macros : %B%flip flipon flipoff%B%
# cdef key : %B%flps%B%
#%PRE%
#
#The flip software is hooked to standard scan user macros from %B%flipon/flipoff%B% commands, or by having usual scan commands preceeded by the word %B%%{%<a href="flip_src.html#flip">flip</a>%}%%B%. (eg: flip ascan mot0 0 10 10 1). In the last case, all is removed at the end of the scan. The hooks are listed below: (see %{%<a href="flip_src.html#flipon">flipon</a>%}%)
#%BR%%BR%%UL%
#%LI%%B%user_cleanup2%B%_flip_cleanup
#%LI%%B%user_checkall%B%_flip_move
#%LI%%B%user_getpangles%B%_flip_get;_flip_heading
#%LI%%B%Fheader%B%_flip_Fhead
#%LI%%B%Flabel%B%_flip_Flab
#%LI%%B%Pheader%B%_flip_Phead
#%LI%%B%Plabel%B%_flip_Plab
#%LI%%B%Fout%B%_flip_Fout
#%LI%%B%Pout%B%_flip_Pout
#%LI% and rdef %B%scan_count%B%_flip_count
#%XUL%
#%XDL%
#%BR%%BR%
#%DL%
#%DT% IV - PLOT COUNTERS SELECTION
#%DD%
#%PRE%
# macros : %B%flipcounterselect%B%
# globals : %B%FLP_CNO FLP_CLST%B%
#%PRE%
# %B%%{%<a href="flip_src.html#flipcounterselect">flipcounterselect</a>%}%%B% macro selects the counters to be plotted in the flip window, as %B%setplot%B% does for standard scan window. %B%FLP_CNO%B% holds the number of selected counters, and the array %B%FLP_CLST%B% holds selected counters mnemonics.
#%XDL%
#%BR%%BR%
#%DL%
#%DT% V - SAVE COUNTERS SELECTION
#%DD%
#%PRE%
# macros : %B%flipsave%B%
# globals : %B%FLP_SNO FLP_SLST%B%
#%PRE%
# %B%%{%<a href="flip_src.html#flipsave">flipsave</a>%}%%B% macro selects the counters which value should be dumped to scan file more than once at each scan step (in fact, each time a flip counting occurs). %B%FLP_SNO%B% holds the number of selected counters, and the array %B%FLP_SLST%B% holds selected counters numbers. If %B%flipsave%B% is never called, default behavior applies, i.e. all the measurements are dumped to the file.
#Any scan will always start with a measurement at POSITIVE polarity. Then the following measurements results are always dumped alternating - and +, even if they did not actually occured that way.
#%XDL%
#%END%
#----------------------------------------------------------------------- SETUP
#%UU% [sleep]
#%MDESC% General initialisation and default settings.
#%BR% One can specify here the time to wait after flipping has occured.
def flipsetup '
global FLP_SLEEP
flipinit
if ($1) FLP_SLEEP = $1
else if (!$#) FLP_SLEEP = getval ("Wait time after flip, in sec.",FLP_SLEEP)
setup_tail("flip")
'
#%UU%
#%MDESC% Initialises internal macros and set defaults.
#%BR% Called by %B%flipsetup%B%.
def flipinit '
global FLPOL FLP_CNO FLP_CLST FLP_SNO FLP_SLST FLP_SLEEP
global FLIP_ON
FLP_CLST[-1]=0
FLP_SLST[-1]=0
if (!(whatis("_flip_calcs")&2)) rdef _flip_calcs \'\'
if (!(whatis("_flip_calcs_splot")&2)) rdef _flip_calcs_splot \'\'
if (!(whatis("_flip_move")&2)) rdef _flip_move \'\'
if (!(whatis("_flip_get")&2)) rdef _flip_get \'\'
if (!(whatis("_flip_Fhead")&2)) rdef _flip_Fhead \'\'
if (!(whatis("_flip_Phead")&2)) rdef _flip_Phead \'\'
if (!(whatis("_flip_usermacro1")&2)) rdef _flip_usermacro1 \'\'
if (!(whatis("_flip_usermacro2")&2)) rdef _flip_usermacro2 \'\'
if (!(whatis("_flip_flip")&2)) rdef _flip_flip \'\'
if (!(whatis("_flip_pos")&2)) rdef _flip_pos \'\'
if (!(whatis("_flip_readpol")&2)) rdef _flip_readpol \'FLPOL\'
if (!(whatis("_flip_Flab")&2)) rdef _flip_Flab \'""\'\'
if (!(whatis("_flip_Fout")&2)) rdef _flip_Fout \'""\'
if (!(whatis("_flip_Plab")&2)) rdef _flip_Plab \'""\'
if (!(whatis("_flip_Pout")&2)) rdef _flip_Pout \'""\'
cdef ("config_mac","_flip_config;","flipscan")
# default:
if (0==FLPSTYLE) {
flipstyle 2
fliphdwsim
}
if (0==FLP_CNO) {
flipcounterselect ALL
}
if (0==FLP_SNO) {
flipsave ALL
}
'
#%UU%
#%MDESC% Remove flip software.
def flipunsetup '
unglobal FLPOL FLP_CNO FLP_CLST FLPCOUNTERS FLPSTYLE FLP_LABEL FLP_OUT
unglobal Y_FL FLPG
flipoff
flipresetcontrol
cdef ("","","flipscan","delete")
print "FLIP deleted"
'
#%IU%
#%MDESC% Configuration macro. (%B%config_mac%B%)
def _flip_config ''
#%UU% [[number (always even)] [flag]] | | [style_string]
#%MDESC% Sets the number of countings and flippings.
#%BR% If %B%flag%B% is zero, flipping occurs between each couting; if it is 1, I dont know how to explain it, but the %B%style_string%B% way might help.
#It is a string of %B%+%B% and %B%-%B% ordered along with the flippings. e.g. %B%+-+-%B% would mean 4 countings flipped (flipstyle 4), %B%+--+%B% is also 4 countings, but not flipped at the middle. It is flag 1. (flipstyle 4 1).
#There must be as many negative as positive countings for it works, and it will neither allow an odd number of countings. Means that allowed entries are 1, 2, 4 0, 4 1, or +--+, or +-+-. +-+--+-+ would also work, but not +-++-+...
def flipstyle '{
global FLPSTYLE FLPOPTION FLP
local i1 i2
i1="$1"+0; i2="$2"+0
FLPSTYLE = i1>=2?2*int(i1/2):1
FLPOPTION = FLPSTYLE>2?i2:0
_flip_style_keep_request $*
if (FLPSTYLE==1) {
FLP[-1]="< -"
FLP[1]="< +"
rdef _flip_Plab \'""\'
rdef _flip_Pout \'sprintf("%s ",FLP[FLPOL])\'
} else {
rdef _flip_Plab \'sprintf("%7.7s %7.7s ",cnt_name(DET),cnt_name(MON))\'
rdef _flip_Pout \'sprintf("- | + %7.5g %7.5g ", FLPDAT[NPTS][DET+1+COUNTERS*(FLPSTYLE-2)], FLPDAT[NPTS][MON+1+COUNTERS*(FLPSTYLE-2)])\'
}
}
'
def _flip_style_keep_request '{
global FLPSTYLEREQ
local tok str1 str2
FLPSTYLEREQ="$*"
if (index(FLPSTYLEREQ,"+")) {
if ($#>1) {
FLPSTYLE = split (FLPSTYLEREQ,toks)
if (FLPSTYLE>=2) FLPSTYLE = 2*int(FLPSTYLE/2)
else FLPSTYLE = 1
str1 = str2 = ""
str1 = toks[FLPSTYLE/2-1]
str2 = toks[FLPSTYLE/2]
} else {
FLPSTYLE = length (FLPSTYLEREQ)
if (FLPSTYLE>=2) FLPSTYLE = 2*int(FLPSTYLE/2)
else FLPSTYLE = 1
str1 = substr(FLPSTYLEREQ,FLPSTYLE/2,1)
str2 = substr(FLPSTYLEREQ,FLPSTYLE/2+1,1)
}
if (str1==str2 && FLPSTYLE>2) FLPOPTION=1
else FLPOPTION=0
}
}
'
#%UU% [ALL|mnemonic] [mnemonic] [mnemonic] ...
#%MDESC% Select the counters that will be plotted in flip window.
def flipcounterselect '{
global FLPCOUNTERS FLP_CLST
FLP_CLST[0]
for (i=0;i<COUNTERS;i++) FLPCOUNTERS[i]=cnt_mne(i);
if ($#) {
if ("$1" == "ALL") {
FLP_CNO=COUNTERS
for (i=0;i<COUNTERS;i++) FLP_CLST[i]=FLPCOUNTERS[i]
} else {
FLP_CNO = split ("$*",FLP_CLST)
}
} else {
clscreen()
FLP_CNO = menu_2lists(FLP_CLST,FLP_CNO,FLPCOUNTERS,COUNTERS)
}
}
'
#%UU% [ALL|mnemonic] [mnemonic] [mnemonic] [mnemonic]
#%MDESC% Select the counters that will be dumpped their content to the file for additionnal measurements produced by flip.
def flipsave '{
global FLPCOUNTERS FLP_SLST
# if ("$1"=="binned") FLP_SMOD=1
# else FLP_SMOD=0 # raw
FLP_SLST[0]
for (i=0;i<COUNTERS;i++) FLPCOUNTERS[i]=i;
if ($#) {
if ("$1" == "ALL") {
FLP_SNO=COUNTERS
for (i=0;i<COUNTERS;i++) FLP_SLST[i]=FLPCOUNTERS[i]
} else {
FLP_SNO = split ("$*",FLP_SLST)
}
} else {
clscreen()
FLP_SNO = menu_2lists(FLP_SLST,FLP_SNO,FLPCOUNTERS,COUNTERS)
}
for (i=0;i<FLP_SNO;i++) FLP_SLST[i]=cnt_num(FLP_SLST[i])
}
'
#----------------------------------------------------------------------- SAVING
#%IU%
#%MDESC% %B%_cols%B% update and File output formatting. (%B%Fheader%B%).
def _flip_Fhead '{
if (COUNTERS && FLPSTYLE) {
array FLPDAT [4096][COUNTERS*FLPSTYLE+1]
}
_flip_Foutput
rdef _flip_Fout FLP_OUT
printf("#C flipstyle %s : %d %d\n", FLPSTYLEREQ,FLPSTYLE,FLPOPTION)
}
_cols+=FLP_SNO?FLP_SNO*(FLPSTYLE-1):(COUNTERS-1)*(FLPSTYLE-1)
'
#%IU%
#%MDESC% Compiles the global variables %B%FLP_OUT%B% and %B%FLP_LABEL%B% out of the flip style set up. Both are used for printing out flip data to scan file. Each counter name is added a suffix like "_1", for each measurement over the regular one.
#%PRE%
#e.g.:
# FLP_LABEL = "Counter 1 Counter 2" or "Counter 1 Counter 2 Counter 1_1 ..."
# FLP_OUT = ",FLPDAT[NPTS][1],FLPDAT[NPTS][2]"
#%PRE%
def _flip_Foutput '{
global FLP_LABEL FLP_OUT
local _countings _counters cno val ii jj fmt ix
FLP_LABEL = ""
_countings = FLPSTYLE-1
if (_countings<0) _countings=0
_counters = FLP_SNO?FLP_SNO:COUNTERS-1
for (ii=0;ii<_countings;ii++) {
zz=dd=-1
for (jj=0;jj<_counters;jj++) {
cno=FLP_SNO?FLP_SLST[jj]:jj+1
if (cno != MON && cno != DET && cnt_name(cno) != "unused") {
FLP_LABEL = FLP_LABEL cnt_name(cno) "_" ii+1 " "
fmt = fmt "%g "
ix = 1 + cno+COUNTERS*ii
val = sprintf("%s,FLPDAT[NPTS][%d]",val,ix)
}
if (cno==MON) zz=MON
if (cno==DET) dd=DET
}
if (zz >= 0) {
FLP_LABEL = FLP_LABEL cnt_name(zz) "_" ii+1 " "
fmt = fmt "%g "
ix = 1 + zz+COUNTERS*ii
val = sprintf("%s,FLPDAT[NPTS][%d]",val,ix)
}
if (dd >= 0) {
FLP_LABEL = FLP_LABEL cnt_name(DET) "_" ii+1 " "
fmt = fmt "%g "
ix = 1 + DET+COUNTERS*ii
val = sprintf("%s,FLPDAT[NPTS][%d]",val,ix)
}
}
FLP_OUT = "sprintf(\"" fmt "\"" val ")"
}
'
def flip_Foutput_old '{
global FLP_LABEL FLP_OUT
local ctnum val fmt ix
if (COUNTERS && FLPSTYLE) {
array FLPDAT [4096][COUNTERS*FLPSTYLE+1]
}
FLP_LABEL = ""
ctnum = FLPSTYLE-1
if (ctnum<0) ctnum=0
for (num=0;num<ctnum;num++) {
for (cno=1;cno<COUNTERS;cno++) {
zz=MON
if (cno != zz && cno != DET && cnt_name(cno) != "unused") {
FLP_LABEL = FLP_LABEL cnt_name(cno) "_" num+1 " "
fmt = fmt "%g "
ix = 1 + cno+COUNTERS*num
val = sprintf("%s,FLPDAT[NPTS][%d]",val,ix)
}
}
if (zz >= 0) {
FLP_LABEL = FLP_LABEL cnt_name(zz) "_" num+1 " "
fmt = fmt "%g "
ix = 1 + zz+COUNTERS*num
val = sprintf("%s,FLPDAT[NPTS][%d]",val,ix)
}
FLP_LABEL = FLP_LABEL cnt_name(DET) "_" num+1 " "
fmt = fmt "%g "
ix = 1 + DET+COUNTERS*num
val = sprintf("%s,FLPDAT[NPTS][%d]",val,ix)
}
FLP_OUT = "sprintf(\"" fmt "\"" val ")"
}
'
#%IU%
#%MDESC% (%B%Flabel%B%)
def _flip_Flab 'sprintf(FLP_LABEL)'
#-------------------------------------------------------------------- HARDWARE
#%UU%
#%MDESC% Remove any flip controller installed.
def flipresetcontrol '
global FLPHDW
rdef _flip_readpol \'FLPOL\'
rdef _flip_pos \'\'
rdef _flip_flip \'\'
rdef _flip_move \'\'
rdef _flip_get \'\'
FLPHDW = substr("$*",8)
'
#%UU%
#%MDESC% Install a simulation of a hardware flipping.
def fliphdwsim '
flipresetcontrol $0
rdef _flip_pos \'
printf ("\n<+>")
\'
rdef _flip_flip \'
if (FLPOL>0) {
printf("<->")
} else {
printf("<+>")
}
\'
rdef _flip_move \'
print "disable"
\'
rdef _flip_get \'
print "enable"
\'
'
#%UU% <relay_device_server_name>
#%MDESC% needs %B%dio.mac%B% macros. %BR%Install one CS Relay device server to control the flipping. Relay opens for negative polarity and closes for positive.
def fliphdwrelay '
if ($#) {
flipresetcontrol $0 $*
rdef _flip_pos \'
dio_devclose("$1")
\'
rdef _flip_flip \'
if (FLPOL<=0) {
dio_devclose("$1")
} else {
dio_devopen("$1")
}
\'
}
'
#%UU% <pulsedrelay_device_server_name> <pulse_time>
#%MDESC% needs %B%dio.mac%B% macros.%BR%Install one CS Pulsed Relay device server to control the flipping. Flipping occurs on relay pulsing.
def fliphdwpulse '
if ($#) {
flipresetcontrol $0 $*
rdef _flip_flip \'
dio_devpulse("$1",$2)
\'
rdef _flip_pos \'
if (FLPOL<=0) dio_devpulse("$1",$2)
\'
}
'
#%UU% <dac_device_server_name> <pulse_time> <rest_voltage> <pulse_voltage>
#%MDESC% Install one DAC (icv712) output to control the flipping. Flipping occurs when output pulses.
def fliphdwdacpulse '
if ($#==4) {
flipresetcontrol $0 $*
rdef _flip_flip \'
esrf_io("$1","DevSetValue",$4)
sleep ($2)
esrf_io("$1","DevSetValue",$3);
\'
rdef _flip_pos \'
if (FLPOL<=0) {
esrf_io("$1","DevSetValue",$4)
sleep ($2)
esrf_io("$1","DevSetValue",$3);
}
\'
esrf_io("$1","DevSetValue",$3)
}
'
#%UU% <dac_device_server_name> <pulse_time> <pulse_voltage> <rest_voltage>
#%MDESC% Install one DAC (icv712) output to control the flipping. Goes to positive polarity when pulse is positive, and to negative when pulse is negative.
def fliphdwdacpulse1 '
if ($#==4) {
flipresetcontrol $0 $*
rdef _flip_flip \'
if (FLPOL<=0) {
esrf_io("$1","DevSetValue",$3)
sleep ($2)
esrf_io("$1","DevSetValue",$4);
} else {
esrf_io("$1","DevSetValue",-$3)
sleep ($2)
esrf_io("$1","DevSetValue",-$4);
}
\'
rdef _flip_pos \'
if (FLPOL<=0) {
esrf_io("$1","DevSetValue",$3)
sleep ($2)
esrf_io("$1","DevSetValue",$4);
}
\'
}
'
#%UU% <dac_device_server_name> <positive_voltage> <negative_voltage>
#%MDESC% Install one DAC (icv712) output to control the flipping. Goes to positive polarity when <positive_voltage> is applied, and to negative when <negative_voltage> is applied.
def fliphdwdac '
if ($#>=2) {
flipresetcontrol $0 $*
rdef _flip_flip \'
esrf_io("$1","DevSetValue",FLPOL>0?$3:$2)
\'
rdef _flip_pos \'
esrf_io("$1","DevSetValue",$2)
\'
}
'
#%UU% <dio_actuator_name>
#%MDESC% needs %B%dio.mac%B% macros and %B%diosetup%B% done.%BR%
#Install one DIO channel to control the flipping. This works only if %B%diosetup%B% has been done. Otherwise, use %B%fliphdwrelay%B% or %B%fliphdwpulse%B%.
def fliphdwdio '{
if (DIOid["$1"]) {
flipresetcontrol $0 $*
rdef _flip_pos \'
dio_close(DIOid["$1"])
\'
rdef _flip_flip \'
if (FLPOL<=0) {
dio_close(DIOid["$1"])
} else {
dio_open (DIOid["$1"])
}
\'
}
else print "do \"diosetup\" first"
}
'
#%UU%
#%MDESC% needs %B%sdlin.mac%B% macros and %B%sdsetup%B%%BR%
#Install the Sodilec BOS/S Power Supply to control the flipping.
def fliphdwsd '{
flipresetcontrol $0 $*
rdef _flip_readpol \'((SD_SETPOINT >0) ? 1 : -1)\'
rdef _flip_move \'SDPOLF=0\'
rdef _flip_get \'SDPOLF=1\'
rdef _flip_pos \'
sdset fabs(SD_SETPOINT)
\'
rdef _flip_flip \'
if (FLPOL>0) {
sdset -fabs(SD_SETPOINT)
} else {
sdset fabs(SD_SETPOINT)
}
\'
}
'
#%UU% <oxpssetup_device_number>
#%MDESC% needs %B%oxPS1.mac%B% macros, and %B%oxpssetup%B%%BR% Install an Oxford PS 180 or 120 type Power Supply to control the flipping. <oxpssetup_device_number> starts from 1.
def fliphdwoxford '{
local _oxx
if (!$#) {
print "usage: $0 devnum"
print "eg: $0 1"
exit
}
flipresetcontrol $0 $*
rdef _flip_move \'OXPOLF=0\'
rdef _flip_get \'OXPOLF=1\'
rdef _flip_pos \'
_oxps_checkmode $1-1
oxps_iof($1-1,"P1")
oxps_iof($1-1,"P1")
_oxps_wait_mag_pol $1-1 1
_oxps_ifpersistant $1-1
# FLPOL=1
\'
rdef _flip_flip \'
_oxps_checkmode $1-1
ox_iof($1-1,"P4")
_oxps_wait_mag_pol $1-1 -FLPOL
_oxps_ifpersistant $1-1
\'
}
'
#---------------------------------------------------------------- CALCULATIONS
#%UU%
#%MDESC% Install some online DELTA calculation.
def flipcaldelta '
cdef ("_flip_calcs","_flip_delta;","flpdelta")
cdef ("_flip_calcs_splot","_flip_splot 3 FLPDELTA 1;","flpdelta")
'
#%UU%
#%MDESC% Un-install delta calculation.
def flipcaldeltaoff 'cdef ("","","flpdelta","delete")'
#%IU%
#%MDESC% DELTA online calculations. %BR%i.e. substracts negative countings from positive countings, stores the result in %B%FLPDELTA%B% array, and plots it out.
def _flip_delta '{
local offs num
if (0==NPTS) { array FLPDELTA [4096][1+COUNTERS] }
FLPDELTA[NPTS][0]= _stype&1?A[_m[0]]:_time
for (num=0;num<FLPSTYLE;num+=2) {
offs = COUNTERS*num
FLPDELTA[NPTS][1:] += FLPDAT[NPTS][1+offs:COUNTERS+offs]
offs += COUNTERS
FLPDELTA[NPTS][1:] -= FLPDAT[NPTS][1+offs:COUNTERS+offs]
}
_flip_rplot 3 FLPDELTA FLIP_DELTA 1
}
'
#%UU%
#%MDESC% Install some online AVERAGE calculation.
def flipcalaverage '
cdef ("_flip_calcs","_flip_average;","flpaver")
cdef ("_flip_calcs_splot","_flip_splot 4 FLPAVER 1;","flpaver")
'
#%UU%
#%MDESC% Un-install average calculation.
def flipcalaverageoff 'cdef ("","","flpaver","delete")'
#%IU%
#%MDESC% AVERAGE online calculations. %BR% i.e. average all countings, stores the result in %B%FLPAVER%B% array, and plots it out.
def _flip_average '{
local offs num
if (0==NPTS) { array FLPAVER [4096][1+COUNTERS] }
FLPAVER[NPTS][0]= _stype&1?A[_m[0]]:_time
for (num=0;num<FLPSTYLE;num+=1) {
offs = COUNTERS*num
FLPAVER[NPTS][1:] += FLPDAT[NPTS][1+offs:COUNTERS+offs]
}
FLPAVER[NPTS][1:]/=FLPSTYLE
_flip_rplot 4 FLPAVER FLIP_AVERAGE 1
}
'
#------------------------------------------------------------------------ FLIP
#%UU% <standard_usual_scan_command>
#%MDESC% Does the flip scan.
def flip '{
flipon
FLPOL = _flip_readpol
_flip_usermacro1
}
$*
flipsplot
_flip_usermacro2
flipoff
'
#%UU%
#%MDESC% Hooks the flip to standard scans.
def flipon '{
cdef("user_cleanup2","_flip_cleanup;","flps")
cdef("user_checkall","_flip_move;","flps",0x10)
cdef("user_getpangles","_flip_get;_flip_heading;","flps",0x20)
cdef("Fheader","_flip_Fhead;","flps")
cdef("Flabel","_flip_Flab","flps")
cdef("Pheader","_flip_Phead;","flps")
cdef("Plabel","_flip_Plab","flps")
cdef("Fout","_flip_Fout","flps")
cdef("Pout","_flip_Pout","flps")
rdef scan_count \'_flip_count\'
FLIP_ON = 1
}
'
#%UU%
#%MDESC% Detach the flip from standard scans.
def flipoff '{
cdef("","","flps","delete")
cdef("Flabel","\"\"","flps",0)
cdef("Plabel","\"\"","flps",0)
cdef("Fout","\"\"","flps",0)
cdef("Pout","\"\"","flps",0)
rdef scan_count \'_count\'
FLIP_ON = 0
}
'
#%IU%
#%MDESC% Scan heading string. (%B%HEADING%B%)
def _flip_heading 'HEADING = "flip " HEADING'
#%IU%
#%MDESC% (%B%scan_count%B%). Here is the flipping_counting manager.
def _flip_count '{
local ctnum
local cc offs
waitmove
for (ctnum=0;ctnum<FLPSTYLE;ctnum++) {
if ((FLPSTYLE>1 && !ctnum) || (FLPSTYLE==1 && !NPTS)) {
_flip_pos
sleep(FLP_SLEEP)
FLPOL=1
} else if (FLPSTYLE==1 || !FLPOPTION || (((FLPSTYLE/2)!=ctnum))) {
_flip_flip
sleep(FLP_SLEEP)
FLPOL=-FLPOL
}
if ($1) for (;;) {
count_em $1
waitcount
get_counts
chk_beam
}
if (S[sec] && MON >= 0)
MON_RATE=S[MON]/S[sec]
offs = int (ctnum/2)*2
if (FLPSTYLE>1 && FLPOL<0) offs++
for (cc=0;cc<COUNTERS;cc++) FLPDAT[NPTS][1+cc+COUNTERS*offs]=S[cc]
}
for (cc=0;cc<COUNTERS;cc++) {
S[cc] = FLPDAT[NPTS][1+cc+COUNTERS*(FLPSTYLE-1)]
}
FLPDAT [NPTS][0] = _stype&1?A[_m[0]]:_time
_flip_calcs
_flip_rplot 2 FLPDAT FLIP FLPSTYLE
}
'
#%IU%
#%MDESC% Cleanup macro. (%B%user_cleanup2%B%)
def _flip_cleanup '{
_flip_get
flipsplot
_flip_usermacro2
flipoff
}
'
#--------------------------------------------------------------------- PLOTTING
#%IU% <filter_num> <data_array_name> [window_title]
#%MDESC% Running scan plot for all flip data.
def _flip_rplot '{
global Y_FL
local pstr num
plot_cntl("filter$1")
if (PLOT_MODE&128) {
plot_cntl(sprintf("colors=%s",rplot_col))
plot_cntl("open")
}
if ((_stype&8? _g1:NPTS) == 0) {
for (Y_FL = cnt_name(cnt_num(FLP_CLST[0])),uu=1;uu<FLP_CNO;uu++) {
Y_FL = Y_FL" "cnt_name(cnt_num(FLP_CLST[uu]))
}
plot_range(_sx,_fx,YMIN,"auto")
plot_cntl("title=$3")
plot_cntl(PLOT_MODE&32? "ylog":"-ylog")
plot_cntl(PLOT_MODE&256? "-dots":"dots")
plot_cntl(PLOT_MODE&512? "-lines":"lines")
plot_cntl(PLOT_MODE&1024? "-ebars":"ebars")
plot_cntl("erase")
plot_move(0,1,sprintf("Flip %s",T_L))
plot_move(0,2,Y_FL)
plot_move(0,-1,sprintf("%.8s", X_L))
}
if (_stype&16) plot_range("auto","auto",YMIN,"auto")
num = $4?$4:FLPSTYLE
pstr = _flip_plotwhat(num)
array_plot($2[0:NPTS][pstr])
plot_move(0,0)
plot_cntl("filter1")
}
'
#%UU%
#%MDESC% Screen plot of flip data.
def flipsplot '{
_flip_splot 2 FLPDAT FLPSTYLE
_flip_calcs_splot
}
'
#%IU% <filter_num> <data_array_name>
#%MDESC% Final scan plot for all flip data.
def _flip_splot '{
local pstr num
plot_cntl("filter$1")
if (PLOT_MODE&128) {
plot_cntl(sprintf("colors=%s",splot_col))
plot_cntl("open")
}
plot_cntl("erase")
plot_range("auto","auto",YMIN,"auto")
plot_move(0,1,sprintf("Flip %s",T_L))
plot_move(0,2,Y_FL)
plot_move(0,-1,sprintf("%.8s", X_L))
num = $3?$3:FLPSTYLE
pstr = _flip_plotwhat(num)
array_plot($2[0:NPTS-1][pstr])
plot_move(0,3)
plot_cntl("filter1")
}
'
#%IU% (number_of_countings)
#%MDESC% Returns %B%FLPDAT%B% array index string of what to plot.
def _flip_plotwhat(loop1end) '{
local num
pstr = "0"
for (num=0;num<loop1end;num++) {
for (cno=0;cno<FLP_CNO;cno++) {
pstr = pstr "," cnt_num(FLP_CLST[cno])+1+COUNTERS*num
}
}
return pstr
}
'
#--------------------------------------------------------------- CPLOT ACCESS
#%UU% [detector-mnemonic] [detector-mnemonic] ...
#%MDESC% flip data printer plot, pplot like.
def flippplot 'cp_setprinter; _flip_cplot $*'
#%UU% [detector-mnemonic] [detector-mnemonic] ...
#%MDESC% flip data cplot, cplot like.
def flipcplot 'cp_setx11;_flip_cplot $*'
#%IU%
#%MDESC% Does for cplot.
def _flip_cplot '{
global FLPG
local yind ylabel
_flip_y $*
nn = 1+COUNTERS*FLPSTYLE
FLPG = groupinit(FLPG, int (65536/nn), nn)
data_read (FLPDAT[0:NPTS][yind],FLPG)
cp_mplot FLPG 0 \'"yind"\' \'"T_L"\' \'"X_L"\' \'"ylabel"\'
}
'
#%IU%
#%MDESC% Compiles Y index string to pass to cp_mplot.
def _flip_y '{
local firsthit
yind = 0
ylabel = ""
if (!$#) {
yind = substr(_flip_plotwhat(FLPSTYLE),3)
} else {
split("$*",_p)
for (i2=0,firsthit=1;i2<COUNTERS;i2++) {
for (i1=0;i1<$#;i1++) {
if (cnt_num(_p[i1]) == i2) {
if (firsthit) {
yind=sprintf("%d",i2+1)
if (FLPSTYLE>=2) yind = sprintf ("%s,%d",yind,i2+1+COUNTERS)
ylabel = sprintf("%s ",cnt_name(i2))
firsthit = 0
} else {
yind=sprintf("%s,%d",yind,i2+1)
if (FLPSTYLE>=2) yind = sprintf ("%s,%d",yind,i2+1+COUNTERS)
ylabel = sprintf("%s%s ",ylabel,cnt_name(i2))
}
}
}
}
}
}
'
#--------------------------------------------------------------- MISC
#%UU%
#%MDESC% Shows what is installed.
def flipstat '{
printf( "\nflipstat : ")
if (FLPSTYLE) {
printf( "requested flipstyle %s\n-----\n", FLPSTYLEREQ)
printf( "number of countings (flipstyle): %d. ",FLPSTYLE,FLPOPTION)
for (i=0;i<4;i++) {
local ctnum flpol
for (ctnum=0;ctnum<FLPSTYLE;ctnum++) {
if ((FLPSTYLE>1 && !ctnum) || (FLPSTYLE==1 && !i)) {
flpol=1
} else if (FLPSTYLE==1 || !FLPOPTION || (((FLPSTYLE/2)!=ctnum))) {
flpol=-flpol
}
printf("%s",flpol>0?"+":"-")
}
printf (" ; ")
}
print
printf( "plotted counters (flipcounterselect): ")
for (i=0;i<FLP_CNO;i++) printf("%s ",FLP_CLST [i]);
print
printf( "saved counters (flipsave): ")
for (i=0;i<FLP_SNO;i++) printf("%s ",cnt_mne(FLP_SLST [i]));
print
printf( "hardware installed (fliphdw*): %s\n",FLPHDW)
printf( "sleep after flip (flipsetup): %g\n",FLP_SLEEP)
} else
print "Setup not done"
}
'
#%IU%
#%MDESC% Menu stuff.
def menu_2lists (list,sz,list0,sz0) '{
local sel ttyx i j text
for (sel="";sel!="q";sel = getval(sprintf("enter element to move or %sq%suit\n\n ---> ",MENU_ONB,MENU_OFS),"q")) {
ttyx[0]=ttyx[1]=length("SELECTION: ")
tty_move(0,5,"SELECTION: ");tty_cntl("ce")
tty_move(0,7," OTHER: ");tty_cntl("ce")
for (i=0;i<sz0;i++) {
text = sprintf("<%s%s%s>",MENU_ONB,list0[i],MENU_OFS)
for (j=0;j<sz;j++) {
if (list0[i]==list[j]) break
}
if (sel == list0[i]) {
if (j==sz) {
list[sz++]=sel
} else {
list[j]=list[--sz]
delete list[sz]
j=sz
}
}
if (j==sz) {
tty_move(ttyx[0],7,text)
ttyx[0]+=length(text)-2
} else {
tty_move(ttyx[1],5,text);
ttyx[1]+=length(text)-2
}
}
tty_move(0,11);tty_cntl("ce");tty_move(0,9)
}
return (sz)
}
'
#%IU%
#%MDESC% For use of blmenu (use blmenu.mac).
def flipbody(mode) '{
if (mode == 1) {
if (FLIP_ON) {
flipoff
}
else {
flipon
}
}
return(sprintf("%s",FLIP_ON?"ON":"OFF"))
}
'
#%MACROS%
#%IMACROS%
#%DEPENDENCIES%
#The file %B%flip.mac%B% has to be read in.%BR%
#It also needs:
#%UL%
#%LI%%B%stlocal.mac%B%
#%LI%flipping device %B%specific macros%B%.(oxPS.mac, dio.mac ...)
#%XUL%
#%AUTHOR%
# FLIP.MAC - Marie-Claire LAGIER - 96/10/21
#%TOC%
## DATE Wed Mar 4 15:57:42 MET 1998 REV 2.6;
|