* update after a1-a6 drive * intrduction of targets - POLDI writing - Moved HKL calculation 4 TRICS to fourlib
499 lines
16 KiB
Tcl
499 lines
16 KiB
Tcl
#---------------------------------------------------------------------------
|
|
# peaksearch a peak search utility for TRICS using the PSD detectors.
|
|
#
|
|
# Mark Koennecke, November 2001
|
|
#---------------------------------------------------------------------------
|
|
|
|
proc initPeakSearch {} {
|
|
|
|
#------- phi Range
|
|
VarMake ps.phiStart Float User
|
|
ps.phiStart 0
|
|
VarMake ps.phiEnd Float User
|
|
ps.phiEnd 180
|
|
VarMake ps.phiStep Float User
|
|
ps.phiStep 3.
|
|
|
|
#-------- chi range
|
|
VarMake ps.chiStart Float User
|
|
ps.chiStart 0
|
|
VarMake ps.chiEnd Float User
|
|
ps.chiEnd 180
|
|
VarMake ps.chiStep Float User
|
|
ps.chiStep 12.
|
|
|
|
#-------- omega range
|
|
VarMake ps.omStart Float User
|
|
ps.omStart 0
|
|
VarMake ps.omEnd Float User
|
|
ps.omEnd 30
|
|
VarMake ps.omStep Float User
|
|
ps.omStep 3.
|
|
|
|
#------- two theta range
|
|
VarMake ps.sttStart Float User
|
|
ps.sttStart 5
|
|
VarMake ps.sttEnd Float User
|
|
ps.sttEnd 70
|
|
VarMake ps.sttStep Float User
|
|
ps.sttStep 3.
|
|
|
|
#------- maximum finding parameters
|
|
VarMake ps.threshold Int User
|
|
ps.threshold 30
|
|
VarMake ps.steepness Int User
|
|
ps.steepness 3
|
|
VarMake ps.window Int User
|
|
ps.window 7
|
|
VarMake ps.cogwindow Int User
|
|
ps.cogwindow 60
|
|
VarMake ps.cogcontour Float User
|
|
ps.cogcontour .2
|
|
|
|
#-------- counting parameters
|
|
VarMake ps.countmode Text User
|
|
ps.countmode monitor
|
|
VarMake ps.preset Float User
|
|
ps.preset 1000
|
|
|
|
#-------- final scan counting parameters
|
|
VarMake ps.scanpreset Float User
|
|
ps.scanpreset 1000000
|
|
VarMake ps.scansteps Int User
|
|
ps.scansteps 24
|
|
|
|
#--------- file to which to write the results
|
|
VarMake ps.listfile Text User
|
|
ps.listfile peaksearch.dat
|
|
|
|
#--------- conversion factors from Pixel to mm
|
|
VarMake xfactor Float Mugger
|
|
xfactor 0.715
|
|
VarMake yfactor Float Mugger
|
|
yfactor 1.42
|
|
|
|
#--------- published functions
|
|
Publish ps.phirange User
|
|
Publish ps.chirange User
|
|
Publish ps.omrange User
|
|
Publish ps.sttrange User
|
|
Publish ps.countpar User
|
|
Publish ps.scanpar User
|
|
Publish ps.maxpar User
|
|
Publish ps.list User
|
|
Publish ps.listpeaks User
|
|
Publish ps.run User
|
|
Publish ps.continue User
|
|
Publish ps.scanlist User
|
|
#------- these are for debugging only!
|
|
Publish checkomega User
|
|
Publish optimizedetector User
|
|
Publish optimizepeak User
|
|
Publish printpeak User
|
|
Publish initsearch User
|
|
Publish catchdrive User
|
|
Publish catchdriveval User
|
|
Publish scandetectorsD User
|
|
Publish scandetectors User
|
|
}
|
|
#--------------------------------------------------------------------------
|
|
proc ps.phirange args {
|
|
if { [llength $args] >= 3 } {
|
|
ps.phiStart [lindex $args 0]
|
|
ps.phiEnd [lindex $args 1]
|
|
ps.phiStep [lindex $args 2]
|
|
}
|
|
clientput "Peak Search Phi Range:"
|
|
return [format " Start = %6.2f, End = %6.2f, Step = %6.2f" \
|
|
[SplitReply [ps.phiStart]] [SplitReply [ps.phiEnd]] \
|
|
[SplitReply [ps.phiStep]]]
|
|
}
|
|
#--------------------------------------------------------------------------
|
|
proc ps.chirange args {
|
|
if { [llength $args] >= 3 } {
|
|
ps.chiStart [lindex $args 0]
|
|
ps.chiEnd [lindex $args 1]
|
|
ps.chiStep [lindex $args 2]
|
|
}
|
|
clientput "Peak Search Chi Range:"
|
|
return [format " Start = %6.2f, End = %6.2f, Step = %6.2f" \
|
|
[SplitReply [ps.chiStart]] [SplitReply [ps.chiEnd]] \
|
|
[SplitReply [ps.chiStep]]]
|
|
}
|
|
#--------------------------------------------------------------------------
|
|
proc ps.omrange args {
|
|
if { [llength $args] >= 3 } {
|
|
ps.omStart [lindex $args 0]
|
|
ps.omEnd [lindex $args 1]
|
|
ps.omStep [lindex $args 2]
|
|
}
|
|
clientput "Peak Search Omega Range:"
|
|
return [format " Start = %6.2f, End = %6.2f, Step = %6.2f" \
|
|
[SplitReply [ps.omStart]] [SplitReply [ps.omEnd]] \
|
|
[SplitReply [ps.omStep]]]
|
|
}
|
|
#--------------------------------------------------------------------------
|
|
proc ps.sttrange args {
|
|
if { [llength $args] >= 3 } {
|
|
ps.sttStart [lindex $args 0]
|
|
ps.sttEnd [lindex $args 1]
|
|
ps.sttStep [lindex $args 2]
|
|
}
|
|
clientput "Peak Search Two Theta Range:"
|
|
return [format " Start = %6.2f, End = %6.2f, Step = %6.2f" \
|
|
[SplitReply [ps.sttStart]] [SplitReply [ps.sttEnd]] \
|
|
[SplitReply [ps.sttStep]]]
|
|
}
|
|
#-------------------------------------------------------------------------
|
|
proc ps.countpar args {
|
|
if { [llength $args] >= 2 } {
|
|
if { [catch {counter setmode [lindex $args 0]} msg] != 0} {
|
|
error "ERROR: Invalid countmode specified"
|
|
}
|
|
ps.countmode [lindex $args 0]
|
|
ps.preset [lindex $args 1]
|
|
}
|
|
clientput "Peak Search Count Parameters:"
|
|
return [format " Mode = %s, Preset = %12.2f" \
|
|
[SplitReply [ps.countmode]] [SplitReply [ps.preset]]]
|
|
}
|
|
#-------------------------------------------------------------------------
|
|
proc ps.scanpar args {
|
|
if { [llength $args] >= 2 } {
|
|
ps.scanpreset [lindex $args 0]
|
|
ps.scansteps [lindex $args 1]
|
|
}
|
|
clientput "Peak Search Scan Parameters:"
|
|
return [format " Count Preset = %12.2f, No. Steps %4d" \
|
|
[SplitReply [ps.scanpreset]] [SplitReply [ps.scansteps]]]
|
|
}
|
|
#-------------------------------------------------------------------------
|
|
proc ps.maxpar args {
|
|
if { [llength $args] >= 5 } {
|
|
ps.window [lindex $args 0]
|
|
ps.threshold [lindex $args 1]
|
|
ps.steepness [lindex $args 2]
|
|
ps.cogwindow [lindex $args 3]
|
|
ps.cogcontour [lindex $args 4]
|
|
}
|
|
clientput "Peak Search Maximum Detection Parameters:"
|
|
set t1 [format " Window = %d, Threshold = %d * average, Steepness = %d" \
|
|
[SplitReply [ps.window]] [SplitReply [ps.threshold]] \
|
|
[SplitReply [ps.steepness] ]]
|
|
set t2 [format " COGWindow = %d, COGcontour = %f " \
|
|
[SplitReply [ps.cogwindow]] [SplitReply [ps.cogcontour]]]
|
|
return [format "%s\n%s" $t1 $t2]
|
|
}
|
|
#-----------------------------------------------------------------------
|
|
proc ps.list {} {
|
|
clientput [ps.sttrange]
|
|
clientput [ps.omrange]
|
|
clientput [ps.chirange]
|
|
clientput [ps.phirange]
|
|
clientput [ps.countpar]
|
|
clientput [ps.scanpar]
|
|
clientput [ps.maxpar]
|
|
}
|
|
#------------------------------------------------------------------------
|
|
proc string2list {txt} {
|
|
return [split [string trim $txt \{\}]]
|
|
}
|
|
#------------------------------------------------------------------------
|
|
proc checknewomega {hm x y omega maxIntensity} {
|
|
if {[catch {drive om $omega} msg] != 0} {
|
|
error $msg
|
|
}
|
|
if {[catch {hmc start [SplitReply [ps.preset]] [string trim [SplitReply \
|
|
[ps.countmode]]]} msg] != 0} {
|
|
error $msg
|
|
}
|
|
if {[catch {Success} msg] != 0} {
|
|
error $msg
|
|
}
|
|
if { [catch {lomax cog $hm $x $y} result] != 0} {
|
|
error "Failed to calculate COG: $result"
|
|
}
|
|
set result [split $result " "]
|
|
if {[lindex $result 2] > $maxIntensity } {
|
|
return $result
|
|
} else {
|
|
return 0
|
|
}
|
|
}
|
|
#------------------------------------------------------------------------
|
|
proc optimizedetector {hm} {
|
|
if { [catch {lomax stat $hm} result] != 0} {
|
|
#--- This can be due to the fact that the detector is missing. Sigh ....
|
|
return
|
|
}
|
|
set l2 [split [string trim $result]]
|
|
lomax threshold [expr [lindex $l2 0] * [SplitReply [ps.threshold]]]
|
|
set result [lomax search $hm]
|
|
set oldom [SplitReply [om]]
|
|
set result [split $result @]
|
|
for {set i 0} { $i < [llength $result]} {incr i} {
|
|
if { [catch {drive om $oldom} msg] != 0} {
|
|
error $msg
|
|
}
|
|
set piecks [split [lindex $result $i] " "]
|
|
set x [lindex $piecks 0]
|
|
set y [lindex $piecks 1]
|
|
if { [catch {optimizepeak $hm $x $y} msg] != 0} {
|
|
clientput [format "Aborted peak at %d %d with %s" $x $y $msg]
|
|
}
|
|
}
|
|
}
|
|
#------------------------------------------------------------------------
|
|
proc optimizepeak {hm x y} {
|
|
if { [catch {lomax cog $hm $x $y} result] != 0} {
|
|
error "Failed to calculate COG: $result"
|
|
}
|
|
set result [split $result " "]
|
|
set xMax [lindex $result 0]
|
|
set yMax [lindex $result 1]
|
|
set maxIntensity [lindex $result 2]
|
|
set maxOmega [SplitReply [om]]
|
|
set startOmega $maxOmega
|
|
set omSearchStep .1
|
|
#--------- move to positive omega until maximum found
|
|
while {1} {
|
|
set newOm [expr [SplitReply [om]] + $omSearchStep]
|
|
if {[catch {checknewomega $hm $xMax $yMax $newOm $maxIntensity} \
|
|
result] != 0} {
|
|
error $result
|
|
}
|
|
if {$result != 0} {
|
|
set xMax [lindex $result 0]
|
|
set yMax [lindex $result 1]
|
|
set maxIntensity [lindex $result 2]
|
|
set maxOmega [SplitReply [om]]
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
#--------- if maxOmega is still startOmega then we were on the right
|
|
# side of the peak. In this case try to find the maximum in
|
|
# negative direction
|
|
if {$maxOmega == $startOmega} {
|
|
while {1} {
|
|
set newOm [expr [SplitReply [om]] - $omSearchStep]
|
|
if {[catch {checknewomega $hm $xMax $yMax $newOm $maxIntensity} \
|
|
result] != 0} {
|
|
error $result
|
|
}
|
|
if {$result != 0} {
|
|
set xMax [lindex $result 0]
|
|
set yMax [lindex $result 1]
|
|
set maxIntensity [lindex $result 2]
|
|
set maxOmega [SplitReply [om]]
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
#----------- print the results we have found
|
|
printpeak $hm $xMax $yMax $maxOmega $maxIntensity
|
|
#------------ scan the peak for Oksana
|
|
# set scanStart [expr $maxOmega - 0.1*([SplitReply [ps.scansteps]]/2)]
|
|
# if { [catch {tricsscan $scanStart .1 [SplitReply [ps.scansteps]] \
|
|
# [SplitReply [ps.countmode]] [SplitReply [ps.scanpreset]]} msg] } {
|
|
# error $msg
|
|
# }
|
|
}
|
|
#---------------------------------------------------------------------------
|
|
proc printpeak {hm x y om intensity} {
|
|
set phval [SplitReply [phi]]
|
|
set chval [SplitReply [chi]]
|
|
set gamOffset .0
|
|
switch $hm {
|
|
hm1 {
|
|
set tilt [SplitReply [dg1]]
|
|
set gamOffset .0
|
|
}
|
|
hm2 {
|
|
set tilt [SplitReply [dg2]]
|
|
set gamOffset 0.
|
|
}
|
|
hm3 {
|
|
set tilt [SplitReply [dg3]]
|
|
set gamOffset 45.
|
|
}
|
|
default {error "Invalid hm requested in printpeak"}
|
|
}
|
|
set sttval [expr [SplitReply [stt]] + $gamOffset]
|
|
set zero [SplitReply [$hm configure dim0]]
|
|
set xval [expr $x * [SplitReply [xfactor]]]
|
|
set zero [SplitReply [$hm configure dim1]]
|
|
set yval [expr $y * [SplitReply [yfactor]]]
|
|
set line [format "%7.2f%7.2f%7.2f%7.2f%7.2f%7.2f%7.2f%10d" \
|
|
$xval $yval $sttval $om $chval $phval $tilt $intensity]
|
|
clientput "Found Peak at:"
|
|
clientput $line
|
|
set f [open [string trim [SplitReply [ps.listfile]]] a+]
|
|
puts $f $line
|
|
close $f
|
|
}
|
|
#--------------------------------------------------------------------------
|
|
proc ps.listpeaks {} {
|
|
clientput "Peakse found so far: "
|
|
clientput " X Y STT OM CHI PHI TILT INTENSITY"
|
|
set f [open [string trim [SplitReply [ps.listfile]]] r]
|
|
while {[gets $f line] > 0} {
|
|
clientput [format "%s" $line]
|
|
}
|
|
close $f
|
|
}
|
|
#-------------------------------------------------------------------------
|
|
proc initsearch {filename} {
|
|
#----- stow away filename and empty it
|
|
ps.listfile $filename
|
|
set f [open $filename w]
|
|
close $f
|
|
#----- tell lomax its parameters
|
|
lomax threshold [SplitReply [ps.threshold]]
|
|
lomax steepness [SplitReply [ps.steepness]]
|
|
lomax window [SplitReply [ps.window]]
|
|
lomax cogwindow [SplitReply [ps.cogwindow]]
|
|
lomax cogcontour [SplitReply [ps.cogcontour]]
|
|
#----- drive to start
|
|
if { [catch {drive stt [SplitReply [ps.sttStart]] \
|
|
om [SplitReply [ps.omStart]] \
|
|
chi [SplitReply [ps.chiStart]] \
|
|
phi [SplitReply [ps.phiStart]] } msg] != 0} {
|
|
error $msg
|
|
}
|
|
}
|
|
#------------------------------------------------------------------------
|
|
# This code means: ignore any errors except interrupts when searching
|
|
|
|
proc scandetectors {} {
|
|
# set names [list hm1 hm2 hm3]
|
|
set names [list hm2 hm3]
|
|
if {[catch {hmc start [SplitReply [ps.preset]] [string trim [SplitReply \
|
|
[ps.countmode]]]} msg] != 0} {
|
|
if{[string compare [getint] continue] != 0} {
|
|
error $msg
|
|
} else {
|
|
clientput [format "Ignoring: %s" $msg]
|
|
}
|
|
}
|
|
if {[catch {Success} msg] != 0} {
|
|
if{[string compare [getint] continue] != 0} {
|
|
error $msg
|
|
} else {
|
|
clientput [format "Ignoring: %s" $msg]
|
|
}
|
|
}
|
|
for {set i 0} { $i < [llength $names]} {incr i} {
|
|
set ret [catch {optimizedetector [lindex $names $i]} msg]
|
|
if { $ret != 0} {
|
|
if {[string compare [getint] continue] != 0} {
|
|
error $msg
|
|
} else {
|
|
clientput [format "Ignoring problem: %s" $msg]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#------------------------------------------------------------------------
|
|
# loop debugging
|
|
|
|
proc scandetectorsD {} {
|
|
clientput [format "stt = %6.2f, om = %6.2f, chi = %6.2f, phi = %6.2f" \
|
|
[SplitReply [stt]] [SplitReply [om]] \
|
|
[SplitReply [chi]] [SplitReply [phi]]]
|
|
wait 1
|
|
}
|
|
#-----------------------------------------------------------------------
|
|
proc catchdrive { mot step} {
|
|
set ret [catch {drive $mot [expr [SplitReply [$mot]] + $step]} msg]
|
|
if {$ret != 0} {
|
|
if {[string compare [getint] continue] != 0} {
|
|
error $msg
|
|
} else {
|
|
clientput [format "Ignoring: %s" $msg]
|
|
}
|
|
}
|
|
}
|
|
#-----------------------------------------------------------------------
|
|
proc catchdriveval { mot val} {
|
|
set ret [catch {drive $mot $val} msg]
|
|
if {$ret != 0} {
|
|
if {[string compare [getint] continue] != 0} {
|
|
error $msg
|
|
} else {
|
|
clientput [format "Ignoring: %s" $msg]
|
|
}
|
|
}
|
|
}
|
|
#------------------------------------------------------------------------
|
|
# The actual loop. It is written in a way which allows for the continuation
|
|
# of a search
|
|
|
|
proc searchloop { } {
|
|
set sttStep [SplitReply [ps.sttStep]]
|
|
set sttEnd [SplitReply [ps.sttEnd]]
|
|
set chiStep [SplitReply [ps.chiStep]]
|
|
set chiEnd [SplitReply [ps.chiEnd]]
|
|
set phiStep [SplitReply [ps.phiStep]]
|
|
set phiEnd [SplitReply [ps.phiEnd]]
|
|
set omStep [SplitReply [ps.omStep]]
|
|
set omEnd [SplitReply [ps.omEnd]]
|
|
while {[SplitReply [stt]] + $sttStep <= $sttEnd} {
|
|
while {[SplitReply [chi]] + $chiStep <= $chiEnd} {
|
|
while {[SplitReply [om]] + $omStep <= $omEnd} {
|
|
while {[SplitReply [phi]] + $phiStep <= $phiEnd} {
|
|
scandetectors
|
|
catchdrive phi $phiStep
|
|
}
|
|
catchdrive om $omStep
|
|
catchdriveval phi [SplitReply [ps.phiStart]]
|
|
}
|
|
catchdrive chi $chiStep
|
|
catchdriveval om [SplitReply [ps.omStart]]
|
|
}
|
|
catchdrive stt $sttStep
|
|
catchdriveval chi [SplitReply [ps.chiStart]]
|
|
}
|
|
return "Peak Search finished normally"
|
|
}
|
|
#---------------------------------------------------------------------------
|
|
proc ps.run {filename} {
|
|
initsearch $filename
|
|
searchloop
|
|
}
|
|
#-------------------------------------------------------------------------
|
|
proc ps.continue {} {
|
|
searchloop
|
|
}
|
|
#------------------------------------------------------------------------
|
|
proc ps.scanlist {} {
|
|
if { [catch {set f [open [string trim [SplitReply [ps.listfile]]] "r"]} \
|
|
msg ] != 0} {
|
|
error $msg
|
|
}
|
|
while { [gets $f line] > 0} {
|
|
set n [stscan $line "%f %f %f %f %f %f" x y stt om chi phi]
|
|
if {$n < 6} {
|
|
clientput [format "Skipping invalid line: %s" line]
|
|
continue
|
|
}
|
|
if { [catch {drive stt $stt om $om chi $chi phi $phi} msg] != 0 } {
|
|
clientput $msg
|
|
if {[string compare [getint] continue] != 0} {
|
|
error "ps.scanlist interupted"
|
|
}
|
|
}
|
|
set scanStart [expr $om - 0.1*([SplitReply [ps.scansteps]]/2)]
|
|
if { [catch {tricsscan $scanStart .1 [SplitReply [ps.scansteps]] \
|
|
[SplitReply [ps.countmode]] [SplitReply [ps.scanpreset]]} msg] \
|
|
!= 0 } {
|
|
clientput $msg
|
|
if {[string compare [getint] continue] != 0} {
|
|
error "ps.scanlist interupted"
|
|
}
|
|
}
|
|
}
|
|
close $f
|
|
return "Scanning list finished"
|
|
} |