
proc APSMpSRRestoreFBfiltersInfo {} {
    return "This procedure changes the RTFB high-pass filters by some factor or restores the filters to the default values, with optional ramping."
}

proc APSMpSRSetFBfilters {args} {
    set ramp 0
    set steps 5
    set interval 1
    set restore 0
    set hFactor 1
    set vFactor 1
    APSStrictParseArguments {ramp steps interval restore hFactor vFactor}

    if $restore {
        set paramFile /home/helios/oagData/sr/rtfeedback/parameterFiles/srfb-default.param
        set tmpFile /tmp/[APSTmpString]
        if [catch {exec sddsprocess $paramFile -pipe=out \
                     -match=col,ControlName=hpFilterCutoffVert \
                     | sdds2stream -pipe -col=ValueString} hpVertFinal] {
            APSMpReturn error "APSMpSRRestoreFBfilters: $result"
        }
        if [catch {exec sddsprocess $paramFile -pipe=out\
                     -match=col,ControlName=hpFilterCutoffHoriz \
                     | sdds2stream -pipe -col=ValueString} hpHorizFinal] {
            APSMpReturn error "APSMpSRRestoreFBfilters: $result"
        }
        if $ramp {
            if [catch {exec cavget -pend=15 -list=SRFB:fh -list=SlAO,AO \
                     } values] {
                APSMpReturn error "APSMpSRRestoreFBfilters: $values"
            }
            set hpHorizInit [lindex $values 0]
            set hpVertInit [lindex $values 1]
        }
    } else {
        if [catch {exec cavget -pend=15 -list=SRFB:fh -list=SlAO,AO \
                 } values] {
            APSMpReturn error "APSMpSRRestoreFBfilters: $values"
        }
        set hpHorizInit [lindex $values 0]
        set hpVertInit  [lindex $values 1]
        set hpHorizFinal [expr $hFactor * [lindex $values 0]]
        set hpVertFinal [expr $vFactor * [lindex $values 1]]
    }
    
    if $ramp {
        for {set i 1} {$i <= $steps} {incr i} {
            set hpHoriz [expr ($hpHorizFinal - $hpHorizInit) * $i/ $steps + $hpHorizInit]
            set hpVert [expr ($hpVertFinal - $hpVertInit) * $i/ $steps + $hpVertInit]
            if [catch {exec cavput -pend=15 -list=SRFB:fh -list=SlAO=$hpHorizFinal,AO=$hpVertFinal
                exec cavput -pend=15 -list=SRFB:GBL:loadBO=1} error] {
                APSMpReturn error "APSMpSRRestoreFBfilters: Error setting regulators: $error"
            }
        }
    } else {
        if [catch {exec cavput -pend=15 -list=SRFB:fh -list=SlAO=$hpHorizFinal,AO=$hpVertFinal
            exec cavput -pend=15 -list=SRFB:GBL:loadBO=1} error] {
            APSMpReturn error "APSMpSRRestoreFBfilters: Error setting regulators: $error"
        }
    }
    APSMpReturn ok 0
}

proc APSRTFBSampleAndCollect {args} {
    set monfile ""
    set datafile ""
    set clearMode 1
    set wait 1
    set statusCallback ""
    set autoRestore 0
    set restoreTiming 1
    set restoreChannels 1
    set scalarsFile ""
    set description ""
    set waitWhileInjecting 1
    APSStrictParseArguments {monfile datafile clearMode wait statusCallback autoRestore \
			   waitWhileInjecting \
			   restoreTiming restoreChannels scalarsFile description}

   
    if ![string length $monfile] {
        return -code error "APSRTFBSampleAndCollect(Error1): must supply a monitor file name"
    }
    
	 if ![file exists $monfile] {
		  	return -code error "APSRTFBSampleAndCollect(Error2): monitor file $monfile does not exit."
    }
    
    if {$datafile == ""} {
	return -code error "APSRTFBSampleAndCollect(Error3): must supply a datafile name."
    }
    if [file isdirectory $datafile] {
        return -code error "APSRTFBSampleAndCollect(Error4): $datafile is a directory, please provide the filename!"
    }
    if {[file exists $datafile]} {
	return -code error "APSRTFBSampleAndCollect(Error5): $datafile exists."
    }
    
    if $autoRestore {
	if [catch {APSRestoreSRFBDspScope  -filename $monfile -clearMode $clearMode \
		       -timing $restoreTiming -channels $restoreChannels } result] {
	    return -code error "APSRTFBSampleAndCollect(Error7): error in restoring DSPscope: $result"
	}
    }
    if $wait {
	if [catch {APSArmDSPscope -statusCallback $statusCallback -waitWhileInjecting $waitWhileInjecting} result] {
	    return -code error "APSRTFBSampleAndCollect(Error8) -- error in ARM dsp scope: $result"
	}
	#wait for trigger
	if [catch {APSWaitForDSPtrigger -statusCallback $statusCallback} result] {
	    return -code error "APSRTFBSampleAndCollect(Error9): $result"
	}
    }
    set filename [file root ${datafile}]-[exec date +%y%m%d-%H%M%S]
    if [string length $statusCallback] {
	eval $statusCallback {"[exec date +%H:%M:%S] Collecting data from DSPscope..."}; update
    }
    if [catch {exec sddswmonitor \
		   -comment=Comment,[APSMakeSafeQualifierString $description] \
		   $monfile $filename -scalars=$scalarsFile \
	       } result] {
	return -code error "APSRTFBSampleAndCollect(Error10)(sddswmonitor): $result"
    }
    
    if [catch {exec sddsprocess $filename $datafile \
		   "-def=par,TickTime,SRFB:fsAO rec,units=sec" \
		   "-def=par,TimeCollected,Time" \
		   "-def=col,t,Index TickTime * SRFB:DS:SampleSkipAO 1 + * " \
		   "-def=col,Time,t TimeCollected + TickTime SRFB:DS:RecordLengthAO * - " } result] {
	return -code error "APSRTFBSampleAndCollect(Error11)(sddsprocess): $result"
    }
    exec rm $filename
}

