Commit 7fbd6c8d01a3d2a2833fc36a219749c18b2c40c5
1 parent
86f1665a
Exists in
master
added IDL lib files that may become obsolete or retired in future IDL releases
Showing
3 changed files
with
552 additions
and
0 deletions
Show diff stats
... | ... | @@ -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 | + | ... | ... |
... | ... | @@ -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 | ... | ... |
... | ... | @@ -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 | ... | ... |