PSI sics-cvs-psi_pre-ansto
This commit is contained in:
499
peaksearch.tcl
Normal file
499
peaksearch.tcl
Normal file
@@ -0,0 +1,499 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# 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"
|
||||
}
|
||||
Reference in New Issue
Block a user