Commit 7fbd6c8d01a3d2a2833fc36a219749c18b2c40c5

Authored by Annie Hughes
1 parent 86f1665a
Exists in master

added IDL lib files that may become obsolete or retired in future IDL releases

src/idl_special/int_tabulated.pro 0 → 100644
@@ -0,0 +1,171 @@ @@ -0,0 +1,171 @@
  1 +; $Id: //depot/Release/ENVI52_IDL84/idl/idldir/lib/int_tabulated.pro#1 $
  2 +;
  3 +; Copyright (c) 1995-2014, Exelis Visual Information Solutions, Inc. All
  4 +; rights reserved. Unauthorized reproduction is prohibited.
  5 +;+
  6 +; NAME:
  7 +; INT_TABULATED
  8 +;
  9 +; PURPOSE:
  10 +; This function integrates a tabulated set of data { x(i) , f(i) },
  11 +; on the closed interval [min(X) , max(X)].
  12 +;
  13 +; CATEGORY:
  14 +; Numerical Analysis.
  15 +;
  16 +; CALLING SEQUENCE:
  17 +; Result = INT_TABULATED(X, F)
  18 +;
  19 +; INPUTS:
  20 +; X: The tabulated X-value data. This data may be irregularly
  21 +; gridded and in random order. If the data is randomly ordered
  22 +; you must set the SORT keyword to a nonzero value.
  23 +; Duplicate x values will result in a warning message.
  24 +; F: The tabulated F-value data. Upon input to the function
  25 +; X(i) and F(i) must have corresponding indices for all
  26 +; values of i. If X is reordered, F is also reordered.
  27 +;
  28 +; X and F must be of floating point or double precision type.
  29 +;
  30 +; KEYWORD PARAMETERS:
  31 +; SORT: A zero or non-zero scalar value.
  32 +; SORT = 0 (the default) The tabulated x-value data is
  33 +; already in ascending order.
  34 +; SORT = 1 The tabulated x-value data is in random order
  35 +; and requires sorting into ascending order. Both
  36 +; input parameters X and F are returned sorted.
  37 +; DOUBLE: If set to a non-zero value, computations are done in
  38 +; double precision arithmetic.
  39 +;
  40 +; OUTPUTS:
  41 +; This fuction returns the integral of F computed from the tabulated
  42 +; data in the closed interval [min(X) , max(X)].
  43 +;
  44 +; RESTRICTIONS:
  45 +; Data that is highly oscillatory requires a sufficient number
  46 +; of samples for an accurate integral approximation.
  47 +;
  48 +; PROCEDURE:
  49 +; INT_TABULATED.PRO constructs a regularly gridded x-axis with a
  50 +; number of segments as an integer multiple of four. Segments
  51 +; are processed in groups of four using a 5-point Newton-Cotes
  52 +; integration formula.
  53 +; For 'sufficiently sampled' data, this algorithm is highly accurate.
  54 +;
  55 +; EXAMPLES:
  56 +; Example 1:
  57 +; Define 11 x-values on the closed interval [0.0 , 0.8].
  58 +; x = [0.0, .12, .22, .32, .36, .40, .44, .54, .64, .70, .80]
  59 +;
  60 +; Define 11 f-values corresponding to x(i).
  61 +; f = [0.200000, 1.30973, 1.30524, 1.74339, 2.07490, 2.45600, $
  62 +; 2.84299, 3.50730, 3.18194, 2.36302, 0.231964]
  63 +;
  64 +; Compute the integral.
  65 +; result = INT_TABULATED(x, f)
  66 +;
  67 +; In this example, the f-values are generated from a known function,
  68 +; (f = .2 + 25*x - 200*x^2 + 675*x^3 - 900*x^4 + 400*x^5)
  69 +;
  70 +; The Multiple Application Trapazoid Method yields; result = 1.5648
  71 +; The Multiple Application Simpson's Method yields; result = 1.6036
  72 +; INT_TABULATED.PRO yields; result = 1.6232
  73 +; The Exact Solution (4 decimal accuracy) yields; result = 1.6405
  74 +;
  75 +; Example 2:
  76 +; Create 30 random points in the closed interval [-2 , 1].
  77 +; x = randomu(seed, 30) * 3.0 - 2.0
  78 +;
  79 +; Explicitly define the interval's endpoints.
  80 +; x(0) = -2.0 & x(29) = 1.0
  81 +;
  82 +; Generate f(i) corresponding to x(i) from a given function.
  83 +; f = sin(2*x) * exp(cos(2*x))
  84 +;
  85 +; Call INT_TABULATED with the SORT keyword.
  86 +; result = INT_TABULATED(x, f, /sort)
  87 +;
  88 +; In this example, the f-values are generated from the function,
  89 +; f = sin(2*x) * exp(cos(2*x))
  90 +;
  91 +; The result of this example will vary because the x(i) are random.
  92 +; Executing this example three times gave the following results:
  93 +; INT_TABULATED.PRO yields; result = -0.0702
  94 +; INT_TABULATED.PRO yields; result = -0.0731
  95 +; INT_TABULATED.PRO yields; result = -0.0698
  96 +; The Exact Solution (4 decimal accuracy) yields; result = -0.0697
  97 +;
  98 +; MODIFICATION HISTORY:
  99 +; Written by: GGS, RSI, September 1993
  100 +; Modified: GGS, RSI, November 1993
  101 +; Use Numerical Recipes cubic spline interpolation
  102 +; function NR_SPLINE/NR_SPLINT. Execution time is
  103 +; greatly reduced. Added DOUBLE keyword. The 'sigma'
  104 +; keyword is no longer supported.
  105 +; Modified: GGS, RSI, April 1995
  106 +; Changed cubic spline calls from NR_SPLINE/NR_SPLINT
  107 +; to SPL_INIT/SPL_INTERP. Improved double-precision
  108 +; accuracy.
  109 +; Modified: GGS, RSI, April 1996
  110 +; Replaced WHILE loop with vector operations.
  111 +; Check for duplicate points in x vector.
  112 +; Modified keyword checking and use of double precision.
  113 +;-
  114 +
  115 +FUNCTION Int_Tabulated, X, F, Double = Double, Sort = Sort
  116 +
  117 + ;Return to caller if an error occurs.
  118 + ON_ERROR, 2
  119 +
  120 + TypeX = SIZE(X)
  121 + TypeF = SIZE(F)
  122 +
  123 + ;Check F data type.
  124 + if TypeF[TypeF[0]+1] ne 4 and TypeF[TypeF[0]+1] ne 5 then $
  125 + MESSAGE, "F values must be float or double."
  126 +
  127 + ;Check length.
  128 + if TypeX[TypeX[0]+2] ne TypeF[TypeF[0]+2] then $
  129 + MESSAGE, "X and F arrays must have the same number of elements."
  130 +
  131 + ;Check duplicate values.
  132 + if TypeX[TypeX[0]+2] ne N_ELEMENTS(UNIQ(X[SORT(X)])) then $
  133 + MESSAGE, "X array contains duplicate points."
  134 +
  135 + ;If the DOUBLE keyword is not set then the internal precision and
  136 + ;result are identical to the type of input.
  137 + if N_ELEMENTS(Double) eq 0 then $
  138 + Double = (TypeX[TypeX[0]+1] eq 5 or TypeF[TypeF[0]+1] eq 5)
  139 +
  140 + Xsegments = TypeX[TypeX[0]+2] - 1L
  141 +
  142 + ;Sort vectors into ascending order.
  143 + if KEYWORD_SET(Sort) ne 0 then begin
  144 + ii = SORT(x)
  145 + X = X[ii]
  146 + F = F[ii]
  147 + endif
  148 +
  149 + while (Xsegments MOD 4L) ne 0L do $
  150 + Xsegments = Xsegments + 1L
  151 +
  152 + Xmin = MIN(X)
  153 + Xmax = MAX(X)
  154 +
  155 + ;Uniform step size.
  156 + h = (Xmax+0.0 - Xmin) / Xsegments
  157 + ;Compute the interpolates at Xgrid.
  158 + ;x values of interpolates >> Xgrid = h * FINDGEN(Xsegments + 1L) + Xmin
  159 + z = SPL_INTERP(X, F, SPL_INIT(X, F, Double = Double), $
  160 + h * FINDGEN(Xsegments + 1L) + Xmin, Double = Double)
  161 + ;Compute the integral using the 5-point Newton-Cotes formula.
  162 + ii = (LINDGEN((N_ELEMENTS(z) - 1L)/4L)+1) * 4
  163 + if Double eq 0 then $
  164 + RETURN, FLOAT(TOTAL(2.0 * h * (7.0 * (z[ii-4] + z[ii]) + $
  165 + 32.0 * (z[ii-3] + z[ii-1]) + 12.0 * z[ii-2]) / 45.0)) $
  166 + else $
  167 + RETURN, TOTAL(2D * h * (7D * (z[ii-4] + z[ii]) + $
  168 + 32D * (z[ii-3] + z[ii-1]) + 12D * z[ii-2]) / 45D, /DOUBLE)
  169 +
  170 +END
  171 +