set abort 0
proc APSArmDSPscope {args} {
    set statusCallback ""
    set waitWhileInjecting 1
    APSStrictParseArguments {statusCallback waitWhileInjecting}

    global abort
    set dum 1
    while {($abort==0) && ([exec cavget -pend=15 -list=SRFB:GBL:FeedbackBlockedBI] == "Blocked")} {
        if {$dum == 1} {
	    if [string length $statusCallback] {
		eval $statusCallback {"Waiting for feedback block to clear... [exec date +%H:%M:%S]"}
	    }
	    set dum 0
	}
        APSWaitWithUpdate -waitSeconds 1 -updateInterval 0.5
    }
    set dum 1
    while {($abort==0) && ($waitWhileInjecting == 1) && \
	       ([exec caget -tn S:InjectingStatusMBBI] == 1)} {
        if {$dum == 1} {
	    if [string length $statusCallback] {
		eval $statusCallback {"Waiting for injection to complete... [exec date +%H:%M:%S]"}
	    }
            set dum 0
        }
        APSWaitWithUpdate -waitSeconds 1 -updateInterval 0.5
    }
    
    set dum 1
    while {(([exec cavget -pend=15 -list=SRFB:GBL:HorzTripBI] == "Trip") || \
              ([exec cavget -pend=15 -list=SRFB:GBL:VertTripBI] == "Trip")) && \
             ($abort == 0) } {
        if {$dum == 1} {
	    if [string length $statusCallback] {
		eval $statusCallback {"Waiting for trips to be reset... [exec date +%H:%M:%S]"}
	    }
            set dum 0
        }
        APSWaitWithUpdate -waitSeconds 1 -updateInterval 0.5
    }
    
    if {$abort == 0} {
	if [string length $statusCallback] {
	    eval $statusCallback  {"Arming DSPscope... [exec date +%H:%M:%S]"}; update
	}
        exec cavput -pend=15 -list=SRFB:DS:SampleBO=1
        while {[exec cavget -pend=15 -list=SRFB:DS:SampleBO] == "Off"} {
            APSWaitWithUpdate -waitSeconds 1 -updateInterval 0.5
        }
    } else {
	return -code error "Arm Dsp scope was cancelled."
    }
}

proc APSWaitForDSPtrigger {args} {
    set statusCallback ""
    APSStrictParseArguments {statusCallback}

    global abort
    set triggered 0
    set dum 1
    while {($triggered == 0) && ($abort == 0)} {
        if {[exec cavget -pend=15 -list=SRFB:DS:SampleBO] == "Off" } {
            set triggered 1
        }
        if {$dum == 1} {
	    if [string length $statusCallback] {
		eval $statusCallback {"Waiting for dspscope to trigger... [exec date +%H:%M:%S]"}; update
	    }
	    set dum 0
        }
        APSWaitWithUpdate -waitSeconds 1 -updateInterval 0.5
    }
    
    if {$triggered == 1} {
	if [string length $statusCallback] {
	    eval $statusCallback {"Triggered [exec date +%H:%M:%S]"}; update
	}
	return ok
    } elseif {$abort} {
	if [string length $statusCallback] {
	    eval $statusCallback {"waiting for trigger aborted... [exec date +%H:%M:%S]"}; update
	}
	return -code error "DSP scope was not triggered."
    }
}
