\cancel mode verify
! trackplot.jnl
! 4/99 *sh* and *jd*

! Description: Plot values of a variable alongside a plotted track

! Usage:                  $1        $2     $3     $4     $5       $6        $7
! yes?  GO trackplot plot_command xtrack ytrack values [scale] [baseline] [smooth]
! $1 - the plot command with qualifiers (eg PLOT/VS/OVER/LINE=2)
! $2 - X coordinates of track to be plotted
! $3 - Y coordinates of track to be plotted
! $4 - variable whose values will be plotted along the track (eg SST)
! $5 - optional: scale the values by this factor (in units/inch) 
! $6 - baseline (a.k.a. offset) -- what data value is associated with zero
!      displacement from the trackline ans the "horizontal axis" of the trackplot
!      Default = 0
! $7 - smooth the track to be plotted with SBX:$6 (optional, default 3)
!      The "smooth" parameter is given in units of the number of points over
!      which a running mean filter will be applied to the normal vectors. It 
!      is effective only in special cases. For "rough" paths, best results are
!      obtained by smoothing the position data that is passed to this script. 

! example
! Define synthetic data
!       yes? LET xpts = 230 - L[L=1:80]
!       yes? LET ypts = 30 + 20*SIN(L[L=1:80]/30)
!       yes? LET val  = RANDN(L[L=1:80])
!
! Draw base map
!       yes? go basemap x=130E:120W Y=10n:60n 20
!       yes? plot/vs/over/line/title="track" xpts, ypts
!
! Auto-scaled plot, then manually scaled plot
!	yes? GO trackplot plot/vs/over/line=2/title="my data" xpts, ypts, val
!       yes? SAY ($TRACKPLOTscale)     ! value is 3.356 units/inch
!	yes? GO trackplot plot/vs/over/line=4/title="scaled" xpts, ypts, val 3

! argument check
QUERY/IGNORE $1"<usage: yes? GO trackplot plot_command xtrack ytrack values [scale] [baseline] [smooth]"
QUERY/IGNORE $2"<usage: yes? GO trackplot plot_command xtrack ytrack values [scale] [baseline] [smooth]"
QUERY/IGNORE $3"<usage: yes? GO trackplot plot_command xtrack ytrack values [scale] [baseline] [smooth]"
QUERY/IGNORE $4"<usage: yes? GO trackplot plot_command xtrack ytrack values [scale] [baseline] [smooth]"

! save the input expressions into simple variable definitions
LET/QUIET TRKx = ($2)
LET/QUIET TRKy = ($3)
LET/QUIET TRKdata = ($4)
LET/QUIET TRKoffset = $6"0"

! determine the orientation of the data (and check that it is 1D)
DEFINE SYMBOL TRKax `TRKx,return=shape`

LET/QUIET TRKxscale = ((($xaxis_max))-(($xaxis_min)))/($ppl$xlen)
LET/QUIET TRKyscale = ((($yaxis_max))-(($yaxis_min)))/($ppl$ylen)

! compute factor to compensate for unequal scaling of X and Y plot axes
LET/QUIET TRKaxscale_factor = TRKyscale/TRKxscale
LET/QUIET TRKx_correction = (1 + TRKaxscale_factor^2)^0.5
LET/QUIET TRKy_correction = TRKaxscale_factor * TRKx_correction

! compute the local normal vector components -- (COS,SIN) --> (-SIN,COS)
! this will be used to createoffsets from track line
LET/QUIET TRKdx0 = MISSING(TRKx[($TRKax)=@ddc],MISSING(TRKx[($TRKax)=@ddf],TRKx[($TRKax)=@ddb])) * TRKaxscale_factor

LET/QUIET TRKdy0 = MISSING(TRKy[($TRKax)=@ddc],MISSING(TRKy[($TRKax)=@ddf],TRKy[($TRKax)=@ddb]))

LET/QUIET TRKds_mag = (TRKdx0^2+TRKdy0^2)^0.5
LET/QUIET TRKxnorm0 = TRKx_correction * (-1 *  TRKdy0 / TRKds_mag)
LET/QUIET TRKynorm0 = TRKy_correction * TRKdx0 / TRKds_mag

! smooth the normal vectors ...
LET/QUIET TRKxnorm = MISSING(TRKxnorm0[($TRKax)=@sbx:$6"3"],TRKxnorm0)
LET/QUIET TRKynorm = MISSING(TRKynorm0[($TRKax)=@sbx:$6"3"],TRKynorm0)

! determine default scale
LET/QUIET TRKmap_range = ( (($yaxis_max)-(($yaxis_min))) * (($xaxis_max)-(($xaxis_min))) ) ^ 0.5
LET/QUIET TRKdata_range = MAX(ABS(TRKdata[($TRKax)=@max])-TRKoffset,ABS(TRKdata[($TRKax)=@min])-TRKoffset)

! Handle all-zero fields & custom scaling...
LET/QUIET TRKinches = (($ppl$ylen)*($ppl$xlen))^0.5    ! blend X and Y ax lens
IF  $5"FALSE|*>TRUE" THEN 
    LET/QUIET TRKunitsperinch = $5     ! user-specified
ELIF `TRKdata_range eq 0` THEN 
    LET/QUIET TRKunitsperinch =  1     ! irrelevant
ELSE
    LET/QUIET TRKaxis_fraction = 0.06 ! fraction of axis length for default scale
    LET/QUIET TRKunitsperinch = TRKdata_range / (TRKaxis_fraction*TRKinches)  ! auto-scaled
ENDIF
DEFINE SYMBOL TRACKPLOTscale  `TRKunitsperinch`
DEFINE SYMBOL TRACKPLOToffset `TRKoffset`


LET/QUIET TRKscale = TRKmap_range / (TRKunitsperinch * TRKinches)

LET/QUIET TRKxplot = TRKx + TRKscale*TRKxnorm*(TRKdata-TRKoffset)
LET/QUIET TRKyplot = TRKy + TRKscale*TRKynorm*(TRKdata-TRKoffset)

$1/vs TRKxplot,TRKyplot

cancel symbol TRK*
cancel variable TRK*
set mode/last verify