src/idl_special/interpol.pro 0 → 100644
@@ -0,0 +1,265 @@ @@ -0,0 +1,265 @@
  1 +; $Id: //depot/Release/ENVI52_IDL84/idl/idldir/lib/interpol.pro#1 $
  2 +;
  3 +; Copyright (c) 1982-2014, Exelis Visual Information Solutions, Inc. All
  4 +; rights reserved. Unauthorized reproduction is prohibited.
  5 +
  6 +Function ls2fit, xx, y, xm
  7 +
  8 +COMPILE_OPT idl2, hidden
  9 +
  10 +x = xx - xx[0] ;Normalize to preserve significance.
  11 +ndegree = 2L
  12 +n = n_elements(xx)
  13 +
  14 +corrm = fltarr(ndegree+1, ndegree+1) ;Correlation matrix
  15 +b = fltarr(ndegree+1)
  16 +
  17 +corrm[0,0] = n ;0 - Form the normal equations
  18 +b[0] = total(y)
  19 +z = x ;1
  20 +b[1] = total(y*z)
  21 +corrm[[0,1],[1,0]] = total(z)
  22 +z = z * x ;2
  23 +b[2] = total(y*z)
  24 +corrm[[0,1,2], [2,1,0]] = total(z)
  25 +z = z * x ;3
  26 +corrm[[1,2],[2,1]] = total(z)
  27 +corrm[2,2] = total(z*x) ;4
  28 +
  29 +c = b # invert(corrm)
  30 +xm0 = xm - xx[0]
  31 +return, c[0] + c[1] * xm0 + c[2] * xm0^2
  32 +end
  33 +
  34 +
  35 +
  36 +;+
  37 +; NAME:
  38 +; INTERPOL
  39 +;
  40 +; PURPOSE:
  41 +; Linearly interpolate vectors with a regular or irregular grid.
  42 +; Quadratic or a 4 point least-square fit to a quadratic
  43 +; interpolation may be used as an option.
  44 +;
  45 +; CATEGORY:
  46 +; E1 - Interpolation
  47 +;
  48 +; CALLING SEQUENCE:
  49 +; Result = INTERPOL(V, N) ;For regular grids.
  50 +;
  51 +; Result = INTERPOL(V, X, XOUT) ;For irregular grids.
  52 +;
  53 +; INPUTS:
  54 +; V: The input vector can be any type except string.
  55 +;
  56 +; For regular grids:
  57 +; N: The number of points in the result when both input and
  58 +; output grids are regular.
  59 +;
  60 +; Irregular grids:
  61 +; X: The absicissae values for V. This vector must have same # of
  62 +; elements as V. The values MUST be monotonically ascending
  63 +; or descending.
  64 +;
  65 +; XOUT: The absicissae values for the result. The result will have
  66 +; the same number of elements as XOUT. XOUT does not need to be
  67 +; monotonic. If XOUT is outside the range of X, then the
  68 +; closest two endpoints of (X,V) are linearly extrapolated.
  69 +;
  70 +; Keyword Input Parameters:
  71 +; NAN = if set, then filter out NaN values before interpolating.
  72 +; The default behavior is to include the NaN values - by including NaN's
  73 +; the output will contain NaN's in locations where the interpolation
  74 +; result is undefined.
  75 +;
  76 +; LSQUADRATIC = if set, interpolate using a least squares
  77 +; quadratic fit to the equation y = a + bx + cx^2, for each 4
  78 +; point neighborhood (x[i-1], x[i], x[i+1], x[i+2]) surrounding
  79 +; the interval, x[i] <= XOUT < x[i+1].
  80 +;
  81 +; QUADRATIC = if set, interpolate by fitting a quadratic
  82 +; y = a + bx + cx^2, to the three point neighborhood (x[i-1],
  83 +; x[i], x[i+1]) surrounding the interval x[i] <= XOUT < x[i+1].
  84 +;
  85 +; SPLINE = if set, interpolate by fitting a cubic spline to the
  86 +; 4 point neighborhood (x[i-1], x[i], x[i+1], x[i+2]) surrounding
  87 +; the interval, x[i] <= XOUT < x[i+1].
  88 +;
  89 +; Note: if LSQUADRATIC or QUADRATIC or SPLINE is not set, the
  90 +; default linear interpolation is used.
  91 +;
  92 +; OUTPUTS:
  93 +; INTERPOL returns a floating-point vector of N points determined
  94 +; by interpolating the input vector by the specified method.
  95 +;
  96 +; If the input vector is double or complex, the result is double
  97 +; or complex.
  98 +;
  99 +; COMMON BLOCKS:
  100 +; None.
  101 +;
  102 +; SIDE EFFECTS:
  103 +; None.
  104 +;
  105 +; RESTRICTIONS:
  106 +; None.
  107 +;
  108 +; PROCEDURE:
  109 +; For linear interpolation,
  110 +; Result(i) = V(x) + (x - FIX(x)) * (V(x+1) - V(x))
  111 +;
  112 +; where x = i*(m-1)/(N-1) for regular grids.
  113 +; m = # of elements in V, i=0 to N-1.
  114 +;
  115 +; For irregular grids, x = XOUT(i).
  116 +; m = number of points of input vector.
  117 +;
  118 +; For QUADRATIC interpolation, the equation y=a+bx+cx^2 is
  119 +; solved explicitly for each three point interval, and is then
  120 +; evaluated at the interpolate.
  121 +; For LSQUADRATIC interpolation, the coefficients a, b, and c,
  122 +; from the above equation are found, for the four point
  123 +; interval surrounding the interpolate using a least square
  124 +; fit. Then the equation is evaluated at the interpolate.
  125 +; For SPLINE interpolation, a cubic spline is fit over the 4
  126 +; point interval surrounding each interpolate, using the routine
  127 +; SPL_INTERP().
  128 +;
  129 +; MODIFICATION HISTORY:
  130 +; Written, DMS, October, 1982.
  131 +; Modified, Rob at NCAR, February, 1991. Made larger arrays possible
  132 +; and correct by using long indexes into the array instead of
  133 +; integers.
  134 +; Modified, DMS, August, 1998. Now use binary intervals which
  135 +; speed things up considerably when XOUT is random.
  136 +; DMS, May, 1999. Use new VALUE_LOCATE function to find intervals,
  137 +; which speeds things up by a factor of around 100, when
  138 +; interpolating from large arrays. Also added SPLINE,
  139 +; QUADRATIC, and LSQUADRATIC keywords.
  140 +; CT, VIS, Feb 2009: CR54942: Automatically filter out NaN values.
  141 +; Clean up code.
  142 +; CT, VIS, Feb 2010: CR57403: Back out previous change.
  143 +; Add NAN keyword to control filtering out of NaN's
  144 +;-
  145 +;
  146 +FUNCTION INTERPOL, VV, XX, XOUT, $
  147 + SPLINE=spline, LSQUADRATIC=ls2, QUADRATIC=quad, NAN=nan
  148 +
  149 + COMPILE_OPT idl2
  150 +
  151 + on_error,2 ;Return to caller if an error occurs
  152 +
  153 + regular = n_params(0) eq 2
  154 +
  155 + ; Make a copy so we don't overwrite the input arguments.
  156 + v = vv
  157 + x = xx
  158 + m = N_elements(v) ;# of input pnts
  159 +
  160 + if (regular) then nOut = LONG(x)
  161 +
  162 + ; Filter out NaN values in both the V and X arguments.
  163 + if (KEYWORD_SET(nan)) then begin
  164 + isNAN = FINITE(v, /NAN)
  165 + if (~regular) then isNAN or= FINITE(x, /NAN)
  166 +
  167 + if (~ARRAY_EQUAL(isNAN, 0)) then begin
  168 + good = WHERE(~isNAN, ngood)
  169 + if (ngood gt 0 && ngood lt m) then begin
  170 + v = v[good]
  171 + if (regular) then begin
  172 + ; We supposedly had a regular grid, but some of the values
  173 + ; were NaN (missing). So construct the irregular grid.
  174 + regular = 0b
  175 + x = LINDGEN(m)
  176 + xout = FINDGEN(nOut) * ((m-1.0) / ((nOut-1.0) > 1.0)) ;Grid points
  177 + endif
  178 + x = x[good]
  179 + endif
  180 + endif
  181 + endif
  182 +
  183 + ; get the number of input points again, in case some NaN's got filtered
  184 + m = N_elements(v)
  185 + type = SIZE(v, /TYPE)
  186 +
  187 + if regular && $ ;Simple regular case?
  188 + ((keyword_set(ls2) || keyword_set(quad) || keyword_set(spline)) eq 0) $
  189 + then begin
  190 + xout = findgen(nOut)*((m-1.0)/((nOut-1.0) > 1.0)) ;Grid points in V
  191 + xoutInt = long(xout) ;Cvt to integer
  192 + case (type) of
  193 + 1: diff = v[1:*] - FIX(v)
  194 + 12: diff = v[1:*] - LONG(v)
  195 + 13: diff = v[1:*] - LONG64(v)
  196 + 15: diff = LONG64(v[1:*]) - LONG64(v)
  197 + else: diff = v[1:*] - v
  198 + endcase
  199 + return, V[xoutInt] + (xout-xoutInt)*diff[xoutInt] ;interpolate
  200 + endif
  201 +
  202 + if regular then begin ;Regular intervals??
  203 + xout = findgen(nOut) * ((m-1.0) / ((nOut-1.0) > 1.0)) ;Grid points
  204 + s = long(xout) ;Subscripts
  205 + endif else begin ;Irregular
  206 + if n_elements(x) ne m then $
  207 + message, 'V and X arrays must have same # of elements'
  208 + s = VALUE_LOCATE(x, xout) > 0L < (m-2) ;Subscript intervals.
  209 + endelse
  210 +
  211 + ; Clip interval, which forces extrapolation.
  212 + ; XOUT[i] is between x[s[i]] and x[s[i]+1].
  213 +
  214 + CASE (1) OF
  215 +
  216 + KEYWORD_SET(ls2): BEGIN ;Least square fit quadratic, 4 points
  217 + s = s > 1L < (m-3) ;Make in range.
  218 + p = replicate(v[0]*1.0, n_elements(s)) ;Result
  219 + for i=0L, n_elements(s)-1 do begin
  220 + s0 = s[i]-1
  221 + p[i] = ls2fit(regular ? s0+findgen(4) : x[s0:s0+3], v[s0:s0+3], xout[i])
  222 + endfor
  223 + END
  224 +
  225 + KEYWORD_SET(quad): BEGIN ;Quadratic.
  226 + s = s > 1L < (m-2) ;In range
  227 + x1 = regular ? float(s) : x[s]
  228 + x0 = regular ? x1-1.0 : x[s-1]
  229 + x2 = regular ? x1+1.0 : x[s+1]
  230 + p = v[s-1] * (xout-x1) * (xout-x2) / ((x0-x1) * (x0-x2)) + $
  231 + v[s] * (xout-x0) * (xout-x2) / ((x1-x0) * (x1-x2)) + $
  232 + v[s+1] * (xout-x0) * (xout-x1) / ((x2-x0) * (x2-x1))
  233 + END
  234 +
  235 + KEYWORD_SET(spline): BEGIN
  236 + s = s > 1L < (m-3) ;Make in range.
  237 + p = replicate(v[0], n_elements(s)) ;Result
  238 + sold = -1
  239 + for i=0L, n_elements(s)-1 do begin
  240 + s0 = s[i]-1
  241 + if sold ne s0 then begin
  242 + x0 = regular ? s0+findgen(4): x[s0: s0+3]
  243 + v0 = v[s0: s0+3]
  244 + q = spl_init(x0, v0)
  245 + sold = s0
  246 + endif
  247 + p[i] = spl_interp(x0, v0, q, xout[i])
  248 + endfor
  249 + END
  250 +
  251 + ELSE: begin ;Linear, not regular
  252 + case (type) of
  253 + 1: diff = v[s+1] - FIX(v[s])
  254 + 12: diff = v[s+1] - LONG(v[s])
  255 + 13: diff = v[s+1] - LONG64(v[s])
  256 + 15: diff = LONG64(v[s+1]) - LONG64(v[s])
  257 + else: diff = v[s+1] - v[s]
  258 + endcase
  259 + p = (xout-x[s])*diff/(x[s+1] - x[s]) + v[s]
  260 + end
  261 +
  262 + ENDCASE
  263 +
  264 + RETURN, p
  265 +end
