File: knfrom4.F

package info (click to toggle)
emoslib 000380%2Bdfsg-3
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 47,712 kB
  • ctags: 11,551
  • sloc: fortran: 89,643; ansic: 24,200; makefile: 370; sh: 355
file content (174 lines) | stat: -rwxr-xr-x 4,625 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
C Copyright 1981-2007 ECMWF
C 
C Licensed under the GNU Lesser General Public License which
C incorporates the terms and conditions of version 3 of the GNU
C General Public License.
C See LICENSE and gpl-3.0.txt for details.
C

      REAL FUNCTION KNFROM4(LVEGGY,RLAT,RLON,OLAT,OLON,PT,OLDFLD)
C
C---->
C**** KNFROM4
C
C     Purpose
C     -------
C
C     Generates a new field point from its four nearest neighbours.
C
C
C     Interface
C     ---------
C
C     VALUE = KNFROM4(RLAT,RLON,OLAT,OLON,PT,OLDFLD)
C
C     Input
C     -----
C
C     LVEGGY - 'True' if 'nearest neighbour' processing required
C     RLAT   - Latitude of the new point
C     RLON   - Longitude of the new point
C     OLAT   - Latitudes of the four neighbouring points
C     OLON   - Longitudes of the four neighbouring points
C     PT     - Positions in old field array of the four neighbours
C     OLDFLD - Array of old field values
C
C
C     Output
C     ------
C
C     Function returns a value for the new field point.
C
C
C     Method
C     ------
C
C     Uses neighbours to calculate a value by bi-linear interpolation.
C
C
C     Externals
C     ---------
C
C     None.
C
C
C     Author
C     ------
C
C     J.D.Chambers     ECMWF     November 2000
C
C----<
C
      IMPLICIT NONE
C
C     Function arguments
C
      LOGICAL LVEGGY
      REAL RLAT,RLON,OLAT(2),OLON(4),OLDFLD(*)
      INTEGER PT(4)
C
#include "intisl.h"
#include "parim.h"
#include "nifld.common"
C
C     Local variables
C
      INTEGER COUNT, LOOP, NEAREST
      REAL WEIGHT(4), NWEIGHT, SWEIGHT, NORMAL
C
C     Externals
C
C
C     Statement function
C
      REAL A, B
      LOGICAL NOTEQ
      NOTEQ(A,B) = (ABS((A)-(B)).GT.(ABS(A)*1E-3))
C
C     -----------------------------------------------------------------|
C*    Section 1. Calculate weighting values for each neighbour
C     -----------------------------------------------------------------|
C
  100 CONTINUE
C
C     Calculate the north/south weighting values allowing for
C     southern latitude to be same as northern latitude
C
      NWEIGHT = OLAT(NORTH) - RLAT
      SWEIGHT = RLAT - OLAT(SOUTH)
      IF( SWEIGHT.EQ.0.0 ) NWEIGHT = 1.0
C
C     Calculate the weighting values for each matching neighbour
C
      WEIGHT(NWEST) = ABS((OLON(SEAST) - RLON) * SWEIGHT)
      WEIGHT(NEAST) = ABS((RLON - OLON(SWEST)) * SWEIGHT)
      WEIGHT(SWEST) = ABS((OLON(NEAST) - RLON) * NWEIGHT)
      WEIGHT(SEAST) = ABS((RLON - OLON(NWEST)) * NWEIGHT)
C
C     Normalise the weights
C
      NORMAL = ( WEIGHT(NWEST) + WEIGHT(NEAST) +
     X           WEIGHT(SWEST) + WEIGHT(SEAST) )
C
      WEIGHT(NWEST) = WEIGHT(NWEST)/NORMAL
      WEIGHT(NEAST) = WEIGHT(NEAST)/NORMAL
      WEIGHT(SWEST) = WEIGHT(SWEST)/NORMAL
      WEIGHT(SEAST) = WEIGHT(SEAST)/NORMAL
C
C     -----------------------------------------------------------------|
C*    Section 3.   Interpolate
C     -----------------------------------------------------------------|
C
  300 CONTINUE
C
C     Use nearest neighbour for vegetation field
C
      IF( LVEGGY ) THEN
        NEAREST = NWEST
        IF( WEIGHT(NEAST).GT.WEIGHT(NEAREST) ) NEAREST = NEAST
        IF( WEIGHT(SWEST).GT.WEIGHT(NEAREST) ) NEAREST = SWEST
        IF( WEIGHT(SEAST).GT.WEIGHT(NEAREST) ) NEAREST = SEAST
        KNFROM4 = OLDFLD(PT(NEAREST))
C
      ELSE
C
C       Count non-missing data values
C
        COUNT = 0
        IF( NOTEQ(OLDFLD(PT(NWEST)),RMISSGV) ) COUNT = COUNT + 1
        IF( NOTEQ(OLDFLD(PT(NEAST)),RMISSGV) ) COUNT = COUNT + 1
        IF( NOTEQ(OLDFLD(PT(SWEST)),RMISSGV) ) COUNT = COUNT + 1
        IF( NOTEQ(OLDFLD(PT(SEAST)),RMISSGV) ) COUNT = COUNT + 1
C
C       Interpolate using four neighbours if none are missing
C
        IF( COUNT.EQ.4 ) THEN
          KNFROM4 = ( (OLDFLD(PT(NWEST)) * WEIGHT(NWEST)) +
     X                (OLDFLD(PT(NEAST)) * WEIGHT(NEAST)) +
     X                (OLDFLD(PT(SWEST)) * WEIGHT(SWEST)) +
     X                (OLDFLD(PT(SEAST)) * WEIGHT(SEAST)) )
C
C       Set missing if all neighbours are missing
C
        ELSE IF( COUNT.EQ.0 ) THEN
          KNFROM4 = RMISSGV
C
C       Otherwise, use the nearest neighbour
C
        ELSE
          NEAREST = NWEST
          IF( WEIGHT(NEAST).GT.WEIGHT(NEAREST) ) NEAREST = NEAST
          IF( WEIGHT(SWEST).GT.WEIGHT(NEAREST) ) NEAREST = SWEST
          IF( WEIGHT(SEAST).GT.WEIGHT(NEAREST) ) NEAREST = SEAST
          KNFROM4 = OLDFLD(PT(NEAREST))
        ENDIF
      ENDIF
C
C     -----------------------------------------------------------------|
C*    Section 9.   Return
C     -----------------------------------------------------------------|
C
  900 CONTINUE
C
      RETURN
      END