1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4 ! This module provides routines for interpolation.
5 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
9 use misc_definitions_module
15 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16 ! Name: interp_array_from_string
19 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
20 function interp_array_from_string(interp_string)
25 character (len=*), intent(in) :: interp_string
28 integer :: j, p1, p2, iend, num_methods
31 integer, pointer, dimension(:) :: interp_array_from_string
33 ! Get an idea of how many interpolation methods are in the string
34 ! so we can allocate an appropriately sized array
36 do j=1,len_trim(interp_string)
37 if (interp_string(j:j) == '+') num_methods = num_methods + 1
40 allocate(interp_array_from_string(num_methods+1))
41 interp_array_from_string = 0
43 iend = len_trim(interp_string)
46 p2 = index(interp_string(1:iend),'+')
49 if (index(interp_string(p1:p2-1),'nearest_neighbor') /= 0 .and. &
50 len_trim(interp_string(p1:p2-1)) == len_trim('nearest_neighbor')) then
51 interp_array_from_string(j) = N_NEIGHBOR
53 else if (index(interp_string(p1:p2-1),'average_4pt') /= 0 .and. &
54 len_trim(interp_string(p1:p2-1)) == len_trim('average_4pt')) then
55 interp_array_from_string(j) = AVERAGE4
57 else if (index(interp_string(p1:p2-1),'average_16pt') /= 0 .and. &
58 len_trim(interp_string(p1:p2-1)) == len_trim('average_16pt')) then
59 interp_array_from_string(j) = AVERAGE16
61 else if (index(interp_string(p1:p2-1),'wt_average_4pt') /= 0 .and. &
62 len_trim(interp_string(p1:p2-1)) == len_trim('wt_average_4pt')) then
63 interp_array_from_string(j) = W_AVERAGE4
65 else if (index(interp_string(p1:p2-1),'wt_average_16pt') /= 0 .and. &
66 len_trim(interp_string(p1:p2-1)) == len_trim('wt_average_16pt')) then
67 interp_array_from_string(j) = W_AVERAGE16
69 else if (index(interp_string(p1:p2-1),'four_pt') /= 0 .and. &
70 len_trim(interp_string(p1:p2-1)) == len_trim('four_pt')) then
71 interp_array_from_string(j) = FOUR_POINT
73 else if (index(interp_string(p1:p2-1),'sixteen_pt') /= 0 .and. &
74 len_trim(interp_string(p1:p2-1)) == len_trim('sixteen_pt')) then
75 interp_array_from_string(j) = SIXTEEN_POINT
77 else if (index(interp_string(p1:p2-1),'search') /= 0 .and. &
78 len_trim(interp_string(p1:p2-1)) == len_trim('search')) then
79 interp_array_from_string(j) = SEARCH
82 if (index(interp_string(p1:p2-1),'average_gcell') == 0) &
83 call mprintf(.true.,WARN,'Unrecognized interpolation method %s.',s1=interp_string(p1:p2-1))
86 p2 = index(interp_string(p1:iend),'+') + p1 - 1
91 if (index(interp_string(p1:p2-1),'nearest_neighbor') /= 0 .and. &
92 len_trim(interp_string(p1:p2-1)) == len_trim('nearest_neighbor')) then
93 interp_array_from_string(j) = N_NEIGHBOR
95 else if (index(interp_string(p1:p2-1),'average_4pt') /= 0 .and. &
96 len_trim(interp_string(p1:p2-1)) == len_trim('average_4pt')) then
97 interp_array_from_string(j) = AVERAGE4
99 else if (index(interp_string(p1:p2-1),'average_16pt') /= 0 .and. &
100 len_trim(interp_string(p1:p2-1)) == len_trim('average_16pt')) then
101 interp_array_from_string(j) = AVERAGE16
103 else if (index(interp_string(p1:p2-1),'wt_average_4pt') /= 0 .and. &
104 len_trim(interp_string(p1:p2-1)) == len_trim('wt_average_4pt')) then
105 interp_array_from_string(j) = W_AVERAGE4
107 else if (index(interp_string(p1:p2-1),'wt_average_16pt') /= 0 .and. &
108 len_trim(interp_string(p1:p2-1)) == len_trim('wt_average_16pt')) then
109 interp_array_from_string(j) = W_AVERAGE16
111 else if (index(interp_string(p1:p2-1),'four_pt') /= 0 .and. &
112 len_trim(interp_string(p1:p2-1)) == len_trim('four_pt')) then
113 interp_array_from_string(j) = FOUR_POINT
115 else if (index(interp_string(p1:p2-1),'sixteen_pt') /= 0 .and. &
116 len_trim(interp_string(p1:p2-1)) == len_trim('sixteen_pt')) then
117 interp_array_from_string(j) = SIXTEEN_POINT
119 else if (index(interp_string(p1:p2-1),'search') /= 0 .and. &
120 len_trim(interp_string(p1:p2-1)) == len_trim('search')) then
121 interp_array_from_string(j) = SEARCH
124 if (index(interp_string(p1:p2-1),'average_gcell') == 0) &
125 call mprintf(.true.,WARN,'Unrecognized interpolation method %s.',s1=interp_string(p1:p2-1))
131 end function interp_array_from_string
134 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
135 ! Name: interp_sequence
137 ! Purpose: Delegates the actual task of interpolation to specific
138 ! interpolation routines defined in the module.
139 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
140 recursive function interp_sequence(xx, yy, izz, array, start_x, end_x, &
141 start_y, end_y, start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
146 integer, intent(in) :: start_x, start_y, start_z
147 integer, intent(in) :: end_x, end_y, end_z
148 integer, intent(in) :: izz ! The z-index of the 2d-array to
150 real, intent(in) :: xx , yy ! The location to interpolate to
151 real, intent(in) :: msgval
152 real, intent(in), optional :: maskval
153 real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), intent(in) :: array
154 integer, intent(in) :: idx
155 integer, dimension(:), intent(in) :: interp_list
156 real, dimension(start_x:end_x, start_y:end_y), intent(in), optional :: mask_array
157 character (len=1), intent(in), optional :: mask_relational
160 real :: interp_sequence
162 ! No more interpolation methods to try
163 if (interp_list(idx) == 0) then
164 interp_sequence = msgval
168 if (interp_list(idx) == FOUR_POINT) then
169 interp_sequence = four_pt(xx, yy, izz, array, start_x, end_x, &
170 start_y, end_y, start_z, end_z, &
171 msgval, interp_list, idx+1, mask_relational, maskval, mask_array)
172 else if (interp_list(idx) == AVERAGE4) then
173 interp_sequence = four_pt_average(xx, yy, izz, array, start_x, end_x, &
174 start_y, end_y, start_z, end_z, &
175 msgval, interp_list, idx+1, mask_relational, maskval, mask_array)
176 else if (interp_list(idx) == W_AVERAGE4) then
177 interp_sequence = wt_four_pt_average(xx, yy, izz, array, start_x, end_x, &
178 start_y, end_y, start_z, end_z, &
179 msgval, interp_list, idx+1, mask_relational, maskval, mask_array)
180 else if (interp_list(idx) == N_NEIGHBOR) then
181 interp_sequence = nearest_neighbor(xx, yy, izz, array, start_x, end_x, &
182 start_y, end_y, start_z, end_z, &
183 msgval, interp_list, idx+1, mask_relational, maskval, mask_array)
184 else if (interp_list(idx) == SIXTEEN_POINT) then
185 interp_sequence = sixteen_pt(xx, yy, izz, array, start_x, end_x, &
186 start_y, end_y, start_z, end_z, &
187 msgval, interp_list, idx+1, mask_relational, maskval, mask_array)
188 else if (interp_list(idx) == SEARCH) then
189 interp_sequence = search_extrap(xx, yy, izz, array, start_x, end_x, &
190 start_y, end_y, start_z, end_z, &
191 msgval, interp_list, idx+1, mask_relational, maskval, mask_array)
192 else if (interp_list(idx) == AVERAGE16) then
193 interp_sequence = sixteen_pt_average(xx, yy, izz, array, start_x, end_x, &
194 start_y, end_y, start_z, end_z, &
195 msgval, interp_list, idx+1, mask_relational, maskval, mask_array)
196 else if (interp_list(idx) == W_AVERAGE16) then
197 interp_sequence = wt_sixteen_pt_average(xx, yy, izz, array, start_x, end_x, &
198 start_y, end_y, start_z, end_z, &
199 msgval, interp_list, idx+1, mask_relational, maskval, mask_array)
202 end function interp_sequence
205 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
206 ! Name: nearest_neighbor
208 ! Purpose: Returns the point nearest to (xx,yy). If (xx,yy) is outside of the
209 ! array, the point on the edge of the array nearest to (xx,yy) is returned.
210 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
211 recursive function nearest_neighbor(xx, yy, izz, array, start_x, end_x, &
212 start_y, end_y, start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
217 integer, intent(in) :: start_x, start_y, start_z
218 integer, intent(in) :: end_x, end_y, end_z
219 integer, intent(in) :: izz ! The z-index of the 2d-array to
221 real, intent(in) :: xx , yy ! The location to interpolate to
222 real, intent(in) :: msgval
223 real, intent(in), optional :: maskval
224 real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), intent(in) :: array
225 integer, dimension(:), intent(in) :: interp_list
226 integer, intent(in) :: idx
227 real, dimension(start_x:end_x, start_y:end_y), intent(in), optional :: mask_array
228 character (len=1), intent(in), optional :: mask_relational
231 real :: nearest_neighbor
239 ! The first thing to do is to ensure that the point (xx,yy) is within the array
240 if (ix < start_x .or. ix > end_x) then
241 nearest_neighbor = msgval
245 if (iy < start_y .or. iy > end_y) then
246 nearest_neighbor = msgval
250 if (present(mask_array) .and. present(maskval) .and. present(mask_relational)) then
251 if (mask_relational == '<' .and. mask_array(ix,iy) < maskval) then
252 nearest_neighbor = msgval
253 else if (mask_relational == '>' .and. mask_array(ix,iy) > maskval) then
254 nearest_neighbor = msgval
255 else if (mask_relational == ' ' .and. mask_array(ix,iy) == maskval) then
256 nearest_neighbor = msgval
258 nearest_neighbor = array(ix,iy,izz)
260 else if (present(mask_array) .and. present(maskval)) then
261 if (maskval == mask_array(ix,iy)) then
262 nearest_neighbor = msgval
264 nearest_neighbor = array(ix,iy,izz)
267 nearest_neighbor = array(ix,iy,izz)
270 ! If we have a missing value, try the next interpolation method in the sequence
271 if (nearest_neighbor == msgval) then
272 nearest_neighbor = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
273 start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
276 end function nearest_neighbor
279 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
280 ! Name: search_extrap
282 ! Purpose: Returns the point nearest to (xx,yy) that has a non-missing value.
283 ! If no valid value can be found in the array, msgval is returned.
284 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
285 recursive function search_extrap(xx, yy, izz, array, start_x, end_x, &
286 start_y, end_y, start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
291 integer, intent(in) :: start_x, start_y, start_z
292 integer, intent(in) :: end_x, end_y, end_z
293 integer, intent(in) :: izz ! The z-index of the 2d-array to search
294 real, intent(in) :: xx , yy ! The location of the search origin
295 real, intent(in) :: msgval
296 real, intent(in), optional :: maskval
297 real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), &
299 integer, dimension(:), intent(in) :: interp_list
300 integer, intent(in) :: idx
301 real, dimension(start_x:end_x, start_y:end_y), &
302 intent(in), optional :: mask_array
303 character (len=1), intent(in), optional :: mask_relational
306 real :: search_extrap
311 logical :: found_valid
314 type (q_data) :: qdata
316 ! We only search if the starting point is within the array
317 if (nint(xx) < start_x .or. nint(xx) > end_x .or. &
318 nint(yy) < start_y .or. nint(yy) > end_y) then
319 search_extrap = msgval
323 call bitarray_create(b, (end_x-start_x+1), (end_y-start_y+1))
326 found_valid = .false.
329 call q_insert(q, qdata)
330 call bitarray_set(b, qdata%x-start_x+1, qdata%y-start_y+1)
332 do while (q_isdata(q) .and. (.not. found_valid))
337 if (present(mask_array) .and. present(maskval) .and. present(mask_relational)) then
338 if (mask_relational == '>' .and. mask_array(i,j) <= maskval .and. array(i,j,izz) /= msgval) then
340 else if (mask_relational == '<' .and. mask_array(i,j) >= maskval .and. array(i,j,izz) /= msgval) then
342 else if (mask_relational == ' ' .and. mask_array(i,j) /= maskval .and. array(i,j,izz) /= msgval) then
345 else if (present(mask_array) .and. present(maskval)) then
346 if (array(i,j,izz) /= msgval .and. mask_array(i,j) /= maskval) found_valid = .true.
348 if (array(i,j,izz) /= msgval) found_valid = .true.
351 if (i-1 >= start_x) then
352 if (.not. bitarray_test(b, (i-1)-start_x+1, j-start_y+1)) then
355 call q_insert(q, qdata)
356 call bitarray_set(b, (i-1)-start_x+1, j-start_y+1)
359 if (i+1 <= end_x) then
360 if (.not. bitarray_test(b, (i+1)-start_x+1, j-start_y+1)) then
363 call q_insert(q, qdata)
364 call bitarray_set(b, (i+1)-start_x+1, j-start_y+1)
367 if (j-1 >= start_y) then
368 if (.not. bitarray_test(b, i-start_x+1, (j-1)-start_y+1)) then
371 call q_insert(q, qdata)
372 call bitarray_set(b, i-start_x+1, (j-1)-start_y+1)
375 if (j+1 <= end_y) then
376 if (.not. bitarray_test(b, i-start_x+1, (j+1)-start_y+1)) then
379 call q_insert(q, qdata)
380 call bitarray_set(b, i-start_x+1, (j+1)-start_y+1)
385 if (found_valid) then
386 distance = (real(i)-xx)*(real(i)-xx)+(real(j)-yy)*(real(j)-yy)
387 search_extrap = array(i,j,izz)
388 do while (q_isdata(q))
390 if (present(mask_array) .and. present(maskval) .and. present(mask_relational)) then
391 if (mask_relational == '<' .and. mask_array(qdata%x,qdata%y) >= maskval &
392 .and. array(qdata%x,qdata%y,izz) /= msgval) then
393 if ((real(qdata%x)-xx)*(real(qdata%x)-xx)+(real(qdata%y)-yy)*(real(qdata%y)-yy) < distance) then
394 distance = (real(qdata%x)-xx)*(real(qdata%x)-xx)+(real(qdata%y)-yy)*(real(qdata%y)-yy)
395 search_extrap = array(qdata%x, qdata%y, izz)
397 else if (mask_relational == '>' .and. mask_array(qdata%x,qdata%y) <= maskval &
398 .and. array(qdata%x,qdata%y,izz) /= msgval) then
399 if ((real(qdata%x)-xx)*(real(qdata%x)-xx)+(real(qdata%y)-yy)*(real(qdata%y)-yy) < distance) then
400 distance = (real(qdata%x)-xx)*(real(qdata%x)-xx)+(real(qdata%y)-yy)*(real(qdata%y)-yy)
401 search_extrap = array(qdata%x, qdata%y, izz)
403 else if (mask_relational == ' ' .and. mask_array(qdata%x,qdata%y) /= maskval &
404 .and. array(qdata%x,qdata%y,izz) /= msgval) then
405 if ((real(qdata%x)-xx)*(real(qdata%x)-xx)+(real(qdata%y)-yy)*(real(qdata%y)-yy) < distance) then
406 distance = (real(qdata%x)-xx)*(real(qdata%x)-xx)+(real(qdata%y)-yy)*(real(qdata%y)-yy)
407 search_extrap = array(qdata%x, qdata%y, izz)
411 else if (present(mask_array) .and. present(maskval)) then
412 if (array(qdata%x,qdata%y,izz) /= msgval .and. mask_array(qdata%x,qdata%y) /= maskval) then
413 if ((real(qdata%x)-xx)*(real(qdata%x)-xx)+(real(qdata%y)-yy)*(real(qdata%y)-yy) < distance) then
414 distance = (real(qdata%x)-xx)*(real(qdata%x)-xx)+(real(qdata%y)-yy)*(real(qdata%y)-yy)
415 search_extrap = array(qdata%x, qdata%y, izz)
420 if (array(qdata%x,qdata%y,izz) /= msgval) then
421 if ((real(qdata%x)-xx)*(real(qdata%x)-xx)+(real(qdata%y)-yy)*(real(qdata%y)-yy) < distance) then
422 distance = (real(qdata%x)-xx)*(real(qdata%x)-xx)+(real(qdata%y)-yy)*(real(qdata%y)-yy)
423 search_extrap = array(qdata%x, qdata%y, izz)
429 search_extrap = msgval
433 call bitarray_destroy(b)
435 end function search_extrap
438 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
439 ! Name: four_pt_average
441 ! Purpose: Average of four surrounding grid point values
442 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
443 recursive function four_pt_average(xx, yy, izz, array, start_x, end_x, &
444 start_y, end_y, start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
449 integer, intent(in) :: start_x, start_y, start_z
450 integer, intent(in) :: end_x, end_y, end_z
451 integer, intent(in) :: izz ! The z-index of the 2d-array to
453 real, intent(in) :: xx, yy ! The location to interpolate to
454 real, intent(in) :: msgval
455 real, intent(in), optional :: maskval
456 real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), &
458 integer, dimension(:), intent(in) :: interp_list
459 integer, intent(in) :: idx
460 real, dimension(start_x:end_x, start_y:end_y), &
461 intent(in), optional :: mask_array
462 character (len=1), intent(in), optional :: mask_relational
465 real :: four_pt_average
468 integer :: ifx, ify, icx, icy
469 real :: fxfy, fxcy, cxfy, cxcy
481 ! First, make sure that the point is contained in the source array
482 if (ifx < start_x .or. icx > end_x .or. &
483 ify < start_y .or. icy > end_y) then
485 ! But if the point is at most half a grid point out, we can
486 ! still proceed with modified ifx, icx, ify, and icy.
487 if (xx > real(start_x)-0.5 .and. ifx < start_x) then
490 else if (xx < real(end_x)+0.5 .and. icx > end_x) then
495 if (yy > real(start_y)-0.5 .and. ify < start_y) then
498 else if (yy < real(end_y)+0.5 .and. icy > end_y) then
503 if (ifx < start_x .or. icx > end_x .or. &
504 ify < start_y .or. icy > end_y) then
505 four_pt_average = msgval
510 if (present(mask_array) .and. present(maskval) .and. present(mask_relational)) then
511 ! we determine which maskval is useable by... if the symbol > is found, then only
512 ! values less than 'maskval' can be used and if the symbol < is found,
513 ! then only the values greater than 'maskval' can be used.
514 if (mask_relational == '>') then
515 if (array(ifx, ify, izz) == msgval .or. mask_array(ifx,ify) > maskval) fxfy = 0.0
516 if (array(ifx, icy, izz) == msgval .or. mask_array(ifx,icy) > maskval) fxcy = 0.0
517 if (array(icx, ify, izz) == msgval .or. mask_array(icx,ify) > maskval) cxfy = 0.0
518 if (array(icx, icy, izz) == msgval .or. mask_array(icx,icy) > maskval) cxcy = 0.0
519 else if (mask_relational == '<') then
520 if (array(ifx, ify, izz) == msgval .or. mask_array(ifx,ify) < maskval) fxfy = 0.0
521 if (array(ifx, icy, izz) == msgval .or. mask_array(ifx,icy) < maskval) fxcy = 0.0
522 if (array(icx, ify, izz) == msgval .or. mask_array(icx,ify) < maskval) cxfy = 0.0
523 if (array(icx, icy, izz) == msgval .or. mask_array(icx,icy) < maskval) cxcy = 0.0
525 if (array(ifx, ify, izz) == msgval .or. mask_array(ifx,ify) == maskval) fxfy = 0.0
526 if (array(ifx, icy, izz) == msgval .or. mask_array(ifx,icy) == maskval) fxcy = 0.0
527 if (array(icx, ify, izz) == msgval .or. mask_array(icx,ify) == maskval) cxfy = 0.0
528 if (array(icx, icy, izz) == msgval .or. mask_array(icx,icy) == maskval) cxcy = 0.0
530 else if (present(mask_array) .and. present(maskval)) then
531 if (array(ifx, ify, izz) == msgval .or. mask_array(ifx,ify) == maskval) fxfy = 0.0
532 if (array(ifx, icy, izz) == msgval .or. mask_array(ifx,icy) == maskval) fxcy = 0.0
533 if (array(icx, ify, izz) == msgval .or. mask_array(icx,ify) == maskval) cxfy = 0.0
534 if (array(icx, icy, izz) == msgval .or. mask_array(icx,icy) == maskval) cxcy = 0.0
536 if (array(ifx, ify, izz) == msgval) fxfy = 0.0
537 if (array(ifx, icy, izz) == msgval) fxcy = 0.0
538 if (array(icx, ify, izz) == msgval) cxfy = 0.0
539 if (array(icx, icy, izz) == msgval) cxcy = 0.0
542 ! If all four points are missing, try the next interpolation method in the sequence
543 if (fxfy == 0.0 .and. fxcy == 0.0 .and. cxfy == 0.0 .and. cxcy == 0.0) then
544 four_pt_average = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
545 start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
547 four_pt_average = (fxfy * array(ifx, ify, izz) + &
548 fxcy * array(ifx, icy, izz) + &
549 cxfy * array(icx, ify, izz) + &
550 cxcy * array(icx, icy, izz) ) / (fxfy + fxcy + cxfy + cxcy)
553 end function four_pt_average
556 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
557 ! Name: wt_four_pt_average
559 ! Purpose: Weighted average of four surrounding grid point values
560 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
561 recursive function wt_four_pt_average(xx, yy, izz, array, start_x, end_x, &
562 start_y, end_y, start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
567 integer, intent(in) :: start_x, start_y, start_z
568 integer, intent(in) :: end_x, end_y, end_z
569 integer, intent(in) :: izz ! The z-index of the 2d-array to
571 real, intent(in) :: xx, yy ! The location to interpolate to
572 real, intent(in) :: msgval
573 real, intent(in), optional :: maskval
574 real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), &
576 integer, dimension(:), intent(in) :: interp_list
577 integer, intent(in) :: idx
578 real, dimension(start_x:end_x, start_y:end_y), &
579 intent(in), optional :: mask_array
580 character (len=1), intent(in), optional :: mask_relational
583 real :: wt_four_pt_average
586 integer :: ifx, ify, icx, icy
587 real :: fxfy, fxcy, cxfy, cxcy
594 fxfy = max(0., 1.0 - sqrt((xx-real(ifx))**2+(yy-real(ify))**2))
595 fxcy = max(0., 1.0 - sqrt((xx-real(ifx))**2+(yy-real(icy))**2))
596 cxfy = max(0., 1.0 - sqrt((xx-real(icx))**2+(yy-real(ify))**2))
597 cxcy = max(0., 1.0 - sqrt((xx-real(icx))**2+(yy-real(icy))**2))
599 ! First, make sure that the point is contained in the source array
600 if (ifx < start_x .or. icx > end_x .or. &
601 ify < start_y .or. icy > end_y) then
603 ! But if the point is at most half a grid point out, we can
604 ! still proceed with modified ifx, icx, ify, and icy.
605 if (xx > real(start_x)-0.5 .and. ifx < start_x) then
608 else if (xx < real(end_x)+0.5 .and. icx > end_x) then
613 if (yy > real(start_y)-0.5 .and. ifx < start_y) then
616 else if (yy < real(end_y)+0.5 .and. icy > end_y) then
621 if (ifx < start_x .or. icx > end_x .or. &
622 ify < start_y .or. icy > end_y) then
623 wt_four_pt_average = msgval
628 if (present(mask_array) .and. present(maskval) .and. present(mask_relational)) then
629 ! we determine which maskval is useable by... if the symbol > is found, then only
630 ! values less than 'maskval' can be used and if the symbol < is found,
631 ! then only the values greater than 'maskval' can be used.
632 if (mask_relational == '>') then
633 if (array(ifx, ify, izz) == msgval .or. mask_array(ifx,ify) > maskval) fxfy = 0.0
634 if (array(ifx, icy, izz) == msgval .or. mask_array(ifx,icy) > maskval) fxcy = 0.0
635 if (array(icx, ify, izz) == msgval .or. mask_array(icx,ify) > maskval) cxfy = 0.0
636 if (array(icx, icy, izz) == msgval .or. mask_array(icx,icy) > maskval) cxcy = 0.0
637 else if (mask_relational == '<') then
638 if (array(ifx, ify, izz) == msgval .or. mask_array(ifx,ify) < maskval) fxfy = 0.0
639 if (array(ifx, icy, izz) == msgval .or. mask_array(ifx,icy) < maskval) fxcy = 0.0
640 if (array(icx, ify, izz) == msgval .or. mask_array(icx,ify) < maskval) cxfy = 0.0
641 if (array(icx, icy, izz) == msgval .or. mask_array(icx,icy) < maskval) cxcy = 0.0
643 if (array(ifx, ify, izz) == msgval .or. mask_array(ifx,ify) == maskval) fxfy = 0.0
644 if (array(ifx, icy, izz) == msgval .or. mask_array(ifx,icy) == maskval) fxcy = 0.0
645 if (array(icx, ify, izz) == msgval .or. mask_array(icx,ify) == maskval) cxfy = 0.0
646 if (array(icx, icy, izz) == msgval .or. mask_array(icx,icy) == maskval) cxcy = 0.0
648 else if (present(mask_array) .and. present(maskval)) then
649 if (array(ifx, ify, izz) == msgval .or. mask_array(ifx,ify) == maskval) fxfy = 0.0
650 if (array(ifx, icy, izz) == msgval .or. mask_array(ifx,icy) == maskval) fxcy = 0.0
651 if (array(icx, ify, izz) == msgval .or. mask_array(icx,ify) == maskval) cxfy = 0.0
652 if (array(icx, icy, izz) == msgval .or. mask_array(icx,icy) == maskval) cxcy = 0.0
654 if (array(ifx, ify, izz) == msgval) fxfy = 0.0
655 if (array(ifx, icy, izz) == msgval) fxcy = 0.0
656 if (array(icx, ify, izz) == msgval) cxfy = 0.0
657 if (array(icx, icy, izz) == msgval) cxcy = 0.0
660 ! If all four points are missing, try the next interpolation method in the sequence
661 if (fxfy == 0.0 .and. fxcy == 0.0 .and. cxfy == 0.0 .and. cxcy == 0.0) then
662 wt_four_pt_average = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
663 start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
665 wt_four_pt_average = (fxfy * array(ifx, ify, izz) + &
666 fxcy * array(ifx, icy, izz) + &
667 cxfy * array(icx, ify, izz) + &
668 cxcy * array(icx, icy, izz) ) / (fxfy + fxcy + cxfy + cxcy)
671 end function wt_four_pt_average
674 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
675 ! Name: sixteen_pt_average
677 ! Purpose: Average of sixteen surrounding grid point values
678 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
679 recursive function sixteen_pt_average(xx, yy, izz, array, start_x, end_x, &
680 start_y, end_y, start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
685 integer, intent(in) :: start_x, start_y, start_z
686 integer, intent(in) :: end_x, end_y, end_z
687 integer, intent(in) :: izz ! The z-index of the 2d-array to
689 real, intent(in) :: xx , yy ! The location to interpolate to
690 real, intent(in) :: msgval
691 real, intent(in), optional :: maskval
692 real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), &
694 integer, dimension(:), intent(in) :: interp_list
695 integer, intent(in) :: idx
696 real, dimension(start_x:end_x, start_y:end_y), &
697 intent(in), optional :: mask_array
698 character (len=1), intent(in), optional :: mask_relational
701 real :: sixteen_pt_average
704 integer :: i, j, ifx, ify
705 real :: sum, sum_weight
706 real, dimension(4,4) :: weights
711 ! First see whether the point is far enough within the array to
712 ! allow for a sixteen point average.
713 if (ifx < start_x+1 .or. ifx > end_x-2 .or. &
714 ify < start_y+1 .or. ify > end_y-2) then
715 sixteen_pt_average = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
716 start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
723 if (present(mask_array) .and. present(maskval) .and. present(mask_relational)) then
724 if (mask_relational == '>' .and. mask_array(ifx+3-i, ify+3-j) > maskval) then
726 else if (mask_relational == '<' .and. mask_array(ifx+3-i, ify+3-j) < maskval) then
728 else if (mask_relational == ' ' .and. mask_array(ifx+3-i, ify+3-j) == maskval) then
733 if (array(ifx+3-i, ify+3-j, izz) == msgval) weights(i,j) = 0.0
734 else if (present(mask_array) .and. present(maskval)) then
735 if (array(ifx+3-i, ify+3-j, izz) == msgval .or. mask_array(ifx+3-i, ify+3-j) == maskval) then
741 if (array(ifx+3-i, ify+3-j, izz) == msgval) then
748 sum_weight = sum_weight + weights(i,j)
753 ! If all points are missing, try the next interpolation method in the sequence
754 if (sum_weight == 0.0) then
755 sixteen_pt_average = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
756 start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
761 sum = sum + weights(i,j) * array(ifx+3-i, ify+3-j, izz)
764 sixteen_pt_average = sum / sum_weight
767 end function sixteen_pt_average
770 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
771 ! Name: wt_sixteen_pt_average
773 ! Purpose: Weighted average of sixteen surrounding grid point values
774 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
775 recursive function wt_sixteen_pt_average(xx, yy, izz, array, start_x, end_x, &
776 start_y, end_y, start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
781 integer, intent(in) :: start_x, start_y, start_z
782 integer, intent(in) :: end_x, end_y, end_z
783 integer, intent(in) :: izz ! The z-index of the 2d-array to
785 real, intent(in) :: xx , yy ! The location to interpolate to
786 real, intent(in) :: msgval
787 real, intent(in), optional :: maskval
788 real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), &
790 integer, dimension(:), intent(in) :: interp_list
791 integer, intent(in) :: idx
792 real, dimension(start_x:end_x, start_y:end_y), &
793 intent(in), optional :: mask_array
794 character (len=1), intent(in), optional :: mask_relational
797 real :: wt_sixteen_pt_average
800 integer :: i, j, ifx, ify
801 real :: sum, sum_weight
802 real, dimension(4,4) :: weights
807 ! First see whether the point is far enough within the array to
808 ! allow for a sixteen point average.
809 if (ifx < start_x+1 .or. ifx > end_x-2 .or. &
810 ify < start_y+1 .or. ify > end_y-2) then
811 wt_sixteen_pt_average = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
812 start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
819 if (present(mask_array) .and. present(maskval) .and. present(mask_relational)) then
820 if (mask_relational == '>' .and. mask_array(ifx+3-i, ify+3-j) > maskval) then
822 else if (mask_relational == '<' .and. mask_array(ifx+3-i, ify+3-j) < maskval) then
824 else if (mask_relational == ' ' .and. mask_array(ifx+3-i, ify+3-j) == maskval) then
827 weights(i,j) = max(0., 2.0 - sqrt((xx-real(ifx+3-i))**2+(yy-real(ify+3-j))**2))
829 if (array(ifx+3-i, ify+3-j, izz) == msgval) weights(i,j) = 0.0
830 else if (present(mask_array) .and. present(maskval)) then
831 if (array(ifx+3-i, ify+3-j, izz) == msgval .or. mask_array(ifx+3-i, ify+3-j) == maskval) then
834 weights(i,j) = max(0., 2.0 - sqrt((xx-real(ifx+3-i))**2+(yy-real(ify+3-j))**2))
837 if (array(ifx+3-i, ify+3-j, izz) == msgval) then
840 weights(i,j) = max(0., 2.0 - sqrt((xx-real(ifx+3-i))**2+(yy-real(ify+3-j))**2))
844 sum_weight = sum_weight + weights(i,j)
849 ! If all points are missing, try the next interpolation method in the sequence
850 if (sum_weight == 0.0) then
851 wt_sixteen_pt_average = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
852 start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
857 sum = sum + weights(i,j) * array(ifx+3-i, ify+3-j, izz)
860 wt_sixteen_pt_average = sum / sum_weight
863 end function wt_sixteen_pt_average
866 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
869 ! Purpose: Bilinear interpolation among four grid values
870 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
871 recursive function four_pt(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
872 start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
877 integer, intent(in) :: start_x, start_y, start_z
878 integer, intent(in) :: end_x, end_y, end_z
879 integer, intent(in) :: izz ! The z-index of the 2d-array to
881 real, intent(in) :: xx , yy ! The location to interpolate to
882 real, intent(in) :: msgval
883 real, intent(in), optional :: maskval
884 real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), intent(in) :: array
885 integer, dimension(:), intent(in) :: interp_list
886 integer, intent(in) :: idx
887 real, dimension(start_x:end_x, start_y:end_y), intent(in), optional :: mask_array
888 character (len=1), intent(in), optional :: mask_relational
894 integer :: min_x, min_y, max_x, max_y
901 if (min_x < start_x .or. max_x > end_x) then
902 four_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, start_z, end_z, &
903 msgval, interp_list, idx, mask_relational, maskval, mask_array)
907 if (min_y < start_y .or. max_y > end_y) then
908 four_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, start_z, end_z, &
909 msgval, interp_list, idx, mask_relational, maskval, mask_array)
913 ! If we have a missing value, try the next interpolation method in the sequence
914 if (present(mask_array) .and. present(maskval) .and. present(mask_relational)) then
915 ! we determine which maskval is useable by... if the symbol > is found, then only
916 ! values less than 'maskval' can be used and if the symbol < is found,
917 ! then only the values greater than 'maskval' can be used.
918 if (mask_relational == '>' ) then
919 if (array(min_x,min_y,izz) == msgval .or. mask_array(min_x,min_y) > maskval .or. &
920 array(max_x,min_y,izz) == msgval .or. mask_array(max_x,min_y) > maskval .or. &
921 array(min_x,max_y,izz) == msgval .or. mask_array(min_x,max_y) > maskval .or. &
922 array(max_x,max_y,izz) == msgval .or. mask_array(max_x,max_y) > maskval) then
923 four_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, start_z, end_z, &
924 msgval, interp_list, idx, mask_relational, maskval, mask_array)
927 else if (mask_relational == '<' ) then
928 if (array(min_x,min_y,izz) == msgval .or. mask_array(min_x,min_y) < maskval .or. &
929 array(max_x,min_y,izz) == msgval .or. mask_array(max_x,min_y) < maskval .or. &
930 array(min_x,max_y,izz) == msgval .or. mask_array(min_x,max_y) < maskval .or. &
931 array(max_x,max_y,izz) == msgval .or. mask_array(max_x,max_y) < maskval) then
932 four_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, start_z, end_z, &
933 msgval, interp_list, idx, mask_relational, maskval, mask_array)
936 else if (mask_relational == ' ' ) then
937 if (array(min_x,min_y,izz) == msgval .or. mask_array(min_x,min_y) == maskval .or. &
938 array(max_x,min_y,izz) == msgval .or. mask_array(max_x,min_y) == maskval .or. &
939 array(min_x,max_y,izz) == msgval .or. mask_array(min_x,max_y) == maskval .or. &
940 array(max_x,max_y,izz) == msgval .or. mask_array(max_x,max_y) == maskval) then
941 four_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, start_z, end_z, &
942 msgval, interp_list, idx, mask_relational, maskval, mask_array)
946 else if (present(mask_array) .and. present(maskval)) then
947 if (array(min_x,min_y,izz) == msgval .or. mask_array(min_x,min_y) == maskval .or. &
948 array(max_x,min_y,izz) == msgval .or. mask_array(max_x,min_y) == maskval .or. &
949 array(min_x,max_y,izz) == msgval .or. mask_array(min_x,max_y) == maskval .or. &
950 array(max_x,max_y,izz) == msgval .or. mask_array(max_x,max_y) == maskval) then
951 four_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, start_z, end_z, &
952 msgval, interp_list, idx, mask_relational, maskval, mask_array)
955 if (array(min_x,min_y,izz) == msgval .or. &
956 array(max_x,min_y,izz) == msgval .or. &
957 array(min_x,max_y,izz) == msgval .or. &
958 array(max_x,max_y,izz) == msgval ) then
959 four_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
960 start_z, end_z, msgval, interp_list, idx)
965 if (min_x == max_x) then
966 if (min_y == max_y) then
967 four_pt = array(min_x,min_y,izz)
969 four_pt = array(min_x,min_y,izz)*(real(max_y)-yy) + &
970 array(min_x,max_y,izz)*(yy-real(min_y))
972 else if (min_y == max_y) then
973 if (min_x == max_x) then
974 four_pt = array(min_x,min_y,izz)
976 four_pt = array(min_x,min_y,izz)*(real(max_x)-xx) + &
977 array(max_x,min_y,izz)*(xx-real(min_x))
980 four_pt = (yy - min_y) * (array(min_x,max_y,izz)*(real(max_x)-xx) + &
981 array(max_x,max_y,izz)*(xx-real(min_x))) + &
982 (max_y - yy) * (array(min_x,min_y,izz)*(real(max_x)-xx) + &
983 array(max_x,min_y,izz)*(xx-real(min_x)));
989 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
992 ! Purpose: Overlapping parabolic interpolation among sixteen grid values
993 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
994 recursive function sixteen_pt(xx, yy, izz, array, start_x, end_x, start_y, end_y, start_z, end_z, &
995 msgval, interp_list, idx, mask_relational, maskval, mask_array)
1000 integer, intent(in) :: izz ! z-index of 2d-array to interpolate within
1001 integer, intent(in) :: start_x, start_y, start_z
1002 integer, intent(in) :: end_x, end_y, end_z
1003 real, intent(in) :: xx , yy ! The location to interpolate to
1004 real, intent(in) :: msgval
1005 real, intent(in), optional :: maskval
1006 real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), &
1008 integer, dimension(:), intent(in) :: interp_list
1009 integer, intent(in) :: idx
1010 real, dimension(start_x:end_x, start_y:end_y), &
1011 intent(in), optional :: mask_array
1012 character (len=1), intent(in), optional :: mask_relational
1018 integer :: n , i , j , k , kk , l , ll
1019 real :: x , y , a , b , c , d , e , f , g , h
1020 real, dimension(4,4) :: stl
1021 logical :: is_masked
1025 if (int(xx) < start_x .or. int(xx) > end_x .or. &
1026 int(yy) < start_y .or. int(yy) > end_y) then
1027 sixteen_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
1028 start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
1034 i = int(xx + 0.00001)
1035 j = int(yy + 0.00001)
1039 if ( ( abs(x) > 0.0001 ) .or. ( abs(y) > 0.0001 ) ) then
1043 if ( kk < start_x) then
1045 else if ( kk > end_x) then
1051 if ( ll < start_y ) then
1053 else if ( ll > end_y) then
1056 stl(k,l) = array(kk,ll,izz)
1058 if (present(mask_array) .and. present(maskval) .and. present(mask_relational)) then
1059 if (mask_relational == '>' .and. mask_array(kk,ll) > maskval) then
1061 else if (mask_relational == '<' .and. mask_array(kk,ll) < maskval) then
1063 else if (mask_relational == ' ' .and. mask_array(kk,ll) == maskval) then
1066 else if (present(mask_array) .and. present(maskval)) then
1067 if (mask_array(kk,ll) == maskval) is_masked = .true.
1069 if ( stl(k,l) == 0. .and. msgval /= 0.) then
1075 ! If we have a missing value, try the next interpolation method in the sequence
1076 if (present(mask_array) .and. present(maskval)) then
1079 if (stl(k,l) == msgval .or. is_masked) then
1080 sixteen_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
1081 start_z, end_z, msgval, interp_list, idx, mask_relational, maskval, mask_array)
1089 if (stl(k,l) == msgval) then
1090 sixteen_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, &
1091 start_z, end_z, msgval, interp_list, idx)
1098 a = oned(x,stl(1,1),stl(2,1),stl(3,1),stl(4,1))
1099 b = oned(x,stl(1,2),stl(2,2),stl(3,2),stl(4,2))
1100 c = oned(x,stl(1,3),stl(2,3),stl(3,3),stl(4,3))
1101 d = oned(x,stl(1,4),stl(2,4),stl(3,4),stl(4,4))
1102 sixteen_pt = oned(y,a,b,c,d)
1105 e = oned(y,stl(1,1),stl(1,2),stl(1,3),stl(1,4))
1106 f = oned(y,stl(2,1),stl(2,2),stl(2,3),stl(2,4))
1107 g = oned(y,stl(3,1),stl(3,2),stl(3,3),stl(3,4))
1108 h = oned(y,stl(4,1),stl(4,2),stl(4,3),stl(4,4))
1109 sixteen_pt = (sixteen_pt+oned(x,e,f,g,h)) * 0.5
1112 if (sixteen_pt == 1.E-20) sixteen_pt = 0.
1115 if (present(mask_array) .and. present(maskval) .and. present(mask_relational)) then
1116 if (i >= start_x .and. i <= end_x .and. j >= start_y .and. j <= end_y .and. &
1117 mask_relational == '<' .and. mask_array(i,j) >= maskval .and. array(i,j,izz) /= msgval) then
1118 sixteen_pt = array(i,j,izz)
1119 else if (i >= start_x .and. i <= end_x .and. j >= start_y .and. j <= end_y .and. &
1120 mask_relational == '>' .and. mask_array(i,j) <= maskval .and. array(i,j,izz) /= msgval) then
1121 sixteen_pt = array(i,j,izz)
1122 else if (i >= start_x .and. i <= end_x .and. j >= start_y .and. j <= end_y .and. &
1123 mask_relational == ' ' .and. mask_array(i,j) /= maskval .and. array(i,j,izz) /= msgval) then
1124 sixteen_pt = array(i,j,izz)
1126 sixteen_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, start_z, end_z, &
1127 msgval, interp_list, idx, mask_relational, maskval, mask_array)
1129 else if (present(mask_array) .and. present(maskval)) then
1130 if (i >= start_x .and. i <= end_x .and. j >= start_y .and. j <= end_y .and. &
1131 mask_array(i,j) /= maskval .and. array(i,j,izz) /= msgval) then
1132 sixteen_pt = array(i,j,izz)
1134 sixteen_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, start_z, end_z, &
1135 msgval, interp_list, idx, mask_relational, maskval, mask_array)
1138 if (i >= start_x .and. i <= end_x .and. j >= start_y .and. j <= end_y .and. array(i,j,izz) /= msgval) then
1139 sixteen_pt = array(i,j,izz)
1141 sixteen_pt = interp_sequence(xx, yy, izz, array, start_x, end_x, start_y, end_y, start_z, end_z, &
1142 msgval, interp_list, idx, mask_relational, maskval, mask_array)
1147 end function sixteen_pt
1150 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1153 ! Purpose: 1-dimensional overlapping parabolic interpolation
1154 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1155 function oned(x,a,b,c,d)
1160 real, intent(in) :: x,a,b,c,d
1169 else if ( x == 1. ) then
1174 if ( a*d == 0. ) then
1175 if ( ( a == 0 ) .and. ( d == 0 ) ) then
1176 oned = b*(1.0-x)+c*x
1177 else if ( a /= 0. ) then
1178 oned = b+x*(0.5*(c-a)+x*(0.5*(c+a)-b))
1179 else if ( d /= 0. ) then
1180 oned = c+(1.0-x)*(0.5*(b-d)+(1.0-x)*(0.5*(b+d)-c))
1183 oned = (1.0-x)*(b+x*(0.5*(c-a)+x*(0.5*(c+a)-b)))+x*(c+(1.0-x)*(0.5*(b-d)+(1.0-x)*(0.5*(b+d)-c)))
1189 end module interp_module