src/idl_special/str_sep.pro 0 → 100644
@@ -0,0 +1,116 @@ @@ -0,0 +1,116 @@
  1 +; $Id: //depot/Release/ENVI52_IDL84/idl/idldir/lib/obsolete/str_sep.pro#1 $
  2 +;
  3 +; Copyright (c) 1992-2014, Exelis Visual Information Solutions, Inc and
  4 +; CreaSo Creative Software Systems GmbH.
  5 +; All rights reserved. Unauthorized reproduction prohibited.
  6 +;+
  7 +; NAME:
  8 +; STR_SEP
  9 +;
  10 +; PURPOSE:
  11 +; This routine cuts a string into pieces which are separated by the
  12 +; separator string.
  13 +; CATEGORY:
  14 +; String processing.
  15 +; CALLING SEQUENCE:
  16 +; arr = STR_SEP(str, separator)
  17 +;
  18 +; INPUTS:
  19 +; str - The string to be separated.
  20 +; separator - The separator.
  21 +;
  22 +; KEYWORDS:
  23 +; ESC = escape character. Only valid if separator is a single character.
  24 +; Characters following the escape character are treated
  25 +; literally and not interpreted as separators.
  26 +; For example, if the separator is a comma,
  27 +; and the escape character is a backslash, the character
  28 +; sequence 'a\,b' is a single field containing the characters
  29 +; 'a,b'.
  30 +; REMOVE_ALL = if set, remove all blanks from fields.
  31 +; TRIM = if set, remove only leading and trailing blanks from fields.
  32 +;
  33 +; OUTPUT:
  34 +; An array of strings as function value.
  35 +;
  36 +; COMMON BLOCKS:
  37 +; None
  38 +;
  39 +; SIDE EFFECTS:
  40 +; No known side effects.
  41 +;
  42 +; RESTRICTIONS:
  43 +; None.
  44 +;
  45 +; EXAMPLE:
  46 +; array = STR_SEP ("ulib.usca.test", ".")
  47 +;
  48 +; MODIFICATION HISTORY:
  49 +; July 1992, AH, CreaSo Created.
  50 +; December, 1994, DMS, RSI Added TRIM and REMOVE_ALL.
  51 +;-
  52 +function STR_SEP, str, separator, REMOVE_ALL = remove_all, TRIM = trim, ESC=esc
  53 +
  54 +
  55 +ON_ERROR, 2
  56 +if n_params() ne 2 then message,'Wrong number of arguments.'
  57 +
  58 +spos = 0L
  59 +if n_elements(esc) gt 0 then begin ;Check for escape character?
  60 + if strpos(str, esc) lt 0 then goto, no_esc ;None in string, use fast case
  61 + besc = (byte(esc))[0]
  62 + bsep = (byte(separator))[0]
  63 + new = bytarr(strlen(str)+1)
  64 + new[0] = byte(str)
  65 + j = 0L
  66 + for i=0L, n_elements(new)-2 do begin
  67 + if new[i] eq besc then begin
  68 + new[j] = new[i+1]
  69 + i = i + 1
  70 + endif else if new[i] eq bsep then new[j] = 1b $ ;Change seps to 1b char
  71 + else new[j] = new[i]
  72 + j = j + 1
  73 + endfor
  74 + new = string(new[0:j-1])
  75 + w = where(byte(new) eq 1b, count) ;where seps are...
  76 + arr = strarr(count+1)
  77 + for i=0L, count-1 do begin
  78 + arr[i] = strmid(new, spos, w[i]-spos)
  79 + spos = w[i] + 1
  80 + endfor
  81 + arr[count] = strmid(new, spos, strlen(str)) ;Last element
  82 + goto, done
  83 + endif ;esc
  84 +
  85 +no_esc:
  86 +if strlen(separator) le 1 then begin ;Single character separator?
  87 + w = where(byte(str) eq (byte(separator))[0], count) ;where seps are...
  88 + arr = strarr(count+1)
  89 + for i=0, count-1 do begin
  90 + arr[i] = strmid(str, spos, w[i]-spos)
  91 + spos = w[i] + 1
  92 + endfor
  93 + arr[count] = strmid(str, spos, strlen(str)) ;Last element
  94 +endif else begin ;Multi character separator....
  95 + n = 0L ; Determine number of seperators in string.
  96 + repeat begin
  97 + pos = strpos (str, separator, spos)
  98 + spos = pos + strlen(separator)
  99 + n = n+1
  100 + endrep until pos eq -1
  101 +
  102 + arr = strarr(n) ; Create result array
  103 + spos = 0L
  104 + for i=0L, n-1 do begin ; Separate substrings
  105 + pos = strpos (str, separator, spos)
  106 + if pos ge 0 then arr[i] = strmid (str, spos, pos-spos) $
  107 + else arr[i] = strmid(str, spos, strlen(str))
  108 + spos = pos+strlen(separator)
  109 + endfor
  110 +endelse
  111 +
  112 +done:
  113 +if keyword_set(trim) then arr = strtrim(arr,2) $
  114 +else if keyword_set(remove_all) then arr = strcompress(arr, /REMOVE_ALL)
  115 +return, arr
  116 +end