Appendix A: EXTERNAL FUNCTIONS
A number of external functions are included with the Ferret distribution. This number is expected to grow as Ferret developers and users contribute more functions. See the chapter "Writing External Functions" (p. 293) for how to adapt your Fortran code to a Ferret external function. Send your contributions to the Users Guide editor at oar.pmel.contact_ferret@noaa.gov .
Many of these functions, originally developed as external functions, are now linked into the Ferret executable as static functions. The code for them is still available on the Ferret external functions web page.
The functions are listed in the following sections. To see what functions are available to you, type
yes? SHOW FUNCTION/EXTERNAL
or
yes? SHOW FUNCTIONS/DETAILS/EXTERNAL function_name
gives further details on how the arguments influence the grid for the function's result.
COMPRESSI(DAT) Returns data, compressed along the I axis: Missing points moved to the end
|
Arguments: |
DAT |
DAT: variable to compress in I |
|
Result Axes: |
X |
ABSTRACT, same length as DAT x-axis |
|
Y |
Inherited from DAT |
|
|
Z |
Inherited from DAT |
|
|
T |
Inherited from DAT |
Note:
It is generally advisable to include explicit limits when working
with functions that replace axes. for example, consider the function compressi(v).
The expression
list/i=6:10 compressi(v)
is not equivalent to
list compressi(v[i=6:10])
The former will list the 6th through 10th compressed indices from the entire i range of variable v. the latter will list all of the indices that result from compressing v[i=6:10].
COMPRESSJ(DAT) Returns data, compressed along the J axis: Missing points moved to the end
|
Arguments: |
DAT |
DAT: variable to compress in J |
|
Result Axes: |
X |
Inherited from DAT |
|
Y |
ABSTRACT, same length as DAT y-axis |
|
|
Z |
Inherited from DAT |
|
|
T |
Inherited from DAT |
Note: see the note under COMPRESSI on specifying axis limits (p. 75)
COMPRESSK(DAT) Returns data, compressed along the I axis: Missing points moved to the end
|
Arguments: |
DAT |
DAT: variable to compress in K |
|
Result Axes: |
X |
Inherited from DAT |
|
Y |
Inherited from DAT |
|
|
Z |
ABSTRACT, same length as DAT z-axis |
|
|
T |
Inherited from DAT |
Note: see the note under COMPRESSI on specifying axis limits (p. 75)
COMPRESSL(DAT) Returns data, compressed along the L axis: Missing points moved to the end
|
Arguments: |
DAT |
DAT: variable to compress in L |
|
Result Axes: |
X |
Inherited from DAT |
|
Y |
Inherited from DAT |
|
|
Z |
Inherited from DAT |
|
|
T |
ABSTRACT, same length as DAT t-axis |
Note: see the note under COMPRESSI on specifying axis limits (p. 75)
COMPRESSI_BY (var, mask), Compress data according to a mask
|
Arguments: |
VAR |
Variable to compress according to MASK |
|
MASK |
mask to use in compressing the data |
|
|
Result Axes: |
X |
Abstract |
|
Y |
Inherited from VAR and MASK |
|
|
Z |
Inherited from VAR and MASK |
|
|
T |
Inherited from VAR and MASK |
Compress variable "dat" along its I axis using the (multi-dimensional) mask supplied in the second argument.
For example:
yes? LET mask = {1,,1,,1} + 0*L[l=101:102] + 0*K[k=10:11]
yes? LIST mask
{1,,1,,1} + 0*L[L=101:102] + 0*K[K=10:11]
1 2 3 4 5
1 2 3
4 5
---- L:101 T: 101
10 / 10: 1.000 .... 1.000
.... 1.000
11 / 11: 1.000 .... 1.000 .... 1.000
----
L:102 T: 102
10 / 10: 1.000 .... 1.000 .... 1.000
11 / 11: 1.000 .... 1.000 .... 1.000
yes? LIST compressi_by({11,22,33,44,55},mask)
COMPRESSI_BY({11,22,33,44,55},MASK)
1 2 3 4 5
1 2 3
4 5
---- L:101 T: 101
10 / 10: 11.00 33.00 55.00
.... ....
11 / 11: 11.00 33.00 55.00 .... ....
----
L:102 T: 102
10 / 10: 11.00 33.00 55.00 .... ....
11 / 11: 11.00 33.00 55.00 .... ....
COMPRESSJ_BY (var, mask), Compress data according to a mask
Compress variable "dat" along its J axis using the (multi-dimensional) mask supplied in the second argument. See the example under COMPRESSI_by.
COMPRESSK_BY (var, mask), Compress data according to a mask
|
Arguments: |
VAR |
Variable to compress according to MASK |
|
MASK |
mask to use in compressing the data |
|
|
Result Axes: |
X |
Inherited from VAR and MASK |
|
Y |
Inherited from VAR and MASK |
|
|
Z |
Abstract |
|
|
T |
Inherited from VAR and MASK |
Compress variable "dat" along its K axis using the (multi-dimensional) mask supplied in the second argument. See the example under COMPRESSI_by.
COMPRESSL_BY (var, mask), Compress data according to a mask
|
Arguments: |
VAR |
Variable to compress according to MASK |
|
MASK |
mask to use in compressing the data |
|
|
Result Axes: |
X |
Inherited from VAR and MASK |
|
Y |
Inherited from VAR and MASK |
|
|
Z |
Inherited from VAR and MASK |
|
|
T |
Abstract |
Compress variable "dat" along its L axis using the (multi-dimensional) mask supplied in the second argument. See the example under COMPRESSI_by.
CONVOLVEI (VAR, WEIGHT), CONVOLVEJ (VAR, WEIGHT) ,
CONVOLVEK (VAR, WEIGHT),
CONVOLVE L (VAR, WEIGHT)
Convolve I (J,K,or L)component of variable
with weight function
|
Arguments: |
VAR |
COM: variable to convolve |
|
WEIGHT |
Weight function |
|
|
Result Axes: |
X |
Inherited from VAR |
|
Y |
Inherited from VAR |
|
|
Z |
Inherited from VAR |
|
|
T |
Inherited from VAR |
This function (and likewise CONVOLVEJ, CONVOLVEK, and CONVOLVEL) convolves the variable VAR, with the weight function, wt along the X axis. Note that the variable's context may not be of adequate size for the full calculation. Missing data flags will be inserted where computation is impossible.
When bad data points are encountered in the component data all result data depending on it are flagged as bad, too.
The weight function is applied at each point from i-hlen to i+hlen, where hlen is half the length of the weight function. If the function is of even length, a zero weight is used at the upper end. Thus if the weights were {0.1, 0.4, 0.4, 0.1} the result at point I would be computed as the sum 0.1* COM(i-2) + 0.4* com(i-1) + 0.4* COM(i) + 0.1* COM(i+1) + 0.* COM(i+2)
Example:
Use the function to smooth a variable.
yes? LET weight = {0.25, 0.5, 0.25}
yes? LET c = SIN(x[x=0:10:.1]) + RANDU(X[X=0:10:.1])/5
yes?
PLOT c
yes? PLOT/OVER/TITLE="convolvei" CONVOLVEI(c,weight)
Appendix A Sec10. CURV_TO_RECT_MAP
CURV_TO_RECT_MAP(lon_in, lat_in, grid_out, radius)
Computes mapping parameters for regridding from a curvilinear grid (see p. 252) to a rectilinear latitude-longitude grid. The mapping is applied to data with the function CURV_TO_RECT which interpolates the data to the rectilinear grid. This computation uses a spherical interpolation code written at GFDL; the Ferret developers are responsible for its implementation as an external function.
The output of this function is a set of mapping parameters; this mapping may be saved and applied to interpolate any field on the curvilinear grid onto the output rectangular grid.
|
Arguments: |
lon_in |
Source grid longitudes, in degrees (2-D field of longitudes describing the curvilinear grid) |
|
lat_in |
Source grid latitudes, in degrees (2-D field of latitudes describing the curvilinear grid) |
|
|
grid_out |
Any variable on the output recangular lon-lat grid. This grid may have irregularly spaced longitude and/or latitude axes |
|
|
radius |
Source points falling within radius (in degrees) of destination point are included in the mapping to the destination point. Described further below. |
|
|
Result Axes: |
X |
Inherited from grid_out |
|
Y |
Inherited from grid_out |
|
|
Z |
Abstract |
|
|
T |
Abstract |
This function does large amounts of calculation, and so runs slowly. It is recommended that you compute mappings from the curvilinear grid to desired rectilinear grid(s) and save them for use with your data fields. For an example of a call to this function see the documentation for the function CURV_TO_RECT, below (p. 467).
The following figure illustrates a destination grid location (*) with a radius of influence R. Valid source curvilinear grid locations (o) which fall within the radius of influence of the destination point are used in the mapping. Missing source points (x) do not contribute to the mapping. In this case, 13 valid source grid points fall within the radius of influence.
The radius parameter should be chosen to be somewhat larger than the size of the input curvilinear grid cells so that any output grid location will have some input data contributing to its value.
e the value.The variable MAP, the result of a call to function CURV_TO_RECT_MAP, contains weights and the indices of the longitudes and latitudes of the curvilinear grid that correspond to the coordinates of the output grid. Below, in_curv_lon and in_curv_lat are the index value from the input curvilinear grid that correspond to the longitude and latitude of the rectangular output grid. The parameter num_neighbors is 4; the code looks around at four neighboring grid cells.
The weights are based on the distance from the source to the result grid points. The output variable map, then contains:
for each m = 1, nlon_out
for each n = 1, nlat_out
for each k=1, num_neighbors
MAP(m,n,k,1) = weight(m,n,k)
MAP(m,n,k,2) = in_curv_lon(m,n,k)
MAP(m,n,k,3) = in_curv_lat(m,n,k)
This may be used to determine the range of indices required in order to specify a subset of data on a curvilinear grid. See the FAQ, Plotting subsets of data on a curvilinear grid http://ferret.pmel.noaa.gov/FERRET_17sep07/FAQ/custom_plots/subsetting_curvi_data.html, for an outline of the procedure.
Appendix A Sec11. CURV_TO_RECT
CURV_TO_RECT (V, mapping)
Applies the mapping computed by function CURV_TO_RECT_MAP to interpolate data from a curvilinear to a rectilinear latitude-longitude grid. This computation employs a spherical interpolation code written at GFDL; the Ferret developers are responsible for its implementation as an external function.
|
Arguments: |
V |
Variable on the source curvilinear grid |
|
mapping |
mapping from the source grid to a rectilinear grid |
|
|
Result Axes: |
X |
Inherited from mapping |
|
Y |
Inherited from mapping |
|
|
Z |
Inherited from V |
|
|
T |
Inherited from V |
This is a grid-changing function. Indicate limitson the argument axes with square brackets []. See the note on grid-changing functions in Chapter 3 (p. 77)
Example of calls to CURV_TO_RECT_MAP and CURV_TO_RECT:
yes? use my_curvilinear_data.nc
yes? show data
currently SET data sets:
1> /.my_curvilinear_data.nc (default)
name title
I J K L
GEOLON geographic longitude of grid 1:180
1:173 ... ...
GEOLAT geographic latitude of grid 1:180 1:173
... ...
SALT salinity 1:180 1:173 1:30 1:12
AIRT air temperature 1:180 1:173 1:30 1:12
yes? ! For convenience define variables with the input grid
yes? let lonin = geolon[d=1]
yes? let latin = geolat[d=1]
yes? ! Define output grid and a variable on the output grid
yes? define axis/x=0:360:5/modulo/units=degrees xax
yes? def axis/y=0:85:5/units=degrees
yax
yes? let lonlatout = y[gy=yax] + x[gx=xax]
yes? ! Compute the mapping to the rectangular grid, save to a file
yes?
let map = curv_to_rect_map ( lonin,latin,lonlatout,10)
yes? save/clobber/file=curv_map.nc
map
yes? ! Apply the mapping to the data fields
yes? cancel var/all
yes? use curv_map.nc
yes? let out_salt = curv_to_rect(salt[d=1,K=1,L=2],
map[d=2])
yes? shade out_salt
yes? let out_airt = curv_to_rect(airt[d=1], map[d=2])
yes? save/file=air_on_rect.nc out_airt
Appendix A Sec12. RECT_TO_CURV
RECT_TO_CURV (V, lon_bounds_out, lat_bounds_out, missing_allowed) Uses Bilinear Interpolation to regrid data on a recilinear grid to a curvilinear grid.
|
Arguments: |
V |
Variable on the source rectilinear grid |
|
lon_bounds_out |
Destination grid longitudes, in degrees (2-D field of longitudes describing the curvilinear grid) |
|
|
lat_bounds_out |
Destination grid latitudes, in degrees (2-D field of latitudes describing the curvilinear grid) |
|
|
missing_allowed |
Number of missing values allowed among the 4 surrounding source cells: 0 to 3 |
|
|
Result Axes: |
X |
Inherited from lon_bounds_out |
|
Y |
Inherited from lat_bounds_out |
|
|
Z |
Inherited from V |
|
|
T |
Inherited from V |
Example: put a rectilinear data set on a curvilinear grid for comparison.
yes? use my_curvilinear_data.nc
yes? use levitus_climatology
yes? show data
currently SET data sets:
1> /.my_curvilinear_data.nc
name
title I J K L
GEOLON geographic longitude
of grid 1:180 1:173 ... ...
GEOLAT geographic latitude of grid
1:180 1:173 ... ...
SALT salinity 1:180
1:173 1:30 1:12
AIRT air temperature 1:180 1:173
1:30 1:12
2> /home/ja9/tmap/fer_dsets/data/levitus_climatology.cdf (default)
name title I J K L
TEMP TEMPERATURE
1:360 1:180 1:20 ...
SALT SALINITY
1:360 1:180 1:20 ...
yes? ! For convenience, define variables for arguments to RECT_TO_CURV
yes? let lonout = geolon[d=1]
yes? let latout = geolat[d=1]
yes? let a = rect_to_curv(temp[d=2,k=1], lonout, latout, 2)
yes? shade a,
lonout, latout
yes? ! Compare to a variable on the curvilinear grid
yes? shade a-airt[d=1], lonout, latout
yes? ! save the new variable for all depths, with the curvilinear
yes? ! latitude and longitude variables
yes? let temp_curv = rect_to_curv(temp[d=2],
lonout, latout, 2)
yes? save/file=tcurv.nc temp_curv, lonout, latout
LISTing
to file tcurv.nc
DATE1900(formatted date) Scalar function: converts a formatted date into Julian days since 1-Jan-1900.
|
Argument: |
formatted date |
dd-mmm-yyyy or dd-mmm-yyyy, in quotes |
|
Result Axes: |
X |
NORMAL (no axis) |
|
Y |
NORMAL (no axis) |
|
|
Z |
NORMAL (no axis) |
|
|
T |
NORMAL (no axis) |
Examples:
yes? list date1900("23-feb-2003")
VARIABLE : DATE1900("23-feb-2003")
37673.
yes? list date1900("2-jan-1900")
VARIABLE :
DATE1900("2-jan-1900")
1.000
Appendix A Sec14. DAYS1900TOYMDHMS
DAYS1900TOYMDHMS(day1900) Converts Julian days since 1-Jan-1900 to values year, month, day, hour, minute, second.
|
Argument: |
day1900 |
Julian day counted from 1-jan-1900 |
|
Result Axes: |
X |
Inherited from argument |
|
Y |
Inherited from argument |
|
|
Z |
ABSTRACT (results occupy indices 1...6) |
|
|
T |
Inherited from argument |
This function applies only to time in the standard, Gregorian calendar.
Example:
Create a variable based on a time axis. List the result of DAYS1900TOYMDHMS.
yes? DEF AXIS/T=28-JAN-2003:3-FEB-2003:1/UNITS=days/T0=1-JAN-1900 timeax
yes?
LET tday = T[gt=timeax]
yes? LIST days1900toymdhms(tday)
VARIABLE
: DAYS1900TOYMDHMS(TDAY)
SUBSET : 6 by 9 points (Z-TIME)
1 2 3 4 5 6
1 2 3 4 5 6
28-JAN-2003 00 / 1:
2003. 1. 28. 0. 0. 0.
29-JAN-2003 00 / 2: 2003.
1. 29. 0. 0. 0.
30-JAN-2003 00 / 3: 2003. 1. 30.
0. 0. 0.
31-JAN-2003 00 / 4: 2003. 1. 31. 0.
0. 0.
01-FEB-2003 00 / 5: 2003. 2. 1. 0. 0.
0.
02-FEB-2003 00 / 6: 2003. 2. 2. 0. 0. 0.
03-FEB-2003
00 / 7: 2003. 2. 3. 0. 0. 0.
Appendix A Sec15. ELEMENT_INDEX
ELEMENT_INDEX(A, B) Returns index value in B for each point in A
Example
yes? LIST ELEMENT_INDEX({6,5,4,3,2,1}, {1,2,3})
VARIABLE :
ELEMENT_INDEX ({6,5,4,3,2,1}, {1,2,3})
SUBSET : 6 points
(X)
1 / 1: ....
2 / 2: ....
3 / 3: ....
4 / 4: 3.000
5
/ 5: 2.000
6 / 6: 1.000
Appendix A Sec16. ELEMENT_INDEX_STRING
ELEMENT_INDEX_STRING(A, B) Returns index value in B for each string in A. The string comparisons are case-sensitive.
|
Arguments: |
A |
string data to mask |
|
B |
list of strings to match |
|
|
Result Axes: |
X |
Inherited from argument A |
|
Y |
Inherited from argument A |
|
|
Z |
Inherited from argument A |
|
|
T |
Inherited from argument A |
Example
(See ELEMENT_INDEX) above for a simple example of the numeric case. )
Say we have a dataset that contains a string variable called institute for a collection of stations, and station locations xloc, yloc. Use ELEMENT_INDEX_STR to draw a polygon plot where the ! data stations belonging to each institute is shown by a dot with a unique color for each institution.
yes? USE obsdata.nc ! contains a variable called institute
yes? LET inst_names
= {NOAA, WHOI, FSU, BOM}
yes? LET code = IS_ELEMENT_STR(institute,
inst_names)
yes? LIST institute, code
X: 0.5 to 53.5
Column 1: INSTITUTE
Column 2: CODE is ELEMENT_INDEX_STR(institute, {NOAA, FSU, BOM,
WHOI})
INSTITUTE CODE
1 / 1: NOAA 1.000
2 / 2: WHOI
4.000
3 / 3: FSU 2.000
4 / 4: BOM 3.000
5 / 5: NOAA
1.000
6 / 6: BOM 3.000
...
yes? GO basemap X=120:250 Y=25S:65N
20
yes? GO polymark POLY/OVER/PALETTE=rainbow_by_levels/LEV=(1,5,1) \ xloc,
yloc, code, square, 0.2
EOF_SPACE(A, FRAC_TIMESER) Returns EOF (Empirical Orthogonal Function) spacial fields(eigenfunctions) from x-y-z-time field
|
Arguments: |
A |
Variable in any spatial dimensions, and time |
|
FRAC_TIMESER |
Use only those time series with this fraction valid data, e.g. 0.8 to require that 80% of the data be present to use the data at a location. |
|
|
Result Axes: |
X |
Inherited from A |
|
Y |
Inherited from A |
|
|
Z |
Inherited from A |
|
|
T |
ABSTRACT 1 to NEOF |
The EOF functions all make the same computations, returning different portions of the results. EOF_SPACE returns the eigenfunctions, normalized so that they have the units of data, while time amplitude functions (TAF's) are dimensionless. Thus the sum of the values of a given EOF = sqrt(eigenvalue), and the mean of a given TAF = 1. EOF_STAT returns some useful statistics: the number of EOF's which were computed and normalized for the parameters given; the %variation explained for each eigenfunction, and the eigenvalues.
Specifying the context of the input variable explicitly e.g.
EOF_SPACE(A[x=20:40,y=2s:40n,l=1:58],FRAC_TIMESER)
will prevent any confusion about the region. See the note in chapter 3 (p.77 )on the context of variables passed to functions.
The method is an implementation of Chelton's '82 method for finding EOFs of gappy time series. If there are no gaps, it reduces to ordinary EOFs.
The EOF analysis solves a matrix problem where the matrix is dimensioned (NX*NY*NZ) by NT, which can quickly become quite large. The EOF functions use other workspace as well which demands even more memory, and often memory must be increased with the SET MEMORY command. Regridding to a coarser grid or restricting the region may be necessary.
See the example under EOF_STAT for more on the input parameters, and see the demonstration ef_eof_demo.jnl for examples of this function.
Note: Earlier versions of the EOF functions had one more parameter. Check the version you have by saying
yes? SHOW FUNCTION eof*
EOF_STAT(A,FRAC_TIMESER) Used with EOF_SPACE and/or EOF_TFUNC. Return statistics related to an EOF solution for a given set of parameters. Results are on the x-axis j = 1: # EOFscomputed and scaled, j = 2: % percentage of total variance accounted for by each eigenvector, j = 3: the eigenvalues.
|
Arguments: |
A |
Variable in any spatial dimensions, and time |
|
FRAC_TIMESER |
Use only those time series with this fraction valid data, e.g. 0.8 to require that 80% of the data be present to use the data at a location. |
|
|
Result Axes: |
X |
ABSTRACT: 1 to NEOF |
|
Y |
ABSTRACT: 1 through 3 as outlined in the description. |
|
|
Z |
NORMAL (no axis) |
|
|
T |
NORMAL (no axis) |
Please see the discussion under EOF_SPACE, and see the demonstration ef_eof_demo.jnl for examples of this function.
Example results:
For a simple sample function, eof_stat called to decompose it into eigenfunctions. We allow data to be used if the time series at the point has at least 80% valid data.
Request the number of eigenvalues computed for this choice of parameters.
yes? list/i=1/j=1 eofstat
VARIABLE : EOF_STAT(SST[X=67W:1W,Y=11S:11N],
0.8)0
DATA SET : COADS Monthly Climatology (1946-1989)
FILENAME : coads_climatology.des
FILEPATH : /home/ja9/tmap/fer_dsets/descr/
X : 1
Y : 1
284.0
Now get the percent variance explained by the eigenfunctions which were computed.
yes? list/i=1:10/j=2 eofstat
VARIABLE : EOF_STAT(SST[X=67W:1W,Y=11S:11N],
0.8)
DATA SET : COADS Monthly Climatology (1946-1989)
FILENAME : coads_climatology.des
FILEPATH : /home/ja9/tmap/fer_dsets/descr/
SUBSET : 10 points (X)
Y : 2
2
2
1 / 1: 86.95
2 / 2: 5.82
3 /
3: 3.87
4 / 4: 1.51
5 / 5: 0.56
6 / 6: 0.38
7 /
7: 0.31
8 / 8: 0.23
9 / 9: 0.15
10 / 10: 0.11
And finally the eigenvalues associated with these eigenfunctions.
yes? list/i=1:10/j=3 eofstat
VARIABLE : EOF_STAT(SST[X=67W:1W,Y=11S:11N],
0.8)
DATA SET : COADS Monthly Climatology (1946-1989)
FILENAME : coads_climatology.des
FILEPATH : /home/ja9/tmap/fer_dsets/descr/
SUBSET : 10 points (X)
Y : 3
3
3
1 / 1: 249.4
2 / 2: 16.7
3 /
3: 11.1
4 / 4: 4.3
5 / 5: 1.6
6 / 6: 1.1
7 /
7: 0.9
8 / 8: 0.7
9 / 9: 0.4
10 / 10: 0.3
EOF_TFUNC(A, FRAC_TIMESER) Compute EOF time amplitude functions from x-y-z-time field w/gaps.
Please see the discussion under EOF_SPACE, and see the demonstration ef_eof_demo.jnl for examples of this function.
The time amplitude functions (TAF's) are dimension less; and the mean of a given TAF = 1. They are returned as follows: For x=1, time amplitude function corresponding to the first eigenfunction is the time series with t=1:NT.
FINDHI(A,XRANGE,YRANGE) Find local maxima of a variable.
|
Arguments: |
A |
Variable in x and y, may be a function of z and/or t |
|
XRANGE |
Range in data units of the X radius in which the function looks for maxima |
|
|
YRANGE |
Range in data units of the Y radius in which the function looks for maxima |
|
|
Result Axes: |
X |
ABSTRACT |
|
Y |
ABSTRACT: j=1:3 |
|
|
Z |
Inherited from A |
|
|
T |
Inherited from A |
The maxima are listed along the X axis: j=1 contains the X locations of the points, j=2 contains the Y coordinates of the points, and j=3 contains the function values at the maxima.
This function looks for the maximumm gridded value in the neighborhood x+/- XRANGE, Y+/- YRANGE. It returns only values in the interior of the region, not on boundaries. It is an implementaion of the NCAR graphics routine "minmax"
The GO script label_hi_lo.jnl makes it easy to call this function and label and label low's and high's with either their numerical value or the letters L and H. See the demonstration script minmax_label_demo.jnl
Also see the script bullseye.jnl which locates and marks a "bullseye", i.e. a local minimum or maximum in a 2-D field within a user-specified region.
FINDLO(A,XRANGE,YRANGE) Find local minima of a variable.
|
Arguments: |
A |
Variable in x and y, may be a function of z and/or t |
|
XRANGE |
Range in data units of the X radius in which the function looks for minima |
|
|
YRANGE |
Range in data units of the Y radius in which the function looks for minima |
|
|
Result Axes: |
X |
ABSTRACT |
|
Y |
ABSTRACT: j=1:3 |
|
|
Z |
Inherited from A |
|
|
T |
Inherited from A |
The minima are listed along the X axis: j=1 contains the X locations of the points, j=2 contains the Y coordinates of the points, and j=3 contains the function values at the minima.
This function looks for the minimumm gridded value in the neighborhood x+/- XRANGE, Y+/- YRANGE. It returns only values in the interior of the region, not on boundaries. It is an implementaion of the NCAR graphics routine "minmax".
The GO script label_hi_lo.jnl makes it easy to call this function and label and label low's and high's with either their numerical value or the letters L and H. See the demonstration script minmax_label_demo.jnl
Also see the script bullseye.jnl which locates and marks a "bullseye", i.e. a local minimum or maximum in a 2-D field within a user-specified region.
FFT_IM(A) computes the imaginary part of Fast Fourier Transform of time series in variable A
|
Arguments: |
A |
Variable with a regular time axis; may be a function of x, y, and/or z |
|
Result Axes: |
X |
Inherited from A |
|
Y |
Inherited from A |
|
|
Z |
Inherited from A |
|
|
T |
Generated by the function: frequency in cyc/(time units from A) |
The units of the returned time axis are "cycles/Dt" where Dt is the time increment.
Even and odd N's are allowed. N need not be a power of 2. FFT_RE and FFTP_IM assume f(1)=f(N+1), and the user gives the routines the first N pts.
Specifying the context of the input variable explicitly e.g.
LIST FFT_IM(A[l=1:58])
will prevent any confusion about the region. See the note in chapter 3 (p. 77)on the context of variables passed to functions.
The code is based on the FFT routines in Swarztrauber's FFTPACK available at www.netlib.org. See the section on FFTA for more discussion (p. 86). For further discussion of the FFTPACK code, please see the document, Notes on FFTPACK - A Package of Fast Fourier Transform Programs at http://ferret.pmel.noaa.gov/FERRET_17sep07/Documentation/FFTpack_notes/FFTPACK_notes.html
FFT_RE(A) computes the real part of Fast Fourier Transform of time series in variable A
|
Arguments: |
A |
Variable with a regular time axis; may be a function of x, y, and/or z |
|
Result Axes: |
X |
Inherited from A |
|
Y |
Inherited from A |
|
|
Z |
Inherited from A |
|
|
T |
Generated by the function: frequency in cyc/(time units from A) |
The units of the returned time axis are "cycles/Dt" where Dt is the time increment.
Even and odd N's are allowed. N need not be a power of 2. FFT_RE and FFT_IM assume f(1)=f(N+1), and the user gives the routines the first N pts.
Specifying the context of the input variable explicitly e.g.
LIST FFT_RE(A[l=1:58])
will prevent any confusion about the region. See the note in chapter 3 (p. 77)on the context of variables passed to functions.
The code is based on the FFT routines in Swarztrauber's FFTPACK available at www.netlib.org. See the section on FFTA for more discussion (p. 86). For further discussion of the FFTPACK code, please see the document, Notes on FFTPACK - A Package of Fast Fourier Transform Programs at http://ferret.pmel.noaa.gov/FERRET_17sep07/Documentation/FFTpack_notes/FFTPACK_notes.html
FFT_INVERSE(AR, AI) computes the inverse Fast Fourier Transform of the two frequency series AR and AI
|
Arguments: |
AR |
Real part of an FFT transform. Variable with a frequency axis; may be a function of x, y, and/or z |
|
AI |
Imaginary part of an FFT transform. Variable with a frequency axis; may be a function of x, y, and/or z |
|
|
Result Axes: |
X |
Inherited from AR, AI |
|
Y |
Inherited from AR, AI |
|
|
Z |
Inherited from AR, AI |
|
|
T |
Abstract axis: 2*length of input frequency axes of AR and AI |
The returned time axis is abstract; the user will need to regrid it to the appropriate time axis.
The code is based on the FFT routines in Swarztrauber's FFTPACK available at www.netlib.org. See the section on FFTA for more discussion (p. 86). For further discussion of the FFTPACK code, please see the document, Notes on FFTPACK - A Package of Fast Fourier Transform Programs at http://ferret.pmel.noaa.gov/FERRET_17sep07/Documentation/FFTpack_notes/FFTPACK_notes.html
Appendix A Sec25. IS_ELEMENT_OF
IS_ELEMENT_OF(A, B) returns 1 if any element of B matches any element of A, and 0 if there is no match
|
Arguments: |
A |
Numeric variable to search |
|
B |
Numeric variableto match |
|
|
Result Axes: |
X |
Abstract, 1 element long |
|
Y |
Normal |
|
|
Z |
Normal |
|
|
T |
Normal |
Example:
yes? list/nohead IS_ELEMENT_OF ({44,55,66}, {55}) 1.00
Appendix A Sec26. IS_ELEMENT_OF_STR
IS_ELEMENT_OF_STR(A, B) returns 1 if any element of string variable B matches any element of string variable A, and 0 if there is no match. The comparisons are case-sensitive.
|
Arguments: |
A |
String variable to search |
|
B |
String variable to match |
|
|
Result Axes: |
X |
Abstract, 1 element long |
|
Y |
Normal |
|
|
Z |
Normal |
|
|
T |
Normal |
Example:
yes? list/nohead IS_ELEMENT_OF_STR ({"HELLO", "hello", "Friend"}, {"Friend",
"bye"})
1.00
yes? list/nohead IS_ELEMENT_OF_STR ({"HELLO", "hello", "Friend"},
{"friend", "heLLo"})
0.00
LANCZOS(A, F1, F2, N ) Returns the argument, bandpass-filtered in time using a Lanczos filter.
|
Arguments: |
A |
Variable with a regular time axis; may be a function of x, y, and/or z |
|
F1 |
Low frequency cutoff |
|
|
F2 |
High frequency cutoff |
|
|
N |
Number of weights (must be odd) |
|
|
Result Axes: |
X |
Inherited from A |
|
Y |
Inherited from A |
|
|
Z |
Inherited from A |
|
|
T |
Inherited from A |
For details see: Duchon, C. E., 1979: Lanczos filtering in one and two dimensions. J. of App. Met., 18, 1016-1022. This function is based on code written by Bill Gustafson at UC Davis.
Example: apply filter to series after removing its mean.
yes? use monthly_navy_winds
yes? let aa = uwnd[i=50,j=20]
yes? let az = aa
- aa[t=@ave]
yes? plot az
yes? plot/over lanczos(az, 0.05, 0.1, 11)
yes? plot/over
lanczos(az, 0.1, 0.2, 11)
LSL_LOWPASS(A, cutoff_period, filter_span) Returns the argument filtered with Least Squares Lanzcos filter in time.
|
Arguments: |
A |
Variable with a regular time axis; may be a function of x, y, and/or z |
|
cutoff_period |
Cutoff period (the period at which the filter attains 1/2 amplitude) |
|
|
filter_span |
number of input data points used in each filtered output point. |
|
|
Result Axes: |
X |
Inherited from A |
|
Y |
Inherited from A |
|
|
Z |
Inherited from A |
|
|
T |
Inherited from A |
This function low-pass filters an equally spaced time series using least-squares approximation to the ideal low-pass filter of Bloomfield with Lanczos convergence factors. It is very similar to subroutine LOPASS in Chapter 6, p. 149, of Bloomfield, P., 1976, Fourier Analysis of Time Series: An Introduction, John Wiley & Sons, New York, 258 pp.
The main difference is that the present routine takes account of missing values in the input time series Values near the ends and near gaps are filled with the missing value flag.
The cutoff period is the period at which the filter attains ½ amplitude or 1/4 "energy", measured in units of delta T. The cutoff_period must be less than or equal to N, the length of the time axis.
The filter span is the number of input data points used in each filtered output point. A wide filter gives a narrow frequency response transition band, but leads to ringing near data discontinuities and loss of filtered values at the end points and surrounding missing values. A narrow filter reduces ringing and output data loss, but gives a wider frequency transition width, i.e. it falls off less rapidly at frequencies higher than the cutoff. The filter transition region lies in the period range between N*cutoff_period/(N + cutoff_period) and N*cutoff_period/(N - cutoff_period). The filter span should be an odd integer. It is set to the next lower odd number if the input is even.
Note on tidal filtering: For hourly time series containing tidal signals, some investigators use this filter with a 35-hour cutoff period and a filter span of xxx hours to remove at least 99.5 % of the energy for periods less than 25 hours.
Adapted from Bloomfield by E. D. Cokelet, NOAA/PMEL, 3 Dec 1999
MINUTES24(formatted time) Scalar function: converts a formatted time of day into minutes since 00:00, with fractions of minutes.
|
Argument: |
formatted time |
hours, minutes, seconds in the form |
|
Result Axes: |
X |
NORMAL (no axis) |
|
Y |
NORMAL (no axis) |
|
|
Z |
NORMAL (no axis) |
|
|
T |
NORMAL (no axis) |
Examples:
yes? list minutes24("12:24:13")
VARIABLE : MINUTES24("12:24:13")
744.2
yes? list minutes24("00:30:30")
VARIABLE : MINUTES24("00:30:30")
30.50
WRITEV5D(V1,V2,V3,V4,V5,V6,V7,V8,FILENAME) Write up to 8 variables to a Vis5D-formatted file
|
Arguments: |
V1 |
|
|
V2 |
||
|
V3 |
Up to 8 variables to write to the file |
|
|
V4 |
||
|
V5 |
||
|
V6 |
||
|
V7 |
||
|
V8 |
||
|
FILENAME |
Name of the file to write: file type for Vis5d files is .v5d |
|
|
Result Axes: |
X |
Inherited from variables: all variables must have the same x and y axes |
|
Y |
Inherited from variables: all variables must have the same x and y axes |
|
|
Z |
Inherited from variables; the result grid will contain the union of all the levels that are present in the variables. |
|
|
T |
Inherited from variables: all variables must have the same time axis |
This function calls utility functions from the Vis5D distribution to write a Vis5D-formatted file containing Ferret variables. TheVis5D tool is a system for interactive visualization of large 5-D gridded data sets. It was developed by Bill Hibbard and others at the University of Wisconsin, and can be found at
http://www.ssec.wisc.edu/~billh/vis5d.html
There are limits in Vis5D on the size of the grid and the number of timesteps. The function will issue an error if these limits are exceeded.
To make it more convenient to call the writev5d function, to open Vis5D from Ferret, and to append to a Vis5D file, GO tools are available: vis5d_write.jnl, vis5d_start.jnl, and vis5d_append.jnl. These have the filename first in their argument lists, and do not require the user to specify all 9 arguments to the function.
Example:
Write 3 variables to a file, then append timesteps to some of the variables. There is a gap between the times first written to the file and the times written when we call vis5d_append; this will show up in the Vis5d tool as a gap in time. Last, start Vis5d and open the file.
Yes? SET REGION/I=55:180/J=30:60
yes? GO vis5d_write myfile.v5d sst[L=20:30],
airt[L=20:30], fcn_1
yes? GO vis5d_append myfile.v5d sst[l=34,50],
airt[l=34,50]
yes? GO vis5d_start myfile.v5d