UDF Example TCL UTILITIES USER MANUAL UDF Example
EXAMPLE(S)
The following is a working example showing how to access, manipulate and plot UDF data. The program accesses the spacecraft potential data from the Cluster-3 satellite. The data is then filtered using a Savitsky-Golay filter technique. The filtered data is subtracted from the measured data showing the jitter which was filtered out. All three sets of data, original, filtered, and difference, are plotted.

#!/bin/sh
# the next line restarts using wish \
exec wish $0 $@

set Home [file join $env(TCLTOOLS_HOME)]
source [ file join $Home TclToolInits.tcl ]
TclToolInits GUI GPH PLT UTILS UDF UDFDB UDFUTILS FFT

# READ a set of satellite potential data. Fit it using a Savitsky-Golay
#   filter.  Plot the data, the fit, and difference between the data 
#   and the fit.

# THIS procedure acquires the data.  The input is the UDF Key, the PIDF
#   sensor and unit number, and the beginning and ending year, day, hour, 
#   minute, and second.  Return the time and data arrays and the time of
#   one measurement.

proc ReadData { KeY sN uN bY bD bH bM bS eY eD eH eM eS tD pD dT } {
   global Pidf0 ExDa

   upvar $tD tM
   upvar $pD dV
   upvar $dT mT

# OPEN the data file

   FileOpen $KeY 0 $bY $bD $bH $bM $bS $eY $eD $eH $eM $eS

# GET to ths start time 

   FilePos $KeY 0 $bY $bD $bH $bM $bS FINE 

# READ the PIDF file

   ReadPIDF $KeY 0 

# GET the converstion algorithm

   set uI [UUunitAlg $KeY $uN $sN]

# GET the VIDF number of the sensor

   set vN [lindex $Pidf0(SenVidfN) $sN]

# THIS is the beginning and ending time in milliseconds

   set bMs [expr $bH * 3600000 + $bM * 60000 + $bS]
   set eMs [expr $eH * 3600000 + $eM * 60000 + $eS]

# THIS is the end time in the required time compare format

   set Tdone [format "%4d%03d%08d" $eY $eD $eMs]

# INITIALIZE looping flag 

   set GoOn 2

# INITIALIZE the index counter 

   set nE 0

# LOOP over the data until we have reached the end time

   while { $GoOn > 0 } { 

# READ the data

      set S [ReadUDF $KeY 0 0 0 0 1] 

# CHECK for out of data

      if { [lindex [split $S "|"] 0] == -1 } { break }
      
# CONVERT the data to units and save.  Save beginning time as well 

      set dV($nE) [ConvertToUnits $KeY 0 0 $uI rV]
      set tM($nE) [list $ExDa(0,BYR) $ExDa(0,BDY) $ExDa(0,BMSEC) 0]

# CHECK to see if the current time is between the requested start and stop
#   time.  If after the stop time we are done.

      set Ts [format "%4d%03d%08d" $ExDa(0,BYR) $ExDa(0,BDY) $ExDa(0,BMSEC)]
      set Te [format "%4d%03d%08d" $ExDa(0,EYR) $ExDa(0,EDY) $ExDa(0,EMSEC)]
      set tList [lsort -ascii -increasing [list $Ts $Tdone $Te]]
      set GoOn [lsearch $tList $Tdone]

# INCREMENT the index counter

      incr nE
   }

# THIS is the interval of time in seconds spaned by the measurement

   set mT [expr ($ExDa(0,EMSEC) - $ExDa(0,BMSEC)) / 1000.0]

# DONE - return the number of data points read

   return $nE
}

# THIS is the time range we are interested in

set bY 2005 ; set bD 33 ; set bH 14 ; set bM 0  ; set bS 0;
set eY 2005 ; set eD 33 ; set eH 14 ; set eM 45 ; set eS 0;

# THIS is the plot time range 

set BT [list $bY $bD $bH $bM $bS 0]
set ET [list $eY $eD $eH $eM $eS 0]

# EXPAND the input time by 5 minutes to take into account the effect of the
#   filter length.  If will corrupt data at the beginning and ending of the 
#   time period  

set sY $bY ; set sD $bD ; set sH $bH ; set sM [expr $bM - 5] ; set sS $bS
set fY $eY ; set fD $eD ; set fH $eH ; set fM [expr $eM + 5] ; set fS $eS

if { $sM < 0 } {
   incr sM 60 ; incr sH -1
   if { $sH < 0 } { incr sH 24 ; incr sD -1 }
   if { $sD < 1 } {
      incr sY -1
      incr sD [TUyearLeap $sY]
   }
}
if { $fM > 59 } {
   incr fM -60 ; incr fH 
   if { $fH > 23 } { incr fH -24 ; incr fD }
   set DiY [TUyearLeap $fY]
   if { $fD > $DiY } {
      incr fY 
      incr fD -$DiY
   }
}

# INITIALIZE the UDF common variables

UDFInits

# ESTABLISH the UDF Key

set KeY [GetDataKey CLUSTERII CLUSTER-3 EFW POTENTIAL SCPOT_SP]

# READ the data 

set nE [ReadData $KeY 0 1 $sY $sD $sH $sM $sS $fY $fD $fH $fM $fS tM pV mT] 

# CONVERT the data times into offsets in seconds from the beginning of the
#   time at which the plot starts and centered on the measurement.

# THIS is the start and stop time the plot and the same for the times
#   over which data is acquired

set bMs [expr $bH * 3600000 + $bM * 60000 + $bS]
set eMs [expr $eH * 3600000 + $eM * 60000 + $eS]
set sMs [expr $sH * 3600000 + $sM * 60000 + $sS]
set fMs [expr $fH * 3600000 + $fM * 60000 + $fS]

