#! /usr/bin/expectk # # PROGRAM: dfm # AUTHOR: Cormac Purcell, UNSW # PURPOSE: A GUI wrapper for the spectral line reduction program SPC used at Mopra and Parkes # Designed to allow easy reduction of position switched spectra # CREATES: Reduced fits or sdf files with quotient performed on alternate sets of n scans # COMMENTS: Support for different schedule files must be hard coded into program for now. # UPDATED: 30/10/03 # # # CHANGELOG: # 31/10/03 Header variables now transfered correctly from Pol B to A when copying # "info-all" routine now updates information each time a scan is selected # Tsys and Integration time displayed in the feedback window on scan selection # Added option to reduce "ON-OFF, OFF-ON" data # # 13/11/03 Added an option to shift the frequency scale simultaneously with the velocity scale. # Procedures written to calculate the 0 vel freq from the header information. Incurs a # slight error in the calculation due to rounding, not significant at 3mm. # # 30/11/03 The Mopra TCS Scaling Error was incorrectly corrected for previous to this date. Previously # the scaling corrections were applied before forming the quotient, leading to them being # canceled out. Two options have now replaced the old routine: # 1) Scale the Tsig and Tref values # 2) Directly scale the amplitude after the quotient has been formed. # Both scale the data correctly, but one scales the tsys also (Need to find out which is correct) # Improved support for large files and other telescopes. # # 04/12/03 The date on which the Mopra TCS Scaling Error was previously applied was erroneous. # Prior to this date it was assumed that the error affected data previous to 05th Sept 02, # however the error was intermittant and affected data between 2001-05-15_01:15 and # 2002-09-05_14:18, and again between 2002-09-06_14:02 and 2002-09-17_21:10. The # function to correct the Tsys has been altered to these dates. # # 10/12/03 Fixed Tsys correction to scale redundant header variable 8202. FITS writer uses this value # to fill the Tsys header variable. # # 26/12/03 Fixed problem with the align command in spc - frequency is not aligned with velocity and # redundant velocity header 8199 is not shifted accordingly. This could cause a problem with # spectra fixed with "moprafix.pl" where a rounding jump occured- the line frequency would be # incorrectly reported and the any velocity shifts calculated based on this frequency would be # in error. # # Implemented a more accurate method of calculating a velocity shift from the line frequency # based on the vel/channel and freq/channel # # 19/02/04 Added settings buttons: # Remove continuum? Allows choice to remove continuum when forming quotient. # Clip Edge Channels: Setting the plot edges. # Rest Frame: Choose between LSR-K and BARY rest frames. # Added "Smooth" button- hanning smooths the current scan. # # 20/02/04 Added routine to enable saving to ascii .dat files for plotting in super mongo # # # WISHLIST: # Better check for incorrectly entered parameters (e.g. baseline boxes) # ################################################################################################## wm title . "Data From Mopra ( Last Updated 20/02/04 - See changelog for details )" # DECLARE GLOBAL VARIABLES global prompt timeout nscans source date a_colour b_colour outdir indir outfile obs_freq obs_freq_calc cent_freq offset choicelist global polname n_channels chan_range chan_rangea chan_rangeb plot_range plot_rangea plot_rangeb global zero_range_l zero_range_r zero_rangea_l zero_rangea_r zero_rangeb_l zero_rangeb_r global boxchan_left boxchan_right boxchan_a_left boxchan_a_right boxchan_b_left boxchan_b_right poly_order poly_mema poly_memb global pstate index_lsta index_lstb cur_sel stor_sel stat_box stat_txt sleep_time utc rest_choice global save_opt quotient_choice tel_state load_choice load_method scale_choice freq_check freq_step cont_choice clip_left clip_right set scale_choice "yes" # GET THE LAST SAVED SETTINGS FROM THE HIDDEN FILE OR DEFINE INITIAL VALUES if [file exists "~/.dfm_settings"] { set settings [open ~/.dfm_settings r] gets $settings indir gets $settings filename gets $settings outdir gets $settings tel_state gets $settings load_choice gets $settings load_method gets $settings quotient_choice gets $settings quotient_order gets $settings scaling_choice gets $settings cont_choice gets $settings clip_left gets $settings clip_right gets $settings rest_choice close $settings } else { set indir "[exec pwd]/" set filename "Enter filename here" set outdir $indir set tel_state "Mopra" set load_choice "rpf" set load_method "auto" set quotient_choice "1" set quotient_order "offon" set scaling_choice "1" set cont_choice "n" set clip_left "50" set clip_right "50" set rest_choice "LSRK" } # SET THE INITIAL VARIABLES NECESSARY TO DISPLAY THE GUI set save_opt "sdf file" set a_colour #aaf99a set b_colour #fce658 set polname "Pol A" set pstate 1 set offset 0.0 set freq_check 0 set timeout 10 set sleeptime 0.3 set tcl_precision 17 # NOW START SPC log_user 1 spawn spc ######################################################################################################### # DEFINE THE PROC FUNCTIONS BEFORE SETTING OUT THE GUI ################################################## # FEEDBACK THROUGH THE EMBEDDED TEXT-BOX proc feedback { msg } { global prompt $prompt insert end "$msg\n" $prompt see end } # POPUP MESSAGE BOX proc message { msg } { if [catch {toplevel .message_popup} result ] { raise .message_popup } else { # CREATE THE POPUP WINDOW wm title .message_popup "!" frame .message_popup.border -relief solid -borderwidth 2 label .message_popup.border.entry -text $msg -relief flat button .message_popup.border.ok_button -relief groove -text "OK" -command { destroy .message_popup } pack .message_popup.border.entry -side top -fill both pack .message_popup.border.ok_button -side top -fill x pack .message_popup.border -side top -fill x -padx 3 -pady 2 grab .message_popup } } # INITIALISE THE PLOTTING VARIABLES ON LOAD TO DEFAULT VALUES proc init { } { global n_channels chan_rangea_l chan_rangea_r chan_rangea global chan_rangeb_l chan_rangeb_r chan_rangeb chan_range global plot_rangea_l plot_rangea_r plot_rangea global plot_rangeb_l plot_rangeb_r plot_rangeb plot_range global polname chan_rangea_l clip_left clip_right set chan_rangea_l "1" set chan_rangea_r $n_channels set chan_rangea "$chan_rangea_l-$chan_rangea_r" set chan_rangeb_l [expr $n_channels + 1] set chan_rangeb_r [expr $chan_rangea_r + $n_channels] set chan_rangeb "$chan_rangeb_l-$chan_rangeb_r" set plot_rangea_l [expr $chan_rangea_l + $clip_left] set plot_rangea_r [expr $chan_rangea_r - $clip_right] set plot_rangea "$plot_rangea_l-$plot_rangea_r" set plot_rangeb_l [expr $chan_rangeb_l + $clip_left] set plot_rangeb_r [expr $chan_rangeb_r - $clip_right] set plot_rangeb "$plot_rangeb_l-$plot_rangeb_r" if { $polname == "Pol A" } { init_a } elseif {$polname == "Pol B" } { init_b } } # INITALISE TO POL A proc init_a {} { global plot_range plot_rangea polname pstate poly_order poly_mema global chan_range chan_rangea chan_rangea_l chan_rangea_r global boxchan_left boxchan_right boxchan_a_left boxchan_a_right global zero_range_l zero_range_r zero_rangea_l zero_rangea_r stat_box global a_colour set plot_range $plot_rangea set chan_range $chan_rangea set polname "Pol A" set pstate 1 catch { .frame3.bb.selections.ch_button configure -text $polname } catch { .frame2.lbox_frm.choices configure -selectbackground $a_colour } # SET THE BASELINE FITTING BOXES FROM THE MEMORY VARIABLES IF THEY EXIST if [info exists boxchan_a_left] { set boxchan_left $boxchan_a_left set boxchan_right $boxchan_a_right set poly_order $poly_mema } else { # DEFINE THE INITIAL BASELINE FITTING BOXES & POLYNOMIAL ORDER set boxchan_left "[expr $chan_rangea_l + 50]-[expr $chan_rangea_l + 350]" set boxchan_right "[expr $chan_rangea_r - 350]-[expr $chan_rangea_r - 50]" set poly_order 3 } # SET THE ZERO RANGE BOX FROM THE MEMORY VARIABLES IF THEY EXIST if [info exists zero_rangea_l] { set zero_range_l $zero_rangea_l set zero_range_r $zero_rangea_r } else { # DEFINE THE INITIAL ZERO RANGE BOX set zero_range_l $chan_rangea_l set zero_range_r "[expr $chan_rangea_l + 100]" } } # INITALISE TO POL B proc init_b {} { global plot_range plot_rangeb polname pstate poly_order poly_memb global chan_range chan_rangeb chan_rangeb_l chan_rangeb_r global boxchan_left boxchan_right boxchan_b_left boxchan_b_right global zero_range_l zero_range_r zero_rangeb_l zero_rangeb_r stat_box global b_colour set plot_range $plot_rangeb set chan_range $chan_rangeb set polname "Pol B" set pstate 2 catch { .frame3.bb.selections.ch_button configure -text $polname } catch { .frame2.lbox_frm.choices configure -selectbackground $b_colour } # SET THE BASELINE FITTING BOXES FROM THE MEMORY VARIABLES IF THEY EXIST if [info exists boxchan_b_left] { set boxchan_left $boxchan_b_left set boxchan_right $boxchan_b_right set poly_order $poly_memb } else { # DEFINE THE INITIAL BASELINE FITTING BOXES, POLYNOMIAL ORDER, AND STATISTICS BOX set boxchan_left "[expr $chan_rangeb_l + 50]-[expr $chan_rangeb_l + 350]" set boxchan_right "[expr $chan_rangeb_r - 350]-[expr $chan_rangeb_r - 50]" set poly_order 3 } # SET THE ZERO RANGE BOX FROM THE MEMORY VARIABLES IF THEY EXIST if [info exists zero_rangeb_l] { set zero_range_l $zero_rangeb_l set zero_range_r $zero_rangeb_r } else { set zero_range_l $chan_rangeb_l set zero_range_r "[expr $chan_rangeb_l + 100]" } } # DIALOG BOX FOR DEFINING THE SCHEDULE FILE AND LOAD METHOD proc settings {} { global load_choice cont_choice load_method clip_left clip_right n_channels rest_choice if [catch {toplevel .settings_popup} result ] { raise .settings_popup } else { wm title .settings_popup "Settings" frame .settings_popup.telescope_frm -relief solid -borderwidth 2 frame .settings_popup.format_frm -relief solid -borderwidth 2 frame .settings_popup.method_frm -relief solid -borderwidth 2 frame .settings_popup.quotient_frm -relief solid -borderwidth 2 frame .settings_popup.scaling_frm -relief solid -borderwidth 2 frame .settings_popup.quotient_frm.frm1 -relief flat -borderwidth 0 frame .settings_popup.quotient_frm.frm2 -relief flat -borderwidth 0 frame .settings_popup.continuum_frm -relief solid -borderwidth 2 frame .settings_popup.continuum_frm.frm1 -relief flat -borderwidth 0 frame .settings_popup.plot_frm -relief solid -borderwidth 2 frame .settings_popup.plot_frm.frm1 -relief flat -borderwidth 0 frame .settings_popup.rest_frm -relief solid -borderwidth 2 frame .settings_popup.rest_frm.frm1 -relief flat -borderwidth 0 radiobutton .settings_popup.telescope_frm.mopra -text "Mopra" -variable tel_state -value "Mopra" radiobutton .settings_popup.telescope_frm.parkes -text "Other" -variable tel_state -value "Other" label .settings_popup.scaling_frm.label -text "TCS scaling error correction:\n(Mopra Only)" checkbutton .settings_popup.scaling_frm.enable -anchor w -text "Enable" -variable scaling_choice radiobutton .settings_popup.format_frm.rpf -text "rpf file" -variable load_choice -value "rpf" radiobutton .settings_popup.format_frm.sdf -text "sdf file" -variable load_choice -value "sdf" radiobutton .settings_popup.method_frm.auto -text "Auto" -variable load_method -value "auto" radiobutton .settings_popup.method_frm.straight -text "Straight" -variable load_method -value "straight" checkbutton .settings_popup.quotient_frm.quotent -anchor w -text "Perform Quotient" -variable quotient_choice radiobutton .settings_popup.quotient_frm.frm1.onoff -text "ON-OFF" -variable quotient_order -value "on_off" radiobutton .settings_popup.quotient_frm.frm1.offon -text "OFF-ON" -variable quotient_order -value "off_on" radiobutton .settings_popup.quotient_frm.frm2.offon_onoff -text "OFF-ON, ON-OFF" -variable quotient_order -value "off_on_on_off" radiobutton .settings_popup.quotient_frm.frm2.onoff_offon -text "ON-OFF, OFF-ON" -variable quotient_order -value "on_off_off_on" label .settings_popup.continuum_frm.label -text "Remove Continuum?" radiobutton .settings_popup.continuum_frm.frm1.remove -text "yes" -variable cont_choice -value "y" radiobutton .settings_popup.continuum_frm.frm1.keep -text "no" -variable cont_choice -value "n" label .settings_popup.plot_frm.label -text "Clip Edge Channels:" label .settings_popup.plot_frm.frm1.l_label -text "Left" entry .settings_popup.plot_frm.frm1.l_box -textvar clip_left -relief sunken -width 3 label .settings_popup.plot_frm.frm1.r_label -text " Right" entry .settings_popup.plot_frm.frm1.r_box -textvar clip_right -relief sunken -width 3 button .settings_popup.ok -relief groove -text "OK" -command { if [info exists n_channels] { init } ; destroy .settings_popup } label .settings_popup.rest_frm.label -text "Rest Frame" radiobutton .settings_popup.rest_frm.frm1.lsrk -text "LSR-K" -variable rest_choice -value "LSRK" radiobutton .settings_popup.rest_frm.frm1.bary -text "BARY" -variable rest_choice -value "BARY" pack .settings_popup.telescope_frm.mopra -side left -padx 2 -pady 1 pack .settings_popup.telescope_frm.parkes -side left -padx 2 -pady 1 pack .settings_popup.format_frm.rpf -side left -padx 2 -pady 1 pack .settings_popup.format_frm.sdf -side left -padx 2 -pady 1 pack .settings_popup.method_frm.auto -side left -padx 2 -pady 1 pack .settings_popup.method_frm.straight -side left -padx 2 -pady 1 pack .settings_popup.telescope_frm -side top -padx 3 -pady 2 -fill x pack .settings_popup.format_frm -side top -padx 3 -pady 2 -fill x pack .settings_popup.method_frm -side top -padx 3 -pady 2 -fill x pack .settings_popup.scaling_frm.label -side top -padx 2 -pady 1 pack .settings_popup.scaling_frm.enable -side top -padx 2 -pady 1 pack .settings_popup.scaling_frm -side top -padx 2 -pady 1 -fill x pack .settings_popup.quotient_frm.frm1.onoff -side left -padx 2 -pady 1 pack .settings_popup.quotient_frm.frm1.offon -side left -padx 2 -pady 1 pack .settings_popup.quotient_frm.frm2.offon_onoff -side top -padx 2 -pady 1 pack .settings_popup.quotient_frm.frm2.onoff_offon -side top -padx 2 -pady 1 pack .settings_popup.quotient_frm.quotent -side top -padx 2 -pady 1 pack .settings_popup.quotient_frm.frm1 -side top -padx 2 -pady 1 pack .settings_popup.quotient_frm.frm2 -side top -padx 2 -pady 1 pack .settings_popup.quotient_frm -side top -padx 2 -pady 1 -fill x pack .settings_popup.continuum_frm.label -side top -padx 2 -pady 1 pack .settings_popup.continuum_frm.frm1 -side top -padx 2 -pady 1 pack .settings_popup.continuum_frm.frm1.remove -side left -padx 2 -pady 1 pack .settings_popup.continuum_frm.frm1.keep -side left -padx 2 -pady 1 pack .settings_popup.continuum_frm -side top -padx 2 -pady 1 -fill x pack .settings_popup.plot_frm.label -side top -padx 2 -pady 1 pack .settings_popup.plot_frm.frm1 -side top -padx 2 -pady 1 pack .settings_popup.plot_frm.frm1.l_label -side left -padx 2 -pady 1 pack .settings_popup.plot_frm.frm1.l_box -side left -padx 2 -pady 1 pack .settings_popup.plot_frm.frm1.r_label -side left -padx 2 -pady 1 pack .settings_popup.plot_frm.frm1.r_box -side left -padx 2 -pady 1 pack .settings_popup.plot_frm -side top -padx 2 -pady 1 -fill x pack .settings_popup.rest_frm.label -side top -padx 2 -pady 1 pack .settings_popup.rest_frm.frm1 -side top -padx 2 -pady 1 pack .settings_popup.rest_frm.frm1.lsrk -side left -padx 2 -pady 1 pack .settings_popup.rest_frm.frm1.bary -side left -padx 2 -pady 1 pack .settings_popup.rest_frm -side top -padx 2 -pady 1 -fill x pack .settings_popup.ok -side top -padx 2 -pady 1 -fill x # bind .settings_popup.telescope_frm.mopra { init } # bind .settings_popup.telescope_frm.parkes { init } grab .settings_popup } } # EVENTS BOUND TO THE LOAD BUTTON proc Load_Button {} { global endreg source indir filename pstate index_lsta index_lstb plot_range tel_state outfile load_choice load_method quotient_choice global date utc scaling_choice sleeptime rest_choice # RESET VARIABLES ASSOCIATED WITH INDIVIDUAL RPF/SDF FILE AS VARIABLES MAY BE INITIALISED FROM PREVIOUS RUN string trim $filename if [info exists index_lsta] { unset index_lsta } if [info exists index_lstb] { unset index_lstb } if [info exists boxchan_a_left] { unset boxchan_a_left } if [info exists boxchan_a_right] { unset boxchan_a_right } if [info exists boxchan_b_left] { unset boxchan_b_left } if [info exists boxchan_b_right] { unset boxchan_b_right } if [info exists outlist] { unset outlist } # SET THE INITIAL CONFIGURATION OF THE BUTTONS .frame3.bb.selections.sel_av configure -state disabled .frame3.bb.operations.fit_button configure -state disabled .frame3.bb.selections.fold configure -state disabled .frame3.bb.operations.zero configure -state disabled .frame3.bb.operations.vel configure -state disabled .frame4.save_frame.bb.save_button configure -state disabled .frame3.bb.selections.ch_button configure -state normal .frame4.save_frame.smooth configure -state disabled if {$filename==""} { message "Enter a file first." return } else { if ![file exists "$indir$filename"] { message "\"$filename\" not found.\nPlease check your directory\nand filename are correct." return } # LOAD BASED ON FILE TYPE AND LOADING CHOICE if { $load_choice == "rpf" } { if { $load_method == "auto" } { loadautorpf } elseif { $load_method == "man" } { loadrpf #combine } elseif { $load_method == "straight" } { loadrpf } } elseif { $load_choice == "sdf" } { if { $load_method == "man" } { loadsdf #combine } elseif { $load_method == "straight" } { loadsdf } else { loadsdf } } info_all 1 # RUN RVEL ON THE RAW SCANS TO CHANGE THE VELOCITY SCALE TO LSR KINEMATIC- works ok expect "Enter Command: " exp_send "rvel\r$rest_choice\r1-256\r" feedback "Using $rest_choice velocity scale..." # SCALE TSYS FOR THE ERRONEOUS 1.51 & 1.73 SCALING FACTORS APPLIED BETWEEN THE FOLLOWING DATES: # 15TH / May / 2001 01:15 => 05TH / SEPT / 2001 14:18 # 06TH / SEPT / 2002 14:02 => 17TH / SEPT / 2002 21:10 if { ($tel_state=="Mopra") && ($scaling_choice=="1") } { set temp [split $date "/"] set year [lindex $temp 0] set month1 [lindex $temp 1] ; set month [stripzeros $month1] set day1 [lindex $temp 2] ; set day [stripzeros $day1] if { $year == 2001 } { if { $month > 5} { feedback "Scaling Tsys by 0.662 & 0.578" for { set i 1 } { $i <= $endreg } { incr i 1 } { scale_tsys 0.662 0.578 $i } } elseif { $month == 5 } { if { $day > 15} { feedback "Scaling Tsys by 0.662 & 0.578" for { set i 1 } { $i <= $endreg } { incr i 1 } { scale_tsys 0.662 0.578 $i } } elseif { ($day == 15) && ($utc >= 4500) } { feedback "Scaling Tsys by 0.662 & 0.578" for { set i 1 } { $i <= $endreg } { incr i 1 } { scale_tsys 0.662 0.578 $i } } } } if { $year == 2002 } { if { $month < 9 } { feedback "Scaling Tsys by 0.662 & 0.578" for { set i 1 } { $i <= $endreg } { incr i 1 } { scale_tsys 0.662 0.578 $i } } elseif { $month == 9 } { if { ($day < 5)} { feedback "Scaling Tsys by 0.662 & 0.578" for { set i 1 } { $i <= $endreg } { incr i 1 } { scale_tsys 0.662 0.578 $i } } elseif { ($day == 5) && ($utc <= 51480) } { feedback "Scaling Tsys by 0.662 & 0.578" for { set i 1 } { $i <= $endreg } { incr i 1 } { scale_tsys 0.662 0.578 $i } } elseif { ($day == 6) && ($utc >= 50520) } { feedback "Scaling Tsys by 0.662 & 0.578" for { set i 1 } { $i <= $endreg } { incr i 1 } { scale_tsys 0.662 0.578 $i } } elseif { ($day > 6) && ($day < 17) } { feedback "Scaling Tsys by 0.662 & 0.578" for { set i 1 } { $i <= $endreg } { incr i 1 } { scale_tsys 0.662 0.578 $i } } elseif { ($day == 17) && ($utc <= 267200) } { feedback "Scaling Tsys by 0.662 & 0.578" for { set i 1 } { $i <= $endreg } { incr i 1 } { scale_tsys 0.662 0.578 $i } } } } } # PERFORM A QUOTENT ON THE SCANS AND RETURN THE LIST OF QUOTENT SPECTRA if { $quotient_choice == "1" } { set outlist [load_quotient] } elseif { $quotient_choice =="0" } { set outlist [makelist] } # ALIGN SCANS IN VELOCITY AND FREQUENCY SPACE align_new [lindex $outlist 0] $outlist # CLEAR THE LISTBOX AND INSERT THE LIST OF SCANS .frame2.lbox_frm.choices delete 0 end foreach item $outlist { .frame2.lbox_frm.choices insert end $item } # RUN 'INFO' TO GET THE DATAFILE PARAMETERS info_all [.frame2.lbox_frm.choices get 0] # ENABLE THE SELECT AND AVERAGE BUTTON, PLOT THE 1ST SCAN .frame3.bb.selections.sel_av configure -state normal # SET THE OUTFILE NAME set outfile [string trimright $source "_RS"] # SET THE PLOTTING PARAMETERS init plot_vel [.frame2.lbox_frm.choices get 0] $plot_range .frame2.lbox_frm.choices select set 0 .frame3.bb.operations.fit_button configure -state normal .frame3.bb.operations.zero configure -state normal .frame3.bb.operations.vel configure -state normal .frame4.save_frame.bb.save_button configure -state normal .frame4.save_frame.smooth configure -state normal sleep $sleeptime raise . return $outlist } } # AUTO-LOADS THE RPF FILE AND READS IN THE NUMBER OF SCANS TAKEN proc loadautorpf { } { global indir filename endreg expect "Enter Command: " exp_send "l.\r$indir$filename\ry\r1\ry\r1-1000\r1-256\r" expect -re "(\\d+)\\s+.{73}\\n\\s{1}End-of-file" set endreg $expect_out(1,string) } # LOADS THE RPF FILE AND READS IN THE NUMBER OF SCANS TAKEN proc loadrpf { } { global indir filename endreg expect "Enter Command: " exp_send "l.\r$indir$filename\rn\ry\r1-256\r1-256\r" expect -re "End-of-file encountered after sequence\\s*(\\d*)" ; # PATTERN MATCH THE NO. OF SCANS set endreg $expect_out(1,string) } # LOADS THE SDF FILE AND READS IN THE NUMBER OF SCANS TAKEN proc loadsdf {} { global indir filename endreg expect "Enter Command: " exp_send "l.\r$indir$filename\r" expect -re "Found an SDFITS file with\\s*(\[\\d]*)\\s*scans" set endreg $expect_out(1,string) exp_send "1-$endreg\r1-256\r" } # COMBINE EVERY N SCANS INTO 1 SCAN - NECESSARY IF AVERAGING IS > 1 CYCLE #proc combine { n } { # # for { set i 1 } { $i <= $endreg } { incr i +[expr $n-1] } { # # for { set j 1} { $j <= 256 } {incr j +1 } { # # averagel "[expr -4 # } # } #} # MULTIPLY THE DATA IN INDIVIDUAL POLARISATIONS BY A SCALING FACTOR proc scale { quad1 quad2 list } { global date expect "Enter Command:" exp_send "sc\r$quad1 $quad2\r$list\r" } # SCALE THE Tsys IN INDIVIDUAL POLARISATIONS BY A SCALING FACTOR proc scale_tsys { quad1 quad2 i } { expect "Enter Command: " exp_send "edit\rn\rn\rl\r8222 8223\r$i\r" expect -re "Reg\\s+Source\\s+8222\\s+8223\\s*\\r*\\s*\[\\d]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)\\s+(\[-|+]*\[\\d]+.\[\\d]+)" set temp_a $expect_out(1,string) set temp_b $expect_out(2,string) # CALCULATION set temp_c [expr $temp_a * $quad1] set temp_d [expr $temp_b * $quad2] # feedback "scan $i: $temp_a -> $temp_c\nscan $i: $temp_b -> $temp_d" expect "Enter Command: " exp_send "edit\rn\rn\re\r8222 8223 8202\rr\r$temp_c $temp_d $temp_c\r$i\r" } # ALIGN THE SCANS IN VELOCITY AND FREQUENCY SPACE proc align_new {ref list} { expect "Enter Command: " exp_send "align\r$ref\r$list\r" expect "Enter Command: " exp_send "edit\rn\rn\rl\r8199 8247 8250 8251\r$ref\r" expect -re "Reg\\s+Source\\s+\[\\d]+\\s+\[\\d]+\\s+\[\\d]+\\s+\[\\d]+\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)\\s*(\[-|+]*\[\\d]+.\[\\d]+)\\s*(\[-|+]*\[\\d]+.\[\\d]+)\\s*(\[-|+]*\[\\d]+.\[\\d]+)" set q1_vshift $expect_out(1,string) set q1_fshift1 $expect_out(2,string) set q1_fshift $expect_out(3,string) set q2_fshift $expect_out(4,string) expect "Enter Command: " exp_send "edit\rn\rn\re\r8199 8247 8250 8251\rr\r$q1_vshift $q1_fshift1 $q1_fshift $q2_fshift\r$list\r" } # A SIMPLE SEQUENTIAL MUMBER GENERATOR proc makelist {} { global endreg for {set count 1 } { $count <= $endreg } { incr count +1 } { lappend outlist $count } return $outlist } # LOAD FILE AND PERFORM A QUOTENT ON EVERY N SCANS proc load_quotient {} { global tel_state endreg startreg currentreg outlist quotient_order # SET REGISTER TRACKING VARIABLES set startreg 1 set currentreg $startreg # PERFORM A QUOTENT ON THE AVERAGED SCANS AND RETURN THE LIST OF QUOTENT SPECTRA set outlist [quotient $endreg $startreg $quotient_order ] return $outlist } # AVERAGES A LIST OF SCANS AND SAVES THEM IN REGISTER X proc averagel { list x } { align_new [lindex $list 0] $list expect "Enter Command: " exp_send "avg\r$x\r$list\r" } # PERFORM A QUOTENT TO REMOVE THE BANDPASS, RETURNS A LIST OF QUOTENT SPECTRA proc quotient { endreg startreg order } { global cont_choice set flip 1 for {set count [expr $startreg + 1]} { $count <= $endreg } { incr count +2 } { if { $order == "off_on" } { expect "Enter Command: " exp_send "q\r$count\r[expr $count - 1]\r$cont_choice\r" lappend outlist $count if { $count != $endreg } { lappend outlist, } } elseif { $order == "on_off" } { expect "Enter Command: " exp_send "q\r[expr $count - 1]\r$count\r$cont_choice\r" lappend outlist [expr $count - 1] if { $count != $endreg } { lappend outlist, } } elseif { $order =="off_on_on_off" } { expect "Enter Command: " if { $flip == 1 } { exp_send "q\r$count\r[expr $count - 1]\r$cont_choice\r" } else { exp_send "q\r[expr $count - 1]\r$count\r$cont_choice\r" } if { $flip == 1 } { lappend outlist $count set flip 2 } else { lappend outlist [expr $count -1] set flip 1 } if { $count != $endreg } { lappend outlist, } } elseif { $order =="on_off_off_on" } { expect "Enter Command: " if { $flip == 1 } { exp_send "q\r[expr $count - 1]\r$count\r$cont_choice\r" } else { exp_send "q\r$count\r[expr $count - 1]\r$cont_choice\r" } if { $flip == 1 } { lappend outlist [expr $count -1] set flip 2 } else { lappend outlist $count set flip 1 } if { $count != $endreg } { lappend outlist, } } } return $outlist } # QUERIES SPC FOR ESSENTIAL PARAMETERS SUCH AS RA, DEC, SOURCE, NO. OF CHANNELS ETC proc info_all { n } { global source date utc ra dec obs_freq cent_freq bandwidth vel_step ch1_vel n_channels plot_range pstate outfile freq_step # READ THE SOURCE NAME FROM THE INFO COMMAND OUTPUT expect "Enter Command: " exp_send "info\r$n\r" expect -re "Source:\\s*(\[^\\s]*)\\s*RA:\\s*(\[-|+]*\[\\d]{2}\\s\[\\d]{2}\\s\[\\d]{2}.\[\\d]+)" set source $expect_out(1,string) set ra $expect_out(2,string) string trim $ra string trim $source exp_send "\r" # READ THE LINE FREQ & DEC FROM THE INFO COMMAND OUTPUT expect -re "Line freq:\\s*(\[^\\s]*)\\s\[^\\s]*\\s*Dec:\\s*(\[-|+]*\[\\d]{2}\\s\[\\d]{2}\\s\[\\d]{2}.\[\\d]+)" set obs_freq $expect_out(1,string) set dec $expect_out(2,string) string trim $dec # READ THE DATE FROM THE INFO COMMAND OUTPUT expect -re "Date:\\s(\[^\\s]{10})\\s*b:" set date $expect_out(1,string) string trim $date # READ THE TIME FROM THE HEADERS expect "Enter Command: " exp_send "edit\rn\rn\rl\r8255\r$n\r" expect -re "Reg\\s+Source\\s+\[\\d]+\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[\\d]+.\[\\d]+)" set utc $expect_out(1,string) # READ THE BANDWIDTH & No. OF CHANNELS FROM THE HEADERS expect "Enter Command: " exp_send "edit\rn\rn\rl\r8226 8218\r$n\r" expect -re "Reg\\s+Source\\s+\[\\d]+\\s+\[\\d]+\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)\\s*(\[-|+]*\[\\d]+.\[\\d]+)" set bandwidth $expect_out(1,string) set n_channels [string trimright $expect_out(2,string) ".0"] # READ THE CENTRE FREQUENCY & CH1 VELOCITY FROM THE HEADERS expect "Enter Command: " exp_send "edit\rn\rn\rl\r[expr 8249 + $pstate] [expr 8233 + $pstate]\r$n\r" expect -re "Reg\\s+Source\\s+\[\\d]+\\s+\[\\d]+\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)\\s*(\[-|+]*\[\\d]+.\[\\d]+)" set cent_freq $expect_out(1,string) set ch1_vel $expect_out(2,string) # READ THE VELOCITY INCREMENT FROM THE HEADERS expect "Enter Command: " exp_send "edit\rn\rn\rl\r[expr 8237 + $pstate]\r$n\r" expect -re "Reg\\s+Source\\s+\[\\d]+\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)" set vel_step $expect_out(1,string) # READ THE FREQUENCY INCREMENT FROM THE HEADERS expect "Enter Command: " exp_send "edit\rn\rn\rl\r8248\r$n\r" expect -re "Reg\\s+Source\\s+\[\\d]+\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)" set freq_step $expect_out(1,string) # NOTE: AS AN ALTERNATIVE TO CALCULATING THE LINE FREQUENCY YOU CAN READ IT WITH THE INFO COMMAND # THIS WORKS ONLY FOR POL A AND WILL REPORT THE SAME LINE FREQ FOR CH B EVEN IF THIS IS NOT THE CASE # CALCULATE THE LINE FREQUENCY - I.E. THE FREQUENCY FOR WHICH THE VELOCITY IS ZERO set n_0 [expr [expr -$ch1_vel / $vel_step ] + 1] #feedback "0 vel channel: $n_0" #set obs_freq [expr ($freq_step * [expr $n_0 - ( $n_channels / 2) - 0.5] + $cent_freq) /1000 ] #set obs_freq [format "%3.6f" $obs_freq] #feedback "obs_freq $obs_freq " # READ THE INT TIME AND THE TSYS FROM THE HEADERS expect "Enter Command: " exp_send "edit\rn\rn\rl\r[expr 8221 + $pstate] [expr 8229 + $pstate]\r$n\r" expect -re "Reg\\s+Source\\s+\[\\d]+\\s+\[\\d]+\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)\\s*(\[-|+]*\[\\d]+.\[\\d]+)" set tsys $expect_out(1,string) set inttime $expect_out(2,string) feedback "$n Tys: $tsys, Int: $inttime" } # SWITCH BETWEEN POLARISATIONS proc switchpol { } { global polname pstate plot_range plot_rangea plot_rangeb chan_range chan_rangea chan_rangeb global chan_rangea_l chan_rangeb_l chan_rangea_r chan_rangeb_r global boxchan_left boxchan_right boxchan_a_left boxchan_a_right boxchan_b_left boxchan_b_right global poly_order poly_mema poly_memb a_colour b_colour global index_lsta index_lstb stat_box if { $polname == "Pol A" } { init_b # SET THE SELECTION LIST FROM THE MEMORY VARIABLES IF THEY EXIST OR CLEAR SELECTION if [info exists index_lstb] { .frame2.lbox_frm.choices selection clear 0 end foreach item $index_lstb { .frame2.lbox_frm.choices select set $item } quicklook_vel } else { .frame2.lbox_frm.choices selection clear 0 end } } else { init_a # SET THE SELECTION LIST FROM THE MEMORY VARIABLES IF THEY EXIST OR CLEAR SELECTION if [info exists index_lsta] { .frame2.lbox_frm.choices selection clear 0 end foreach item $index_lsta { .frame2.lbox_frm.choices select set $item } quicklook_vel } else { .frame2.lbox_frm.choices selection clear 0 end } } } # AVERAGE TOGETHER SELECTED SCANS FROM A SINGLE POLARISATION AND STORE THE RESULT IN A SPECIFIC REGISTER proc select_average {} { global endreg pstate index_lsta index_lstb date tel_state set index_lst [.frame2.lbox_frm.choices curselection] ; # READ THE SELECTION BOX if { $pstate == 1 } { set index_lsta $index_lst } else { set index_lstb $index_lst } foreach item $index_lst { lappend choicelist [.frame2.lbox_frm.choices get $item] } if {![info exists choicelist]} { feedback "You must select at least 1 scan." return } else { # AVERAGE THE FINAL LIST OF SCANS INTO THE NEXT TWO EMPTY REGISTERS # 1ST EMPTY REGISTER = POLA REDUCED, 2ND EMPTY REGISTER = POLB REDUCED averagel $choicelist [expr $endreg + $pstate] # ENABLE THE CHANNEL AVERAGING BUTTON if { [info exists index_lsta] && [info exists index_lstb] } { .frame3.bb.selections.fold configure -state normal } # PLOT A QUICK LOOK SPECTRUM quicklook_vel return $choicelist } } # STRIP LEADING ZEROS OFF THE OBSERVATION DATE VALUE READ FROM THE FILE proc stripzeros { value } { set retval [string trimleft $value 0] if { ![string length $retval] } { return 0 } return $retval } # QUICKLOOK AT THE INDIVIDUAL POLARISATION REDUCTIONS proc quicklook { } { global endreg plot_range pstate plot [expr $endreg + $pstate] $plot_range raise . } # QUICKLOOK AT THE INDIVIDUAL POLARISATION REDUCTIONS IN VELOCITY SPACE proc quicklook_vel { } { global endreg plot_range pstate plot_vel [expr $endreg + $pstate] $plot_range raise . } # PLOT CURRENT RANGE OF CHANNELS FOR CURRENT WORKING REGISTER proc plot { reg plot_range } { global cur_sel expect "Enter Command:" exp_send "pl\rn\rn\rs\ry\rn\rn\rn\r$reg\r$plot_range\r\r" set cur_sel $reg raise . } # PLOT CURRENT RANGE OF CHANNELS IN VELOCITY SPACE proc plot_vel { reg plot_range } { global cur_sel tsys inttime expect "Enter Command:" exp_send "pl\rn\ry\rn\rs\ry\rn\rn\rn\r$reg\r$plot_range\r\r" info_all $reg set cur_sel $reg raise . } # BASELINE POPUP WINDOW proc baseline_popup {} { global index_lsta index_lstb oldfocus poly_order sleeptime if [catch {toplevel .baseline_popup} result ] { raise .baseline_popup } else { # CREATE THE POPUP WINDOW wm title .baseline_popup "Baseline Fitting" frame .baseline_popup.border -relief solid -borderwidth 2 frame .baseline_popup.border.ft -relief flat -borderwidth 1 frame .baseline_popup.border.ee -relief flat -borderwidth 1 frame .baseline_popup.border.ll -relief flat -borderwidth 1 label .baseline_popup.border.ft.label -text "Polynomial (1-5):" -padx 1 menubutton .baseline_popup.border.ft.poly_button -relief groove -text $poly_order -menu .baseline_popup.border.ft.poly_button.menu set m1 [menu .baseline_popup.border.ft.poly_button.menu -tearoff 0] $m1 add command -label "1" -command { set poly_order "1" ; .baseline_popup.border.ft.poly_button configure -text $poly_order } $m1 add command -label "2" -command { set poly_order "2" ; .baseline_popup.border.ft.poly_button configure -text $poly_order } $m1 add command -label "3" -command { set poly_order "3" ; .baseline_popup.border.ft.poly_button configure -text $poly_order } $m1 add command -label "4" -command { set poly_order "4" ; .baseline_popup.border.ft.poly_button configure -text $poly_order } $m1 add command -label "5" -command { set poly_order "5" ; .baseline_popup.border.ft.poly_button configure -text $poly_order } label .baseline_popup.border.ll.lbox1 -text "Baseline box 1" label .baseline_popup.border.ll.lbox2 -text "Baseline box 2 " entry .baseline_popup.border.ee.bbox1 -textvar boxchan_left -relief sunken -width 15 entry .baseline_popup.border.ee.bbox2 -textvar boxchan_right -relief sunken -width 15 button .baseline_popup.border.fit_button -relief groove -text "Fit" -command { fit_baseline sleep $sleeptime raise .baseline_popup } button .baseline_popup.border.revert -relief groove -text "Revert" -state disabled -command { revert set stor_sel $cur_sel plot [expr $endreg + 5] $plot_range set cur_sel $stor_sel sleep $sleeptime raise .baseline_popup} button .baseline_popup.border.save -relief groove -text "Apply" -state disabled -command { commit catch { destroy .baseline_popup } } button .baseline_popup.border.cancel -relief groove -text "Cancel" -command { destroy .baseline_popup plot_vel $cur_sel $plot_range } pack .baseline_popup.border.ft.label -side left -fill x pack .baseline_popup.border.ft.poly_button -side left -fill x pack .baseline_popup.border.ee.bbox1 -side left -fill x pack .baseline_popup.border.ee.bbox2 -side right -fill x pack .baseline_popup.border.ll.lbox1 -side left -fill x pack .baseline_popup.border.ll.lbox2 -side right -fill x pack .baseline_popup.border.ft -side top -fill x pack .baseline_popup.border.ll -side top -fill x pack .baseline_popup.border.ee -side top -fill x pack .baseline_popup.border.fit_button -side left -fill x pack .baseline_popup.border.revert -side left -fill x pack .baseline_popup.border.save -side right -fill y pack .baseline_popup.border.cancel -side right -fill y pack .baseline_popup.border -side top -fill x -padx 3 -pady 2 grab .baseline_popup sleep $sleeptime raise .baseline_popup } } # EVENTS BOUND TO THE BASELINE BUTTON ON THE POPUP WINDOW proc fit_baseline {} { global endreg pstate cur_sel stor_sel chan_range plot_range global boxchan_left boxchan_right boxchan_a_left boxchan_a_right boxchan_b_left boxchan_b_right endreg global poly_order poly_mema poly_memb # SAVE BASELINE BOX VALUES FROM THE ENTRY BOXES if { $pstate == 1 } { set boxchan_a_left $boxchan_left set boxchan_a_right $boxchan_right set poly_mema $poly_order } else { set boxchan_b_left $boxchan_left set boxchan_b_right $boxchan_right set poly_memb $poly_order } # COPY THE SPECTRUM IN THE CURRENT REGISTER TO A TEMPORARY LOCATION expect "Enter Command: " exp_send "co\rn\r$chan_range\r$chan_range\r$cur_sel\r[expr $endreg + 5]\r" # APPLY THE BASELINE ALGORITHIM IN SPC expect "Enter Command: " exp_send "ba\r$boxchan_left $boxchan_right\r$poly_order,n\r[expr $endreg + 5]\r" set stor_sel $cur_sel plot [expr $endreg + 5] $plot_range set cur_sel $stor_sel .baseline_popup.border.revert configure -state normal .baseline_popup.border.save configure -state normal } # ZERO SELECTED CHANNELS POPUP WINDOW proc zero {} { global endreg pstate cur_sel stor_sel chan_range plot_range global boxchan_left boxchan_right boxchan_a_left boxchan_a_right boxchan_b_left boxchan_b_right endreg global zero_range_l zero_range_r sleeptime global index_lsta index_lstb if [catch {toplevel .zero_popup} result ] { raise .zero_popup } else { # CREATE THE POPUP WINDOW wm title .zero_popup "Zero Selected Channels" frame .zero_popup.border -relief solid -borderwidth 2 frame .zero_popup.border.sel_frm -relief flat -borderwidth 1 label .zero_popup.border.sel_frm.label -text "Channels:" entry .zero_popup.border.sel_frm.sel_box_l -textvar zero_range_l -relief sunken -width 5 label .zero_popup.border.sel_frm.minus -text "-" entry .zero_popup.border.sel_frm.sel_box_r -textvar zero_range_r -relief sunken -width 5 button .zero_popup.border.zero_button -relief groove -text "Zero" -command { try_zero sleep $sleeptime raise .zero_popup } button .zero_popup.border.revert -relief groove -text "Revert" -state disabled -command { revert set stor_sel $cur_sel plot [expr $endreg + 5] $plot_range set cur_sel $stor_sel sleep $sleeptime raise .zero_popup } button .zero_popup.border.save -relief groove -text "Apply" -state disabled -command { commit ; catch { destroy .zero_popup } } button .zero_popup.border.cancel -relief groove -text "Cancel" -command { destroy .zero_popup ; plot_vel $cur_sel $plot_range } pack .zero_popup.border.sel_frm.label -side left -fill x pack .zero_popup.border.sel_frm.sel_box_l -side left -fill x pack .zero_popup.border.sel_frm.minus -side left pack .zero_popup.border.sel_frm.sel_box_r -side left -fill x pack .zero_popup.border.sel_frm -side top -fill x pack .zero_popup.border.zero_button -side left -fill x pack .zero_popup.border.revert -side left -fill x pack .zero_popup.border.save -side right -fill y pack .zero_popup.border.cancel -side right -fill y pack .zero_popup.border -side top -fill x -padx 3 -pady 2 grab .zero_popup sleep $sleeptime raise .zero_popup } } # ZERO SELECTED CHANNELS proc try_zero {} { global endreg pstate cur_sel stor_sel chan_range plot_range global boxchan_left boxchan_right boxchan_a_left boxchan_a_right boxchan_b_left boxchan_b_right endreg global chan_rangeb chan_rangeb_l global zero_range_l zero_range_r zero_rangea_l zero_rangea_r zero_rangeb_l zero_rangeb_r # SAVE ZERO VALUES TO MEMORY if { $pstate == 1 } { set zero_rangea_l $zero_range_l set zero_rangea_r $zero_range_r } else { set zero_rangeb_l $zero_range_l set zero_rangeb_r $zero_range_r } # COPY THE SPECTRUM IN THE CURRENT REGISTER TO A TEMPORARY LOCATION expect "Enter Command: " exp_send "co\rn\r$chan_range\r$chan_range\r$cur_sel\r[expr $endreg + 5]\r" # APPLY THE ZERO ALGORITHIM IN SPC expect "Enter Command: " exp_send sh\r-1\r$zero_range_l-$zero_range_r\r$zero_range_l\r[expr $endreg + 5]\r[expr $endreg + 5]\r set stor_sel $cur_sel plot [expr $endreg + 5] $plot_range set cur_sel $stor_sel .zero_popup.border.revert configure -state normal .zero_popup.border.save configure -state normal } # REVERT BACK TO THE UNCHANGED VERSION OF THE SPECTRUM proc revert {} { global endreg cur_sel stor_sel chan_range plot_range expect "Enter Command: " exp_send "co\rn\r$chan_range\r$chan_range\r$cur_sel\r[expr $endreg + 5]\r" } # COPY THE SPECTRUM FROM THE TEMPORARY REGISTER TO THE CURRENT REGISTER proc commit {} { global endreg cur_sel chan_range plot_range boxchan_right expect "Enter Command: " exp_send "co\rn\r$chan_range\r$chan_range\r[expr $endreg + 5]\r$cur_sel\r" plot_vel $cur_sel $plot_range set stat_box $boxchan_right } # VELOCITY CORRECTION POPUP WINDOW proc cor_vel {} { global endreg pstate cur_sel stor_sel chan_range plot_range line_freq obs_freq freq_check global boxchan_left boxchan_right boxchan_a_left boxchan_a_right boxchan_b_left boxchan_b_right endreg global zero_range_l zero_range_r sleeptime set line_freq $obs_freq global index_lsta index_lstb if [catch {toplevel .vel_popup} result ] { raise .vel_popup } else { # CREATE THE POPUP WINDOW wm title .vel_popup "Correct offset velocity" frame .vel_popup.bfrm1 -relief solid -borderwidth 2 frame .vel_popup.bfrm2 -relief solid -borderwidth 2 frame .vel_popup.bfrm1.frm1 -relief flat -borderwidth 2 frame .vel_popup.bfrm1.frm2 -relief flat -borderwidth 2 frame .vel_popup.bfrm2.frm1 -relief flat -borderwidth 2 frame .vel_popup.bfrm2.frm2 -relief flat -borderwidth 2 frame .vel_popup.bfrm2.frm3 -relief flat -borderwidth 2 label .vel_popup.bfrm1.frm1.label -text "Line Freq: " entry .vel_popup.bfrm1.frm1.freq -textvar obs_freq -relief sunken -width 15 label .vel_popup.bfrm1.frm2.label -text "Desired Freq:" entry .vel_popup.bfrm1.frm2.freq -textvar line_freq -relief sunken -width 15 button .vel_popup.bfrm1.calculate -relief groove -text "Calculate" -command offset_calc label .vel_popup.bfrm2.frm1.label -text "Velocity Offset:" entry .vel_popup.bfrm2.frm1.offset -textvar offset -relief sunken -width 10 checkbutton .vel_popup.bfrm2.frm2.freq -anchor w -text "Shift Frequency Simultaneously" -variable freq_check button .vel_popup.bfrm2.frm3.test -relief groove -text "Test" -command { offset_test sleep $sleeptime raise .vel_popup } button .vel_popup.bfrm2.frm3.revert -relief groove -text "Revert" -state disabled -command { revert set stor_sel $cur_sel plot_vel [expr $endreg + 5] $plot_range set cur_sel $stor_sel sleep $sleeptime raise .vel_popup } button .vel_popup.bfrm2.frm3.cancel -relief groove -text "Cancel" -command { destroy .vel_popup ; plot_vel $cur_sel $plot_range } button .vel_popup.bfrm2.frm3.apply -relief groove -text "Apply" -state disabled -command { commit ; catch { destroy .vel_popup } } pack .vel_popup.bfrm1.frm1.label -side left -fill x pack .vel_popup.bfrm1.frm1.freq -side left -fill x -expand true pack .vel_popup.bfrm1.frm2.label -side left -fill x pack .vel_popup.bfrm1.frm2.freq -side left -fill x -expand true pack .vel_popup.bfrm1.frm1 -side top pack .vel_popup.bfrm1.frm2 -side top pack .vel_popup.bfrm1.calculate -side top -fill x -expand true pack .vel_popup.bfrm2.frm1.label -side left -fill x pack .vel_popup.bfrm2.frm1.offset -side left -fill x -expand true pack .vel_popup.bfrm2.frm2.freq -side left -fill x -expand true pack .vel_popup.bfrm2.frm3.test -side left -fill x -expand true pack .vel_popup.bfrm2.frm3.revert -side left -fill x -expand true pack .vel_popup.bfrm2.frm3.cancel -side left -fill x -expand true pack .vel_popup.bfrm2.frm3.apply -side left -fill x -expand true pack .vel_popup.bfrm2.frm1 -side top pack .vel_popup.bfrm2.frm2 -side top pack .vel_popup.bfrm2.frm3 -side top pack .vel_popup.bfrm1 -side top -fill x -padx 3 -pady 2 pack .vel_popup.bfrm2 -side top -fill x -padx 3 -pady 3 grab .vel_popup sleep $sleeptime raise .vel_popup } } # CALCULATE THE VELOCITY OFFSET TO APPLY BASED ON FREQ_STEP AND VEL_STEP proc offset_calc {} { global offset obs_freq cent_freq line_freq vel_step freq_step set delta_freq [expr ($line_freq * 1e3) - ($obs_freq * 1e3)] set offset [ expr ($delta_freq / $freq_step) * -$vel_step ] } # ALTERNATIVE VELOCITY OFFSET CALCULATION BASED ON THE OBSERVED FREQUENCY AND THE LINE FREQUENCY proc offset_calc1 {} { global offset obs_freq cent_freq line_freq obs_freq_calc set delta_freq [expr ($line_freq * 1e9) - ($obs_freq * 1e9)] set av_freq [expr (($line_freq) + ($obs_freq)) / 2] set offset [expr [expr $delta_freq * 2.99792458e5] / ($av_freq * 1e9) ] offset_calc1 } # CORRECT THE VELOCITY AND (OPTIONAL) FREQUENCY AXIS OF A SCAN DUE TO OFFSET LINE FREQUENCY proc offset_test {} { global cur_sel offset chan_range zero_rangel zero_ranger endreg plot_range offset pstate obs_freq cent_freq freq_check global line_freq obs_freq_calc vel_step freq_step # COPY THE SPECTRUM IN THE CURRENT REGISTER TO A TEMPORARY REGISTER expect "Enter Command: " exp_send "co\rn\r$chan_range\r$chan_range\r$cur_sel\r[expr $endreg + 5]\r" # CALCULATE THE OFFSET IN FREQUENCY (MHz) BASED ON THE VELOCITY SHIFT set shift_freq [expr ($offset / $vel_step) * $freq_step ] # ADD THE VELOCITY OFFSET TO THE VELOCITY HEADER expect "Enter Command: " exp_send "edit\rn\rn\re\r[expr 8233 + $pstate]\ra\r$offset\r[expr $endreg + 5]\r" if { $freq_check == 1} { #ADD THE FREQUENCY OFFSET TO THE FREQUENCY HEADER(S) expect "Enter Command: " exp_send "edit\rn\rn\re\r[expr 8249 + $pstate]\ra\r$shift_freq\r[expr $endreg + 5]\r" if { $pstate == 1} { expect "Enter Command: " exp_send "edit\rn\rn\re\r8247\ra\r$shift_freq\r[expr $endreg + 5]\r" } } set stor_sel $cur_sel plot_vel [expr $endreg + 5] $plot_range set cur_sel $stor_sel .vel_popup.bfrm2.frm3.revert configure -state normal .vel_popup.bfrm2.frm3.apply configure -state normal } # AVERAGE POLARISATION A AND POLARISATION B TOGETHER UNDER POLARISATION A proc av_a_b {} { global polname endreg chan_rangea chan_rangea_l chan_rangeb_l chan_rangeb plot_rangea if { $polname == "Pol B" } { switchpol } copy_b_a $chan_rangeb $chan_rangea [expr $endreg + 2] [expr $endreg + 6] align_new [expr $endreg + 1] "[expr $endreg + 1] [expr $endreg + 3]" expect "Enter Command:" exp_send "avg\r[expr $endreg + 3]\r[expr $endreg + 1] [expr $endreg + 6]\r" # ZERO POLB BY SHIFTING TO ITSELF expect "Enter Command: " exp_send sh\r-1\r$chan_rangeb\r$chan_rangeb_l\r[expr $endreg + 3]\r[expr $endreg + 3]\r plot_vel [expr $endreg + 3] $plot_rangea } # HANNING SMOOTH THE CURRENT REGISTER proc smooth {} { global pstate plot_range cur_sel expect "Enter Command: " exp_send sm\rn\r$pstate\rh\r$cur_sel\r plot_vel $cur_sel $plot_range } # COPY DATA AND HEADER VARIABLES FROM POL B (reg1) TO POL B (reg2) proc copy_b_a { chan_rangeb chan_rangea reg1 reg2 } { expect "Enter Command:" exp_send "co\rn\r$chan_rangeb\r$chan_rangea\r$reg1\r$reg2\r" # COPY VELOCITY HEADER VARIABLES FROM POLB TO POLA expect "Enter Command: " exp_send "edit\rn\rn\rl\r8235 8239\r$reg1\r" expect -re "Reg\\s+Source\\s+8235\\s+8239\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)\\s*(\[-|+]*\[\\d]+.\[\\d]+)" set vel_ch1 $expect_out(1,string) set velstep $expect_out(2,string) expect "Enter Command: " exp_send "edit\rn\rn\re\r8234 8238 8200\rr\r$vel_ch1 $velstep $velstep\r$reg2\r" # COPY SYSTEM TEMPERATURE VARIABLE AND INTTIME FROM POLB TO POLA expect "Enter Command: " exp_send "edit\rn\rn\rl\r8223 8231\r$reg1\r" expect -re "Reg\\s+Source\\s+8223\\s+8231\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)\\s+(\[-|+]*\[\\d]+.\[\\d]+)" set systemp $expect_out(1,string) set inttime $expect_out(2,string) expect "Enter Command: " exp_send "edit\rn\rn\re\r8222 8202 8230 8201\rr\r$systemp $systemp $inttime $inttime\r$reg2\r" # COPY FREQUENCY HEADER VARIABLES FROM POLB TO POLA expect "Enter Command: " exp_send "edit\rn\rn\rl\r8251 8208\r$reg1\r" expect -re "Reg\\s+Source\\s+8251\\s+8208\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)\\s+(\[-|+]*\[\\d]+.\[\\d]+)" set freq_cent $expect_out(1,string) set nchan $expect_out(2,string) expect "Enter Command: " exp_send "edit\rn\rn\re\r8250\rr\r$freq_cent\r$reg2\r" # CALCULATE THE FIGURES FOR REDUNDANT FREQ AND VEL VARIABLES expect "Enter Command: " exp_send "edit\rn\rn\rl\r8248\r$reg1\r" expect -re "Reg\\s+Source\\s+8248\\s*\\r*\\s*\[^\\s]+\\s+\[^\\s]*\\s+(\[-|+]*\[\\d]+.\[\\d]+)" set freqstep $expect_out(1,string) set vel_cent [expr $vel_ch1 + ($velstep*($nchan-1)/2)] set freq_ch1 [expr $freq_cent - ($freqstep*($nchan-1)/2)] expect "Enter Command: " exp_send "edit\rn\rn\re\r8199\rr\r$vel_cent\r$reg2\r" exp_send "edit\rn\rn\re\r8247\rr\r$freq_ch1\r$reg2\r" } # GLOBAL SAVE proc save {} { global endreg outdir chan_rangea chan_rangeb outfile index_lsta index_lstb cur_sel save_opt polname plot_range if ![file exists "$outdir."] { message "Directory \"$outdir\" does not exist" return } if { $save_opt == "sdf file" } { set end ".sdf" if { $polname == "Pol A" } { expect "Enter Command: " exp_send "co\rn\r$chan_rangea\r$chan_rangea\r$cur_sel\r[expr $endreg + 4]\r" } elseif {$polname == "Pol B"} { copy_b_a $chan_rangeb $chan_rangea $cur_sel [expr $endreg + 4] } if ![file exists "$outdir$outfile$end"] { expect "Enter Command: " exp_send "wr\r[expr $endreg + 4]\r$outdir$outfile$end\r" feedback "Spectra written to file:\n$outfile$end" } else { message "\"$outfile$end\"\nalready exists!" } } elseif { $save_opt == "fits file" } { if ![file exists "$outdir$outfile.fits"] { if { $polname == "Pol A" } { expect "Enter Command: " exp_send "co\rn\r$chan_rangea\r$chan_rangea\r$cur_sel\r[expr $endreg + 4]\r" } elseif { $polname == "Pol B" } { copy_b_a $chan_rangeb $chan_rangea $cur_sel [expr $endreg + 4] } expect "Enter Command: " exp_send "fits\rtemp\r[expr $endreg + 4]\runsw\nMopra\nn\r" expect -re "Error opening output FITS file\\s(\[^\\s]*)\.fits" \ { message "\"Temporary file \"$expect_out(1,string).fits\"\nalready exists!\nPlease delete it." } \ -re "FITS file\\s(\[^\\s]*)\.fits written" \ { catch { exec mv [exec pwd]/$expect_out(1,string).fits $outdir$outfile.fits } \ ; feedback "Spectra written to file:\n$outfile.fits"} } else { message "\"$outfile.fits\"\nalready exists!" } } elseif { $save_opt == "postscript" } { if ![file exists "$outdir$outfile.ps"] { expect "Enter Command:" exp_send "pl\rn\ry\rn\rs\ry\rn\rn\rn\r$cur_sel\r$plot_range\r$outdir$outfile.ps/ps\r\rn\r" feedback "Spectra written to file:\n$outfile.ps" } else { message "\"$outfile.ps\"\nalready exists!" } } elseif { $save_opt == "ascii dat" } { if ![file exists "$outdir$outfile.dat"] { expect "Enter Command:" exp_send "pl\ry\ry\rn\r$cur_sel\r$plot_range\r/xs\r$outdir$outfile.dat\r\r" feedback "Spectra written as ascii file:\n$outfile.dat" } else { message "\"$outfile.dat\"\nalready exists!" } } } # STOP AND SAVE SETTINGS IN THE SETTINGS FILE proc stop {} { global indir filename outdir tel_state load_choice load_method quotient_choice quotient_order scaling_choice cont_choice global clip_left clip_right rest_choice set settings [open ~/.dfm_settings w+] puts $settings $indir puts $settings $filename puts $settings $outdir puts $settings $tel_state puts $settings $load_choice puts $settings $load_method puts $settings $quotient_choice puts $settings $quotient_order puts $settings $scaling_choice puts $settings $cont_choice puts $settings $clip_left puts $settings $clip_right puts $settings $rest_choice close $settings exp_send "exit\nn\n" exit } # SET OUT THE GUI AND BIND EVENTS TO WIDGETS ########################################################### # CREATE FILE ENTRY SPACE AND LOAD BUTTON frame .frame1 -relief flat -borderwidth 1 frame .frame1.load_frm -relief solid -borderwidth 2 frame .frame1.load_frm.bb -relief flat -borderwidth 0 frame .frame1.load_frm.indir_frm -relief flat -borderwidth 0 frame .frame1.load_frm.file_frm -relief flat -borderwidth 0 label .frame1.load_frm.indir_frm.label -text "Dir:" -padx 1 entry .frame1.load_frm.indir_frm.dir -textvar indir -relief sunken -width 26 label .frame1.load_frm.file_frm.label -text "File:" -padx 0 entry .frame1.load_frm.file_frm.filename -textvar filename -relief sunken -width 26 button .frame1.load_frm.bb.settings_button -relief flat -relief groove -text Settings -command { settings } button .frame1.load_frm.bb.load_button -relief flat -relief groove -text Load -command { set choicelist [Load_Button] } bind .frame1.load_frm.file_frm.filename Load_Button focus .frame1.load_frm.file_frm.filename pack .frame1.load_frm.indir_frm.label -side left pack .frame1.load_frm.indir_frm.dir -side right -fill x pack .frame1.load_frm.file_frm.label -side left pack .frame1.load_frm.file_frm.filename -side right -fill x pack .frame1.load_frm.indir_frm -side top -fill x -padx 1 -pady 1 pack .frame1.load_frm.file_frm -side top -fill x -padx 1 -pady 1 pack .frame1.load_frm.bb.settings_button -side left -fill x pack .frame1.load_frm.bb.load_button -side right -fill x pack .frame1.load_frm.bb -side top -fill x -padx 1 -pady 1 pack .frame1.load_frm -side top -fill x -pady 1 .frame1.load_frm.indir_frm.dir xview end # CREATE FILE INFORMATION BOX frame .frame1.param_frm -relief solid -borderwidth 2 frame .frame1.param_frm.frm1 -relief flat -borderwidth 0 frame .frame1.param_frm.frm2 -relief flat -borderwidth 0 frame .frame1.param_frm.frm3 -relief flat -borderwidth 0 label .frame1.param_frm.frm1.srclabel -text "Src: " entry .frame1.param_frm.frm1.source -textvar source -relief flat -width 10 -state disabled label .frame1.param_frm.frm1.datelabel -text "Date:" entry .frame1.param_frm.frm1.date -textvar date -relief flat -width 10 -state disabled label .frame1.param_frm.frm2.freqlabel -text "Freq:" entry .frame1.param_frm.frm2.freq -textvar cent_freq -relief flat -width 10 -state disabled label .frame1.param_frm.frm2.bwlabel -text "BW:" entry .frame1.param_frm.frm2.bandwidth -textvar bandwidth -width 10 -relief flat -state disabled label .frame1.param_frm.frm3.ralabel -text "RA: " entry .frame1.param_frm.frm3.ra -textvar ra -relief flat -width 10 -state disabled label .frame1.param_frm.frm3.declabel -text "DEC:" entry .frame1.param_frm.frm3.dec -textvar dec -relief flat -width 10 -state disabled pack .frame1.param_frm.frm1.srclabel -side left pack .frame1.param_frm.frm1.source -side left -fill x pack .frame1.param_frm.frm1.date -side right -fill x pack .frame1.param_frm.frm1.datelabel -side right pack .frame1.param_frm.frm2.freqlabel -side left pack .frame1.param_frm.frm2.freq -side left -fill x pack .frame1.param_frm.frm2.bandwidth -side right -fill x pack .frame1.param_frm.frm2.bwlabel -side right pack .frame1.param_frm.frm3.ralabel -side left pack .frame1.param_frm.frm3.ra -side left -fill x pack .frame1.param_frm.frm3.dec -side right -fill x pack .frame1.param_frm.frm3.declabel -side right pack .frame1.param_frm.frm1 -side top -fill x -pady 1 pack .frame1.param_frm.frm2 -side top -fill x -pady 1 pack .frame1.param_frm.frm3 -side top -fill x -pady 1 pack .frame1.param_frm -side top -fill x -pady 1 pack .frame1 -side left -fill both -padx 1 -pady 1 # CREATE THE SCAN SELECTION LISTBOX AND ASSOCIATED SCROLLBARS frame .frame2 -relief flat -borderwidth 1 frame .frame2.lbox_frm -relief solid -borderwidth 2 entry .frame2.reg -textvar cur_sel -relief solid -width 3 \ -font "-adobe-helvetica-bold-r-normal--12-120-75-75-p-70-iso8859-1" \ -borderwidth 2 -justify center -state disabled -bg green listbox .frame2.lbox_frm.choices \ -selectmode multiple \ -exportselection false \ -selectbackground $a_colour \ -selectforeground black \ -setgrid true \ -height 5 \ -width 3 \ -yscrollcommand [list .frame2.lbox_frm.scroll set ] scrollbar .frame2.lbox_frm.scroll -command [list .frame2.lbox_frm.choices yview ] -width 10 pack .frame2.lbox_frm.scroll -side right -fill both -expand true pack .frame2.lbox_frm.choices -side left -fill both -expand true pack .frame2.reg -side top -fill both pack .frame2.lbox_frm -side top -fill both -pady 1 -expand true pack .frame2 -side left -fill both -padx 1 -pady 1 # CREATE THE FEEDBACK BOX frame .frame3 -relief flat -borderwidth 1 frame .frame3.feeback -relief solid -borderwidth 2 set prompt [text .frame3.feeback.prompt \ -width 30 \ -height 3 \ -borderwidth 1 \ -relief ridge \ -bg lightblue \ -font "-adobe-helvetica-bold-r-normal--12-120-75-75-p-70-iso8859-1" \ -yscrollcommand { .frame3.feeback.scroll set}] scrollbar .frame3.feeback.scroll -command { .frame3.feeback.prompt yview } -width 10 pack .frame3.feeback.scroll -side right -fill y pack .frame3.feeback.prompt -side left -fill both pack .frame3.feeback -side top -fill both -pady 1 -expand true # CREATE THE SELECTION BUTTONS frame .frame3.bb -relief solid -borderwidth 2 frame .frame3.bb.selections -relief flat -borderwidth 0 button .frame3.bb.selections.ch_button -relief groove -text $polname -state disabled -command switchpol button .frame3.bb.selections.sel_av -relief groove -text "Sel & Av" \ -state disabled -command {set choicelist [select_average] } button .frame3.bb.selections.fold -relief groove -text "Av A & B" -state disabled -command av_a_b pack .frame3.bb.selections.ch_button -side top -fill x pack .frame3.bb.selections.sel_av -side top -fill x pack .frame3.bb.selections.fold -side top -fill x -expand true pack .frame3.bb.selections -side left -fill x -padx 1 -pady 1 -expand true # CREATE THE OPERATIONS BUTTONS frame .frame3.bb.operations -relief flat -borderwidth 0 button .frame3.bb.operations.fit_button -relief groove -text "Fit Baseline" -state disabled -command { plot $cur_sel $plot_range baseline_popup } button .frame3.bb.operations.zero -relief groove -text "Zero Channels" -state disabled -command { plot $cur_sel $plot_range zero } button .frame3.bb.operations.vel -relief groove -text "Shift Vel" -state disabled -command { plot_vel $cur_sel $plot_range cor_vel } pack .frame3.bb.operations.fit_button -side top -fill x pack .frame3.bb.operations.zero -side top -fill x pack .frame3.bb.operations.vel -side top -fill x pack .frame3.bb.operations -side left -fill both -padx 1 -pady 1 -expand true bind .frame2.lbox_frm.choices { plot_vel [.frame2.lbox_frm.choices get [.frame2.lbox_frm.choices nearest %y]] $plot_range } # PACK THE LOADFRAME AND THE PARAMETERS FRAME pack .frame3.bb -side bottom -fill both -pady 1 pack .frame3 -side left -fill both -padx 1 -pady 1 feedback "To begin, enter a filename and\ \nclick the 'Load' button" # SAVING frame .frame4 -relief flat -borderwidth 1 frame .frame4.save_frame -relief solid -borderwidth 2 frame .frame4.save_frame.dir -relief flat -borderwidth 1 frame .frame4.save_frame.file -relief flat -borderwidth 1 frame .frame4.save_frame.menu -relief flat -borderwidth 1 frame .frame4.save_frame.bb -relief flat -borderwidth 2 label .frame4.save_frame.dir.label -text "Dir: " entry .frame4.save_frame.dir.outdir -textvar outdir -relief sunken -width 15 label .frame4.save_frame.file.label -text "File: " entry .frame4.save_frame.file.outfile -textvar outfile -relief sunken -width 20 label .frame4.save_frame.menu.label -text "File Type: " menubutton .frame4.save_frame.menu.menu_button -relief groove -text $save_opt -menu .frame4.save_frame.menu.menu_button.menu set m [menu .frame4.save_frame.menu.menu_button.menu -tearoff 0] $m add command -label "sdf file" -command { set save_opt "sdf file" ; .frame4.save_frame.menu.menu_button configure -text $save_opt } $m add command -label "fits file" -command { set save_opt "fits file" ; .frame4.save_frame.menu.menu_button configure -text $save_opt } $m add command -label "ascii dat" -command { set save_opt "ascii dat" ; .frame4.save_frame.menu.menu_button configure -text $save_opt } $m add command -label "postscript" -command { set save_opt "postscript" ; .frame4.save_frame.menu.menu_button configure -text $save_opt } button .frame4.save_frame.smooth -relief groove -text "Hanning Smooth" -state disabled -command { smooth } button .frame4.save_frame.bb.save_button -relief groove -text "Save Files" -state disabled -command {save} button .frame4.save_frame.bb.quit_button -relief groove -text Quit -command stop pack .frame4.save_frame.dir.label -side left pack .frame4.save_frame.dir.outdir -side left -padx 1 -fill x -expand true pack .frame4.save_frame.dir -side top -fill x -padx 2 -pady 2 pack .frame4.save_frame.file.label -side left pack .frame4.save_frame.file.outfile -side left -padx 1 -fill x -expand true pack .frame4.save_frame.file -side top -fill x -padx 2 -pady 2 pack .frame4.save_frame.menu.label -side left pack .frame4.save_frame.menu.menu_button -side right -fill x -expand true pack .frame4.save_frame.menu -side top -fill x -padx 2 -pady 2 pack .frame4.save_frame.smooth -side top -fill x -padx 2 -pady 2 pack .frame4.save_frame.bb.save_button -side left -fill x pack .frame4.save_frame.bb.quit_button -side right -fill x pack .frame4.save_frame.bb -side bottom -fill both pack .frame4.save_frame -side top -fill both -expand true pack .frame4 -side left -fill both -padx 1 -pady 1 .frame4.save_frame.dir.outdir xview end