#! /bin/csh -f # # Command-line Fluorescence scan procedure # # if(! $?beamline) then # default to beamline this computer belongs to setenv beamline `beamline.com` if($status) then echo "ERROR: $beamline" exit 9 endif endif set start = 12640 set step = 0.5 set end = 12670 set expose = 1 set goal = 50000 set min_div = 0.002 # aproximate time constant set on the ratemeter set timeconstant = 1500000 set optimize set tempfile = /tmp/scan_tmp$$ set Izero_dark = 0 # allow the use of an old output file if(-e "$1") then set scanfile = "$1" set argv[1] = "" set old_div = "" set Ee = `basename $scanfile | awk -F "_" 'NF>2{print $(NF-1)}'` if ("$Ee" == "") set Ee = `awk '{++n;sum+=$1} END{if(n>0)print sum/n}' $scanfile | elements | awk '{print $2;exit}'` goto interrupt endif #set evenstep set range = "" set Ee = "" foreach arg ( $* ) if("$arg" =~ "-noopt"*) then unset optimize set NOOPTIMIZE continue endif if("$arg" =~ "-nodisp"*) then set NODISPLAY continue endif if("$arg" =~ *".scan") then set user_scanfile = $arg continue endif set num = `echo $arg | awk '{printf $1+0}'` set num10 = `echo $arg | awk '{printf "%d", $1*10}'` set num100 = `echo $arg | awk '{printf "%d", $1*100}'` if(("$arg" =~ *[0-9]s) && ($num10 < 1200) && ($num10 > 0)) then # fits the bill for exposure time set expose = $num continue endif if($num10 > 20000 && $num10 < 200000) then # must be a range limit set range = ( $range $num ) continue endif if($num10 < 1200 && $num100 > 0) then # fits the range for a stepsize set step = $num continue endif # allow use of element symbol/name if(("$arg" =~ *[a-z]*)||("$arg" =~ *[A-Z]*)) then # set temp = `echo "$arg" | elements | awk '{print $3, $4, $4-20, $4+20; exit}'` set temp = `echo "$arg" | elements | awk '{print $3, $4, $4-150, $4+150; exit}'` if($#temp == 4) then echo "$temp[1] edge: $temp[2]" set start = $temp[3] set end = $temp[4] unset evenstep endif endif end set range = `echo $range | awk '{for(i=1;i<=NF;++i) print $i}' | sort -n | awk 'NR==1{print} END{print}'` if($#range == 2) then if("$range[1]" == "$range[2]") then # must be a midpoint set range = `echo $range | awk '{print $1-150,$1+150}'` endif set start = $range[1] set end = $range[2] endif set step = `echo $step | awk '$1+0<0.01{$1=1} {print}'` set edge = `echo $start $end | awk '{print ($1+$2)/2}'` if("$1" == "") then cat << EOF usage: scan.com start_eV end_eV [step_eV] [exposure_s] or scan.com Ee [step_eV] [exposure_s] example: scan.com 12640.0 12670.0 1.0 scan.com Se 1.0 scan.com Hg 5s EOF exit 9 endif # come up with a good name for the scan file set Ee = `echo $start $end | awk '{print ($1+$2)/2}' | elements | awk '{print $2;exit}'` if($?user_scanfile) then set scanfile = "$user_scanfile" else set img_prefix = `echo -n "" | xos3_exchange.tcl 1 "set_motor_dependency" |& awk '/configure_run /{print $7 "/" $6 "_" $5 "_"; exit}' | head -1` set img_prefix = "${img_prefix}$Ee" set num = `ls -1rt ${img_prefix}* |& tail -1 | awk -F "_" '{printf "%03d", $NF+1}'` set img_prefix = "${img_prefix}_${num}" set scanfile = "${img_prefix}.scan" endif touch $scanfile >& /dev/null if($status) set scanfile = `basename $scanfile` touch $scanfile >& /dev/null if($status) set scanfile = ~/`basename $scanfile` echo "" echo "this scan will be saved in $scanfile" echo "$start to $end in $step eV steps for ${expose}s" echo "" diode.com in scintilator.com in if(! $?optimize || $?NOOPTIMIZE) goto doscan # move to the end (relatively high signal) energy wave.com $end # record the current slit settings set old_div = `divergence.com | tail -1 | awk '{print $(NF-1), $NF}'` set div = ( $old_div ) slits: # stick in the attenuator if we can if( `echo $end | awk '{print ($1>8000)}'` ) then attenuator.com in attenuator.com Cu in endif diode.com in scintilator.com in set Ifluor = `fluorescence.com 0.5 | awk '$7+0>0{print $1/$7}'` echo "fluorescence signal is $Ifluor counts/s" # skip auto-adjust of slits if they are already good? if( `echo $Ifluor $goal | awk '{print (sqrt(($1-$2)^2) < 1000)}'` ) set adjusted onintr interrupt if($?adjusted) then # reopen the slits to their initial value divergence.com $old_div $old_div endif # remember that we did the adjustment already set adjusted set div = $min_div while ( `echo $Ifluor | awk '{print ($1 < 25000) || ($1 > 70000)}'` ) # move to the initial divergence divergence.com $div $div | tail -1 | awk '{printf "%s ", $0}' # read the number of counts/s we get set Ifluor = `fluorescence.com 0.5 | awk '$7+0>0{print $1/$7}'` if("$Ifluor" == "") then echo "unable to read fluorescence counts! " echo "Sorry! " goto cleanup endif echo "fluorescence signal is $Ifluor counts/s" # store Izero for normalizing the graph scale set Izero = `blmotor.com Izero | awk '{print $NF; exit}'` if( "$div" == "3" ) then echo "fluorescence is very weak! " echo "make sure the safety shutter is open" set BAD break # goto cleanup endif # calculate proportional adjustment to slits set div = `echo $div $min_div 3 $Ifluor $goal | awk '{div=$1+0;mindiv=$2+0;maxdiv=$3+0;counts=$4+0;goal=$5+0} counts<=10{print $1+0.01;exit} divdiv*2{newdiv=div*2} newdiv
=3{newdiv=3} newdiv! ${scanfile} # make the Izero, Iend in a good range #echo "calibrating Izero..." #echo "autoon\r" | sock_exchange.tcl beamline 10001 1 > /dev/null #sleep 10 # make sure they are not pegged autoscale.com if($status) then set BAD = "no beam" goto cleanup endif stable_signal.com Izero # get a "zero" value for Izero (while the slits are closed) #set div = `divergence.com | tail -1 | awk '{print $(NF-1), $NF}'` #divergence.com $min_div $min_div #usleep $timeconstant #set Izero_dark = `blmotor.com Izero | awk '{print $NF}'` #echo '"dark" Izero is '"$Izero_dark nA" #divergence.com $div > /dev/null set Izero_dark = 0 # make sure autoscale is okay shutter.com open autoscale.com if($status) then set BAD = "no beam" goto cleanup endif shutter.com close if(! $?NODISPLAY) then # make a temporary GNUplot instruction file for live updates cat << EOF >! ${tempfile}.plot set title "8.3.1 $* Fluorescence Scan\n${scanfile}" set data style linespoints set grid set xrange [${start}:${end}] set yrange [:10000] pause 3 plot '${scanfile}' using 1:2 axis x1y1 ti "counts/s", '${scanfile}' using 1:2:(sqrt(\$2*$expose)) axis x1y1 ti "sigma(counts/s)" with errorbars, '${scanfile}' using 1:(\$2/\$3) axis x1y2 ti "counts/s/Izero" reread EOF set pids = `ps -l | awk '$NF~/^gnuplot/ || $NF~/Benny/ || $NF~/Chooch/ || $NF~/pgxwin_se/{print $4}'` if("$pids" != "") kill $pids >& /dev/null endif set energy = $start wave.com $start sleep 2 echo "Energy Fluor Izero Iend epoch" set steps = 0 while ( `echo "$energy $end" | awk '{print ($1 < $2)}'` ) @ steps = ( $steps + 1 ) if (! $?NODISPLAY ) then # fire up the live gnuplot (after a certain amount of steps) if($steps > 2) then set pids = `ps -l | awk '$NF~/^gnuplot/{print $4}'` if("$pids" == "") then ( gnuplot ${tempfile}.plot & ) >& /dev/null endif endif endif foreach repeat ( 1 ) # test repeatability of mono #wave.com 11000 | awk '/Energy: /{print $2} /elapsed/{printf "%s ", $1}' #sleep 6 wave.com $energy | awk '/Energy: /{printf "%s ", $2}' | tee -a ${scanfile} wait_for_beam.com # start counting fluorescent photons set Ifluor = `fluorescence.com $expose $Ee | awk '$7+0>0{print $1/$7}'` # do it again if we get one of those weird failures set retries = 5 while ($retries && ("$Ifluor" == "")) echo "bad read of fluorescence counts... (restart dcss?)" set Ifluor = `fluorescence.com $expose $Ee | awk '$7+0>0{print $1/$7}'` @ retries = ( $retries - 1 ) end if ("$Ifluor" == "") then set BAD = "unable to read fluorescence counts" goto cleanup endif # get other signals from bl computer set Izero = `blmotor.com Izero | awk -v dark=$Izero_dark '{print $NF-dark}'` set Iend = `blmotor.com Iend | awk '{print $NF}'` set now = `echo "puts [clock seconds]" | tclsh` # back this up for later? if(-e spectrum.txt) mv spectrum.txt ${scanfile}_${energy}.subscan echo "$Ifluor $Izero $Iend $now" | tee -a ${scanfile} if ( `echo $Ifluor | awk '$1>300000{print 1}'` && $?optimize ) then echo "detector has saturated! " if(! $?saturated) set saturated set saturated = ( $saturated $energy ) if ($#saturated > 5) goto check_saturation endif end # determine next energy step to use if(! $?evenstep) then # set energy = `echo $energy $step $edge | awk '{step = $2 + 0.5*sqrt(($1-$3)^2); if(step>10)step=10; print $1+step}'` set energy = `echo $energy $step $edge | awk '{step = $2 + 0.1*sqrt(($1-$3)^2); if(step>10)step=10; if(sqrt(($1-$3)^2)<15)step=$2; print $1+step}'` else set energy = `echo $energy $step $edge | awk '{print $1 + $2}'` endif end check_saturation: if ($?saturated) then set mean_sat_energy = `echo $saturated | awk '{for(i=1;i<=NF;++i) sum+=$i; print sum/NF}'` echo "detector saturated at $saturated" wave.com $mean_sat_energy echo "trying again..." unset saturated goto slits endif set peak = `sort -nr +1 ${scanfile} | awk '{print $1;exit}'` set half = `sort -nr +1 ${scanfile} | awk 'NR==1{max=$2} END{print (max-$2)/2+$2}'` set mid = `awk -v half=$half -v peak=$peak 'sqrt(($1-peak)^2) < 6{print $1,sqrt(($2-half)^2)}' ${scanfile} | sort -nr +1 | awk '{print $1;exit}'` set mid = `awk -v half=$half '{print $1,sqrt(($2-half)^2)}' ${scanfile} | sort -n +1 | awk '{print $1;exit}'` echo "" echo "peak energy: $peak eV" echo "inflection maybe: $mid eV" echo "" shutter.com close diode.com out scintillator.com out #wave.com $peak echo "" echo "##### to replot ########" echo "gnuplot scan.gnuplot" echo "########################" echo "" interrupt: onintr if( ! $?NODISPLAY ) then #killall gnuplot_x11 #exit rm -f ${tempfile}.plot >& /dev/null #set pids = `ps -l | awk -v pid=$$ '$5==pid && $NF~/^gnuplot/{print $4}'` set pids = `ps -l | awk '$NF~/^gnuplot/{print $4}'` if("$pids" != "") kill $pids >& /dev/null endif # launch a final graph cat << EOF >! scan.gnuplot set title "8.3.1 $* Fluorescence Scan\n${scanfile}" set data style linespoints set grid plot '${scanfile}' using 1:2 axis x1y1 ti "counts/s", '${scanfile}' using 1:2:(sqrt(\$2*$expose)) axis x1y1 ti "sigma(counts/s)" with errorbars, '${scanfile}' using 1:(\$2/\$3) axis x1y2 ti "counts/s/Izero" EOF # zoom in cat << EOF >! scan_close.gnuplot set title "8.3.1 $* Fluorescence Scan\n${scanfile}" set data style linespoints set xrange [${edge}-15:${edge}+15] set xtics 5 set mxtics 5 set grid xtics mxtics plot '${scanfile}' using 1:2 axis x1y1 ti "counts/s", '${scanfile}' using 1:2:(sqrt(\$2*$expose)) axis x1y1 ti "sigma(counts/s)" with errorbars, '${scanfile}' using 1:(\$2/\$3) axis x1y2 ti "counts/s/Izero" EOF if( ! $?NODISPLAY ) then cat scan.gnuplot - << EOF | gnuplot -persist set terminal postscript set output "| lp" replot set output set terminal X11 EOF cat scan_close.gnuplot - << EOF | gnuplot -persist set terminal postscript set output "| lp" replot set output set terminal X11 EOF endif goto cleanup # do a CHOOCH run echo "$scanfile" >! chooch.raw cat ${scanfile} | wc -l >> chooch.raw cat ${scanfile} |\ awk '{print $1,$2/$3}' |\ cat >> chooch.raw Chooch.sh $Ee K chooch & goto cleanup onintr if(! $?NODISPLAY) then # kill any gnuplot windows set pids = `ps -l | awk '$NF~/^gnuplot/{print $4}'` if("$pids" != "") kill $pids >& /dev/null endif cleanup: onintr shutter.com close diode.com out attenuator.com out attenuator.com Cu out scintilator.com out # get another "zero" value for Izero (while the slits are closed) if(! $?BAD) then # set div = `divergence.com | tail -1 | awk '{print $(NF-1), $NF}'` # divergence.com $min_div $min_div > /dev/null # usleep $timeconstant # set Izero_dark = `echo "getpos Izero\r" | sock_exchange.tcl beamline 10001 1 | awk '{print $1*1}'` # echo '"dark" Izero is '"$Izero_dark nA" # divergence.com $div > /dev/null endif if(! $?NOOPTIMIZE) then # move slits back to where we started divergence.com $old_div # set back to default if divergance is ridiculously low set test = `echo $old_div | awk 'NF>1{printf "%d", $1*$2*10000}'` if($test < 100) then echo "divergence is really low..." divergence.com 2.0 0.3 endif endif if($?BAD) exit 9 exit # curve fit this stuff? gnuplot plot 'scan.log' using 1:2 set xrange [0:10] a=1 b=0 c=2 n=10 xmid=0.5 w=0.01 x0=12610 f(x) = a*((w*(x-x0))**n)/(xmid**n + (w*(x-x0))**n)+b*x+c fit f(x) 'scan.log' except via a,c,x0 plot 'scan.log', f(x)