set bT [list $bY $bD $bMs 0]
set eT [list $eY $eD $eMs 0]
set sT [list $sY $sD $sMs 0]
set fT [list $fY $fD $fMs 0]

# THIS Base will give the difference in seconds.

set Base 1

# THIS does the conversion 

for  { set I 0 } { $I < $nE } { incr I } {
    set tM($I) [expr [TUtimeConv $bT $tM($I) 0 Base] + $mT / 2.0]
}

# START up the graphics

GraphicsOn TK ETones SWAP

# DEFINE the two plot windows, top one will hold the difference plot and
#   the lower one the data and SV fit

GenWindow 0 0.1 0.1 0.0 0.9 0.49 0.0  0. -8. 0. 7200. -4. 0. X
GenWindow 1 0.1 0.51 0.0 0.9 0.9 0.0  0. -2. 0. 7200.  2. 0. X

# DEFINE the plots as time based in X spanning the requested time

DefinePlot 0 0 -1 -1 X $BT $ET
DefinePlot 1 1 -1 -1 X $BT $ET

# SET up two grid definitions one which spans the plot time and one which
#   which spans the time over which the data was acquired. Both The X axis of the grid
#   spans the time offsets from the start time of the plot

set CT [list $bY $bD $bMs 0]

set gI(0) [TUtimeConv $CT $bT 0 Base]
set gI(1) [TUtimeConv $CT $eT 0 Base]
set gI(2) -1.0
set gI(3) 1.0
set gI(4) [expr int([lindex $PltInfo(0,Pix) 0])]
set gI(5) 1
set gI(6) POINT
set gI(7) POINT
set gI(8) COLUMN
set gI(9) KEEP
set gI(10) NEW:ADD:END
set gI(11) 10000.0
set gI(12) -1.0e31
set gI(13) -1.0e30
set gI(14) 1.0e30
set gI(15) NO
set gI(16) NO

set gIa(0) [TUtimeConv $CT $sT 0 Base]
set gIa(1) [TUtimeConv $CT $fT 0 Base]
set gIa(2) -1.0
set gIa(3) 1.0
set gIa(4) [expr int(($gIa(1) - $gIa(0)) / $mT)]
set gIa(5) 1
set gIa(6) POINT
set gIa(7) POINT
set gIa(8) COLUMN
set gIa(9) KEEP
set gIa(10) NEW:ADD:END
set gIa(11) 10000.0
set gIa(12) -1.0e31
set gIa(13) -1.0e30
set gIa(14) 1.0e30
set gIa(15) NO
set gIa(16) NO

# STICK the input data in the full grid.  Then do a fill on the grid to fill 
#   in any empty grids

set YY(0) 0.0
TUdataGrid $nE 1 tM tM $nE YY YY pV gData Norm gIa
TUgridFill1D gData gIa X HF -1 1

# THIS returns the X coordinates of the grid centers in the full grid

TUgridInfo 32 gIa XX

# STICK the full grid in the plot grid.  Then do a fill on the grid to fill 
#   in any empty grids.  This lops of the extra five minutes on the ends

TUdataGrid $gIa(4) 1 XX XX $gIa(4) YY YY gData pGrid Norm gI
TUgridFill1D pGrid gI X HF -1 1

# PLOT this data

Plot2D 0 Xb Yb Ab pGrid -1 0 LINE [list 250 < -1.0e30]

# Pad the full grid to 2^N, filling with 0.  Need this length in forming
#    the S-G filter

set End 1
while { $End <= $gIa(4) } {
   set End [expr $End * 2]
}
for { set I $gIa(4) } { $I < $End } { incr I } { set gData($I) 0.0 }

# FILTER the data using a S-G filter with 8 points on either side of the
#   center.  Since potential is spin averaged (~4s) this is about 1 min
#   data - less than the 5 mins we added at beginning and end.

set fOps(0) 8
set fOps(1) 8
set fOps(2) 2
TUdataFilter gData $End SAVITZKYGOLAY fOps fDSG

# GRID the filtered data and plot it

TUgridInfo 32 gIa XX
TUdataGrid $gIa(4) 1 XX XX $gIa(4) YY YY fDSG fGrid Norm gI
TUgridFill1D fGrid gI X HF -1 1
set oP [list $GphInfo(Blue) NONE HOLD HOLD 10 *]
Plot2D 0 Xb Yb Ab fGrid -1 0 LINE $oP

# DIFFERENCE filtered and non-filtered potential data and plot it

for { set I 0 } { $I < $gI(4) } { incr I } { 
   set Grid($I) [expr $pGrid($I) - $fGrid($I)]
}

Plot2D 1 Xb Yb Ab Grid -1 0 LINE $oP

# SET plots to have 5 major and minor ticks along Y axis

PLTinfoChg 0 Y TICKS MJNUMBER 5
PLTinfoChg 0 Y TICKS MNNUMBER 5
PLTinfoChg 1 Y TICKS MJNUMBER 5
PLTinfoChg 1 Y TICKS MNNUMBER 5

# DRAW the plot boxes.

PlotOutlines 0 [list X 1.0 POT 1] [list BOT BOT BOTH BOTH]
PlotOutlines 1 [list "" 1.0 "DIF" 1 ] [list NONE BOT BOTH BOTH]
set Lab "START TIME: $bY $bD ${bH}:${bM}:${bS}"
PLTaxisRec 1 Xt NONE AXIS 1.0 0.0 right $Lab
      
Feb 19, 2007