Files
sics/peaksearch.tcl
cvs 1e60f3be82 - Many fixes to the triple axis stuff
* update after a1-a6 drive
  * intrduction of targets
- POLDI writing
- Moved HKL calculation 4 TRICS to fourlib
2002-01-25 14:48:50 +00:00

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"
}