Subversion Repositories lagranto.wrf

Rev

Rev 8 | Rev 15 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8 Rev 11
1
      PROGRAM wrfmap
1
      PROGRAM wrfmap
2
 
2
 
3
c     **********************************************************************
3
c     **********************************************************************
4
c     * Transform between lon/lat and x/y coordinates                      *
4
c     * Transform between lon/lat and x/y coordinates                      *
5
c     * Michael Sprenger / Spring 2013                                     *
5
c     * Michael Sprenger / Spring 2013                                     *
6
c     **********************************************************************
6
c     **********************************************************************
7
 
7
 
8
      implicit none
8
      implicit none
9
     
9
     
10
c     ------------------------------------------------------------
10
c     ------------------------------------------------------------
11
c     Declaration of parameters and variables
11
c     Declaration of parameters and variables
12
c     ------------------------------------------------------------
12
c     ------------------------------------------------------------
13
 
13
 
14
c     Input parameters
14
c     Input parameters
15
      character*80 mode
15
      character*80 mode
16
      character*80 inpfile
16
      character*80 inpfile
17
      character*80 outfile
17
      character*80 outfile
18
      integer      ntra,ntim,ncol
18
      integer      ntra,ntim,ncol
19
      character*80 anglemode
19
      character*80 anglemode
20
 
20
 
21
c     Fixed parameters
21
c     Fixed parameters
22
      character*80 mapfile                          ! netCDF file with map transformation
22
      character*80 mapfile                          ! netCDF file with map transformation
23
      parameter    (mapfile ='wrfmap.nc')
23
      parameter    (mapfile ='wrfmap.nc')
24
      real         mdv                              ! missing data value
24
      real         mdv                              ! missing data value
25
      parameter    (mdv=-999.)
25
      parameter    (mdv=-999.)
26
 
26
 
27
c     Numerical grid
27
c     Numerical grid
28
      real         xmin,xmax,ymin,ymax              ! Domain size
28
      real         xmin,xmax,ymin,ymax              ! Domain size
29
      real         dx,dy                            ! Horizontal resolution
29
      real         dx,dy                            ! Horizontal resolution
30
      integer      nx,ny,nz                         ! Grid dimensions
30
      integer      nx,ny,nz                         ! Grid dimensions
31
      real,allocatable,dimension (:,:)  :: lon,lat  ! lon/lat on numerical grid
31
      real,allocatable,dimension (:,:)  :: lon,lat  ! lon/lat on numerical grid
32
      real,allocatable,dimension (:,:)  :: mpx,mpy  ! map scale factors in x/y direction
32
      real,allocatable,dimension (:,:)  :: mpx,mpy  ! map scale factors in x/y direction
33
 
33
 
34
 
34
 
35
c     Geographical grid
35
c     Geographical grid
36
      real         latmin,latmax,lonmin,lonmax      ! Geographical domain
36
      real         latmin,latmax,lonmin,lonmax      ! Geographical domain
37
      real         dlon,dlat                        ! Minimum spacing in geographical space
37
      real         dlon,dlat                        ! Minimum spacing in geographical space
38
      integer      nlon,nlat,nlev                        ! Geographical grid dimension
38
      integer      nlon,nlat,nlev                        ! Geographical grid dimension
39
      real,allocatable,dimension (:,:)   :: x,y      ! x/y on geographical grid
39
      real,allocatable,dimension (:,:)   :: x,y      ! x/y on geographical grid
40
 
40
 
41
c     Vertical grid
41
c     Vertical grid
42
      real,allocatable,dimension (:,:,:)   :: p3    ! 3D pressure
42
      real,allocatable,dimension (:,:,:)   :: p3    ! 3D pressure
43
      real,allocatable,dimension (:,:)     :: ps    ! surface pressure
43
      real,allocatable,dimension (:,:)     :: ps    ! surface pressure
44
      real,allocatable,dimension (:,:,:)   :: z3    ! 3D geopotential height
44
      real,allocatable,dimension (:,:,:)   :: z3    ! 3D geopotential height
45
      real,allocatable,dimension (:,:)     :: zb    ! surface geopotential height
45
      real,allocatable,dimension (:,:)     :: zb    ! surface geopotential height
46
 
46
 
47
c     Transformation between numerical and geographical grid
47
c     Transformation between numerical and geographical grid
48
      real,allocatable,dimension (:,:)  :: connect1 
48
      real,allocatable,dimension (:,:)  :: connect1 
49
      integer      connectval1 
49
      integer      connectval1 
50
      real,allocatable,dimension (:,:)  :: connect2 
50
      real,allocatable,dimension (:,:)  :: connect2 
51
      integer      connectval2
51
      integer      connectval2
52
      real,allocatable,dimension (:,:)  :: xc,yc
52
      real,allocatable,dimension (:,:)  :: xc,yc
53
      real         radius
53
      real         radius
54
      real         xval,yval
54
      real         xval,yval
55
 
55
 
56
c     Trajectories
56
c     Trajectories
57
      real,allocatable, dimension (:,:,:) :: tra             ! Input start coordinates (ntra,ntim,ncol)
57
      real,allocatable, dimension (:,:,:) :: tra             ! Input start coordinates (ntra,ntim,ncol)
58
      integer                                refdate(6)      ! Reference date
58
      integer                                refdate(6)      ! Reference date
59
      character*80                           vars(200)       ! Field names
59
      character*80                           vars(200)       ! Field names
60
      real,allocatable, dimension (:)     :: xx0,yy0,zz0     ! Position of air parcels
60
      real,allocatable, dimension (:)     :: xx0,yy0,zz0     ! Position of air parcels
61
      integer                                inpmode
61
      integer                                inpmode
62
      integer                                outmode
62
      integer                                outmode
63
      integer                                npoints
63
      integer                                npoints
64
 
64
 
65
c     Auxiliary variables
65
c     Auxiliary variables
66
      integer      fid
66
      integer      fid
67
      integer      stat
67
      integer      stat
68
      character*80 varname,cdfname
68
      character*80 varname,cdfname
69
      integer      i,j
69
      integer      i,j
70
      character*80 radunit
70
      character*80 radunit
71
      real         rdummy
71
      real         rdummy
72
      real         rid,rjd,rkd
72
      real         rid,rjd,rkd
73
      real         xpos,ypos,zpos,ppos,lonpos,latpos
73
      real         xpos,ypos,zpos,ppos,lonpos,latpos
74
      real         lon1,lat1,lon2,lat2
74
      real         lon1,lat1,lon2,lat2
-
 
75
      integer      nfilter
75
 
76
 
76
c     Externals
77
c     Externals
77
      real         int_index3
78
      real         int_index3
78
      external     int_index3
79
      external     int_index3
79
      real         sdis
80
      real         sdis
80
      external     sdis
81
      external     sdis
81
 
82
 
82
c     ------------------------------------------------------------
83
c     ------------------------------------------------------------
83
c     Preparations
84
c     Preparations
84
c     ------------------------------------------------------------
85
c     ------------------------------------------------------------
85
 
86
 
86
c     Read parameters
87
c     Read parameters
87
      open(10,file='wrfmap.param')
88
      open(10,file='wrfmap.param')
88
 
89
 
89
       read(10,*) mode
90
       read(10,*) mode
90
 
91
 
91
       if ( mode.eq.'-create' ) then         ! create mapping file
92
       if ( mode.eq.'-create' ) then         ! create mapping file
92
          read(10,*) inpfile
93
          read(10,*) inpfile
93
          read(10,*) anglemode
94
          read(10,*) anglemode
94
       endif
95
       endif
95
 
96
 
96
       if ( mode.eq.'-ll2xy'  ) then         ! convert lon/lat -> x/y
97
       if ( mode.eq.'-ll2xy'  ) then         ! convert lon/lat -> x/y
97
          read(10,*) inpfile
98
          read(10,*) inpfile
98
          read(10,*) outfile
99
          read(10,*) outfile
99
          read(10,*) ntra,ntim,ncol
100
          read(10,*) ntra,ntim,ncol
100
       endif
101
       endif
101
 
102
 
102
       if ( mode.eq.'-ll2xy.single'  ) then   ! convert single lon/lat -> x/y
103
       if ( mode.eq.'-ll2xy.single'  ) then   ! convert single lon/lat -> x/y
103
          read(10,*) lonpos,latpos
104
          read(10,*) lonpos,latpos
104
       endif
105
       endif
105
 
106
 
106
       if ( mode.eq.'-xy2ll'  ) then         ! convert x/y -> lon/lat
107
       if ( mode.eq.'-xy2ll'  ) then         ! convert x/y -> lon/lat
107
          read(10,*) inpfile
108
          read(10,*) inpfile
108
          read(10,*) outfile
109
          read(10,*) outfile
109
          read(10,*) ntra,ntim,ncol
110
          read(10,*) ntra,ntim,ncol
110
       endif
111
       endif
111
 
112
 
112
       if ( mode.eq.'-xy2ll.single'  ) then   ! convert single x/y -> lon/lat
113
       if ( mode.eq.'-xy2ll.single'  ) then   ! convert single x/y -> lon/lat
113
          read(10,*) xpos,ypos
114
          read(10,*) xpos,ypos
114
       endif
115
       endif
115
 
116
 
116
       if ( mode.eq.'-p2z'  ) then            ! convert x/y/p -> x/y/z
117
       if ( mode.eq.'-p2z'  ) then            ! convert x/y/p -> x/y/z
117
          read(10,*) inpfile
118
          read(10,*) inpfile
118
          read(10,*) outfile
119
          read(10,*) outfile
119
          read(10,*) ntra,ntim,ncol
120
          read(10,*) ntra,ntim,ncol
120
       endif
121
       endif
121
 
122
 
122
       if ( mode.eq.'-p2z.single'  ) then     ! convert single x/y/p -> x/y/z
123
       if ( mode.eq.'-p2z.single'  ) then     ! convert single x/y/p -> x/y/z
123
          read(10,*) xpos,ypos,ppos
124
          read(10,*) xpos,ypos,ppos
124
       endif
125
       endif
125
 
126
 
126
       if ( mode.eq.'-z2p'  ) then            ! convert x/y/z -> x/y/p
127
       if ( mode.eq.'-z2p'  ) then            ! convert x/y/z -> x/y/p
127
          read(10,*) inpfile
128
          read(10,*) inpfile
128
          read(10,*) outfile
129
          read(10,*) outfile
129
          read(10,*) ntra,ntim,ncol
130
          read(10,*) ntra,ntim,ncol
130
       endif
131
       endif
131
 
132
 
132
       if ( mode.eq.'-z2p.single'  ) then     ! convert single x/y/z -> x/y/p
133
       if ( mode.eq.'-z2p.single'  ) then     ! convert single x/y/z -> x/y/p
133
          read(10,*) xpos,ypos,zpos
134
          read(10,*) xpos,ypos,zpos
134
       endif
135
       endif
135
 
136
 
-
 
137
       if ( mode.eq.'-mapscale'  ) then       ! calculate mapping scale factors
-
 
138
          read(10,*) nfilter
-
 
139
       endif
-
 
140
 
136
      close(10)
141
      close(10)
137
 
142
 
138
c     Read the mapping file - except for mode '-create'
143
c     Read the mapping file - except for mode '-create'
139
      if ( mode.ne.'-create' ) then
144
      if ( mode.ne.'-create' ) then
140
 
145
 
141
c        Get dimensions 
146
c        Get dimensions 
142
         cdfname = mapfile
147
         cdfname = mapfile
143
         varname = 'Z'
148
         varname = 'Z'
144
         nx      = 1
149
         nx      = 1
145
         ny      = 1
150
         ny      = 1
146
         nz      = 1
151
         nz      = 1
147
         call readcdf2D(cdfname,varname,rdummy,0.,
152
         call readcdf2D(cdfname,varname,rdummy,0.,
148
     >                  dx,dy,xmin,ymin,nx,ny,nz)
153
     >                  dx,dy,xmin,ymin,nx,ny,nz)
149
 
154
 
150
         cdfname = mapfile
155
         cdfname = mapfile
151
         varname = 'X'
156
         varname = 'X'
152
         nlon    = 1
157
         nlon    = 1
153
         nlat    = 1
158
         nlat    = 1
154
         nlev    = 1
159
         nlev    = 1
155
         call readcdf2D(cdfname,varname,rdummy,0.,
160
         call readcdf2D(cdfname,varname,rdummy,0.,
156
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,nlev)
161
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,nlev)
157
 
162
 
158
c        Allocate memory
163
c        Allocate memory
159
         allocate(lon(nx,ny),stat=stat)
164
         allocate(lon(nx,ny),stat=stat)
160
         if (stat.ne.0) print*,'*** error allocating array lon ***'
165
         if (stat.ne.0) print*,'*** error allocating array lon ***'
161
         allocate(lat(nx,ny),stat=stat)
166
         allocate(lat(nx,ny),stat=stat)
162
         if (stat.ne.0) print*,'*** error allocating array lat ***'
167
         if (stat.ne.0) print*,'*** error allocating array lat ***'
163
         allocate(x(nlon,nlat),stat=stat)
168
         allocate(x(nlon,nlat),stat=stat)
164
         if (stat.ne.0) print*,'*** error allocating array x   ***'
169
         if (stat.ne.0) print*,'*** error allocating array x   ***'
165
         allocate(y(nlon,nlat),stat=stat)
170
         allocate(y(nlon,nlat),stat=stat)
166
         if (stat.ne.0) print*,'*** error allocating array y   ***'
171
         if (stat.ne.0) print*,'*** error allocating array y   ***'
167
         allocate(p3(nx,ny,nz),stat=stat)
172
         allocate(p3(nx,ny,nz),stat=stat)
168
         if (stat.ne.0) print*,'*** error allocating array p3  ***'
173
         if (stat.ne.0) print*,'*** error allocating array p3  ***'
169
         allocate(z3(nx,ny,nz),stat=stat)
174
         allocate(z3(nx,ny,nz),stat=stat)
170
         if (stat.ne.0) print*,'*** error allocating array z3  ***'
175
         if (stat.ne.0) print*,'*** error allocating array z3  ***'
171
         allocate(zb(nx,ny),stat=stat)
176
         allocate(zb(nx,ny),stat=stat)
172
         if (stat.ne.0) print*,'*** error allocating array zb  ***'
177
         if (stat.ne.0) print*,'*** error allocating array zb  ***'
173
         allocate(ps(nx,ny),stat=stat)
178
         allocate(ps(nx,ny),stat=stat)
174
         if (stat.ne.0) print*,'*** error allocating array ps  ***'
179
         if (stat.ne.0) print*,'*** error allocating array ps  ***'
175
 
180
 
176
c        Read data
181
c        Read data
177
         cdfname = mapfile
182
         cdfname = mapfile
178
         varname = 'LON'
183
         varname = 'LON'
179
         call readcdf2D(cdfname,varname,lon,0.,
184
         call readcdf2D(cdfname,varname,lon,0.,
180
     >                  dx,dy,xmin,ymin,nx,ny,1)
185
     >                  dx,dy,xmin,ymin,nx,ny,1)
181
         cdfname = mapfile
186
         cdfname = mapfile
182
         varname = 'LAT'
187
         varname = 'LAT'
183
         call readcdf2D(cdfname,varname,lat,0.,
188
         call readcdf2D(cdfname,varname,lat,0.,
184
     >                  dx,dy,xmin,ymin,nx,ny,1)
189
     >                  dx,dy,xmin,ymin,nx,ny,1)
185
         cdfname = mapfile
190
         cdfname = mapfile
186
         varname = 'X'
191
         varname = 'X'
187
         call readcdf2D(cdfname,varname,x,0.,
192
         call readcdf2D(cdfname,varname,x,0.,
188
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,1)
193
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,1)
189
         cdfname = mapfile
194
         cdfname = mapfile
190
         varname = 'Y'
195
         varname = 'Y'
191
         call readcdf2D(cdfname,varname,y,0.,
196
         call readcdf2D(cdfname,varname,y,0.,
192
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,1)
197
     >                  dlon,dlat,lonmin,latmin,nlon,nlat,1)
193
         cdfname = mapfile
198
         cdfname = mapfile
194
         varname = 'Z'
199
         varname = 'Z'
195
         call readcdf2D(cdfname,varname,z3,0.,
200
         call readcdf2D(cdfname,varname,z3,0.,
196
     >                  dx,dy,xmin,ymin,nx,ny,nz)
201
     >                  dx,dy,xmin,ymin,nx,ny,nz)
197
         cdfname = mapfile
202
         cdfname = mapfile
198
         varname = 'P'
203
         varname = 'P'
199
         call readcdf2D(cdfname,varname,p3,0.,
204
         call readcdf2D(cdfname,varname,p3,0.,
200
     >                  dx,dy,xmin,ymin,nx,ny,nz)
205
     >                  dx,dy,xmin,ymin,nx,ny,nz)
201
         cdfname = mapfile
206
         cdfname = mapfile
202
         varname = 'TOPO'
207
         varname = 'TOPO'
203
         call readcdf2D(cdfname,varname,zb,0.,
208
         call readcdf2D(cdfname,varname,zb,0.,
204
     >                  dx,dy,xmin,ymin,nx,ny,1)
209
     >                  dx,dy,xmin,ymin,nx,ny,1)
205
 
210
 
206
c	     Set surface prtessure to lowest 3d pressure level
211
c	     Set surface prtessure to lowest 3d pressure level
207
         do i=1,nx
212
         do i=1,nx
208
            do j=1,ny
213
            do j=1,ny
209
               ps(i,j) = p3(i,j,1)
214
               ps(i,j) = p3(i,j,1)
210
            enddo
215
            enddo
211
         enddo
216
         enddo
212
 
217
 
213
      endif
218
      endif
214
 
219
 
215
c     ------------------------------------------------------------
220
c     ------------------------------------------------------------
216
c     Create mapping file
221
c     Create mapping file
217
c     ------------------------------------------------------------
222
c     ------------------------------------------------------------
218
 
223
 
219
      if ( mode.eq.'-create' ) then
224
      if ( mode.eq.'-create' ) then
220
 
225
 
221
c     Open mapping file
226
c     Open mapping file
222
      call input_open(fid,inpfile)
227
      call input_open(fid,inpfile)
223
 
228
 
224
c     Get grid description
229
c     Get grid description
225
      call input_grid_wrf(fid,
230
      call input_grid_wrf(fid,
226
     >		          xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz)
231
     >		          xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz)
227
 
232
 
228
c     Write grid information to screen
233
c     Write grid information to screen
229
      print*,' xmin,xmax  = ',xmin,xmax
234
      print*,' xmin,xmax  = ',xmin,xmax
230
      print*,' ymin,ymax  = ',ymin,ymax
235
      print*,' ymin,ymax  = ',ymin,ymax
231
      print*,' dx,dy      = ',dx,dy
236
      print*,' dx,dy      = ',dx,dy
232
      print*,' nx,ny,nz   = ',nx,ny,nz 
237
      print*,' nx,ny,nz   = ',nx,ny,nz 
233
 
238
 
234
c     Transform grid specifier into grid coordinates
239
c     Transform grid specifier into grid coordinates
235
      xmin = 1.
240
      xmin = 1.
236
      ymin = 1.
241
      ymin = 1.
237
      dx   = 1.
242
      dx   = 1.
238
      dy   = 1.
243
      dy   = 1.
239
 
244
 
240
c     Allocate memory for lon/lat on numerical grid
245
c     Allocate memory for lon/lat on numerical grid
241
      allocate(lon(nx,ny),stat=stat)
246
      allocate(lon(nx,ny),stat=stat)
242
      if (stat.ne.0) print*,'*** error allocating array lon ***'
247
      if (stat.ne.0) print*,'*** error allocating array lon ***'
243
      allocate(lat(nx,ny),stat=stat)
248
      allocate(lat(nx,ny),stat=stat)
244
      if (stat.ne.0) print*,'*** error allocating array lat ***'
249
      if (stat.ne.0) print*,'*** error allocating array lat ***'
245
      allocate(p3(nx,ny,nz),stat=stat)
250
      allocate(p3(nx,ny,nz),stat=stat)
246
      if (stat.ne.0) print*,'*** error allocating array p3  ***'
251
      if (stat.ne.0) print*,'*** error allocating array p3  ***'
247
      allocate(z3(nx,ny,nz),stat=stat)
252
      allocate(z3(nx,ny,nz),stat=stat)
248
      if (stat.ne.0) print*,'*** error allocating array z3  ***'
253
      if (stat.ne.0) print*,'*** error allocating array z3  ***'
249
      allocate(zb(nx,ny),stat=stat)
254
      allocate(zb(nx,ny),stat=stat)
250
      if (stat.ne.0) print*,'*** error allocating array zb  ***'
255
      if (stat.ne.0) print*,'*** error allocating array zb  ***'
251
 
256
 
252
c     Read lon/lat on the model grid
257
c     Read lon/lat on the model grid
253
      varname='XLONG'
258
      varname='XLONG'
254
      call input_var_wrf(fid,varname,lon,nx,ny,1)
259
      call input_var_wrf(fid,varname,lon,nx,ny,1)
255
      varname='XLAT'
260
      varname='XLAT'
256
      call input_var_wrf(fid,varname,lat,nx,ny,1)
261
      call input_var_wrf(fid,varname,lat,nx,ny,1)
257
      varname='pressure'
262
      varname='pressure'
258
      call input_var_wrf(fid,varname,p3 ,nx,ny,nz)
263
      call input_var_wrf(fid,varname,p3 ,nx,ny,nz)
259
      varname='geopot'
264
      varname='geopot'
260
      call input_var_wrf(fid,varname,z3 ,nx,ny,nz)
265
      call input_var_wrf(fid,varname,z3 ,nx,ny,nz)
261
      varname='geopots'
266
      varname='geopots'
262
      call input_var_wrf(fid,varname,zb ,nx,ny,1)
267
      call input_var_wrf(fid,varname,zb ,nx,ny,1)
263
 
268
 
264
c     Transform longitude depending on <anglemode>
269
c     Transform longitude depending on <anglemode>
265
      if ( anglemode.eq.'greenwich' ) then
270
      if ( anglemode.eq.'greenwich' ) then
266
         do i=1,nx
271
         do i=1,nx
267
           do j=1,ny
272
           do j=1,ny
268
              if ( lon(i,j).lt.0. ) lon(i,j) = lon(i,j) + 360.
273
              if ( lon(i,j).lt.0. ) lon(i,j) = lon(i,j) + 360.
269
            enddo
274
            enddo
270
         enddo
275
         enddo
271
      elseif ( anglemode.eq.'dateline' ) then
276
      elseif ( anglemode.eq.'dateline' ) then
272
         do i=1,nx
277
         do i=1,nx
273
            do j=1,ny
278
            do j=1,ny
274
               if ( lon(i,j).gt.180. ) lon(i,j) = lon(i,j) - 360.
279
               if ( lon(i,j).gt.180. ) lon(i,j) = lon(i,j) - 360.
275
            enddo
280
            enddo
276
         enddo
281
         enddo
277
      else
282
      else
278
         print*,' ERROR: unsupported angle mode... Stop'
283
         print*,' ERROR: unsupported angle mode... Stop'
279
         stop
284
         stop
280
      endif
285
      endif
281
 
286
 
282
c     Close input file file
287
c     Close input file file
283
      call input_close(fid)
288
      call input_close(fid)
284
 
289
 
285
c     Check for 'date line' and for pole
290
c     Check for 'date line' and for pole
286
      do i=2,nx
291
      do i=2,nx
287
      do j=1,ny
292
      do j=1,ny
288
        if ( abs( lat(i,j) ).gt.90. ) then
293
        if ( abs( lat(i,j) ).gt.90. ) then
289
           print*,' ERROR: mapping over pole not supported... Stop'
294
           print*,' ERROR: mapping over pole not supported... Stop'
290
           stop
295
           stop
291
        endif
296
        endif
292
        if ( abs( lon(i,j)-lon(i-1,j) ).gt.180. ) then
297
        if ( abs( lon(i,j)-lon(i-1,j) ).gt.180. ) then
293
           print*,' ERROR: mapping over date line not supported... Stop'
298
           print*,' ERROR: mapping over date line not supported... Stop'
294
           stop
299
           stop
295
        endif
300
        endif
296
      enddo
301
      enddo
297
      enddo
302
      enddo
298
 
303
 
299
c     Determine the extreme coordinates
304
c     Determine the extreme coordinates
300
      latmin  = lat(1,1)
305
      latmin  = lat(1,1)
301
      latmax  = lat(1,1)
306
      latmax  = lat(1,1)
302
      lonmin  = lon(1,1)
307
      lonmin  = lon(1,1)
303
      lonmax  = lon(1,1)
308
      lonmax  = lon(1,1)
304
      do i=1,nx
309
      do i=1,nx
305
	    do j=1,ny
310
	    do j=1,ny
306
          if ( lat(i,j).lt.latmin ) latmin = lat(i,j)
311
          if ( lat(i,j).lt.latmin ) latmin = lat(i,j)
307
          if ( lat(i,j).gt.latmax ) latmax = lat(i,j)
312
          if ( lat(i,j).gt.latmax ) latmax = lat(i,j)
308
          if ( lon(i,j).lt.lonmin ) lonmin = lon(i,j)
313
          if ( lon(i,j).lt.lonmin ) lonmin = lon(i,j)
309
          if ( lon(i,j).gt.lonmax ) lonmax = lon(i,j)
314
          if ( lon(i,j).gt.lonmax ) lonmax = lon(i,j)
310
        enddo
315
        enddo
311
      enddo
316
      enddo
312
 
317
 
313
      print*,' lonmin,max = ',lonmin,lonmax
318
      print*,' lonmin,max = ',lonmin,lonmax
314
      print*,' latmin,max = ',latmin,latmax
319
      print*,' latmin,max = ',latmin,latmax
315
 
320
 
316
c     Determine the extreme dlon/dlat spacing
321
c     Determine the extreme dlon/dlat spacing
317
      dlon = abs( lon(2,1)-lon(1,1) )
322
      dlon = abs( lon(2,1)-lon(1,1) )
318
      do i=2,nx
323
      do i=2,nx
319
	    do j=1,ny
324
	    do j=1,ny
320
           if ( abs( lon(i,j)-lon(i-1,j) ).lt.dlon ) then
325
           if ( abs( lon(i,j)-lon(i-1,j) ).lt.dlon ) then
321
              dlon = abs( lon(i,j)-lon(i-1,j) )
326
              dlon = abs( lon(i,j)-lon(i-1,j) )
322
           endif
327
           endif
323
         enddo
328
         enddo
324
      enddo
329
      enddo
325
      dlat = abs( lat(1,2)-lat(1,1) )
330
      dlat = abs( lat(1,2)-lat(1,1) )
326
      do i=1,nx
331
      do i=1,nx
327
	    do j=2,ny
332
	    do j=2,ny
328
           if ( abs( lat(i,j)-lat(i,j-1) ).lt.dlat ) then
333
           if ( abs( lat(i,j)-lat(i,j-1) ).lt.dlat ) then
329
              dlat = abs( lat(i,j)-lat(i,j-1) )
334
              dlat = abs( lat(i,j)-lat(i,j-1) )
330
           endif
335
           endif
331
         enddo
336
         enddo
332
      enddo
337
      enddo
333
 
338
 
334
c     Set dimension of geographical grid 
339
c     Set dimension of geographical grid 
335
      nlon   = ceiling( (lonmax-lonmin) / dlon + 1. )
340
      nlon   = ceiling( (lonmax-lonmin) / dlon + 1. )
336
      nlat   = ceiling( (latmax-latmin) / dlat + 1. )
341
      nlat   = ceiling( (latmax-latmin) / dlat + 1. )
337
      lonmax = lonmin + real(nlon-1) * dlon
342
      lonmax = lonmin + real(nlon-1) * dlon
338
      latmax = latmin + real(nlat-1) * dlat
343
      latmax = latmin + real(nlat-1) * dlat
339
 
344
 
340
      print*,' dlon,dlat  = ',dlon,dlat
345
      print*,' dlon,dlat  = ',dlon,dlat
341
      print*,' nlon,nlat  = ',nlon,nlat
346
      print*,' nlon,nlat  = ',nlon,nlat
342
 
347
 
343
c     Allocate memory for x/y on geographical grid
348
c     Allocate memory for x/y on geographical grid
344
      allocate(x(nlon,nlat),stat=stat)
349
      allocate(x(nlon,nlat),stat=stat)
345
      if (stat.ne.0) print*,'*** error allocating array x       ***'
350
      if (stat.ne.0) print*,'*** error allocating array x       ***'
346
      allocate(y(nlon,nlat),stat=stat)
351
      allocate(y(nlon,nlat),stat=stat)
347
      if (stat.ne.0) print*,'*** error allocating array y       ***'
352
      if (stat.ne.0) print*,'*** error allocating array y       ***'
348
      allocate(connect1(nlon,nlat),stat=stat)
353
      allocate(connect1(nlon,nlat),stat=stat)
349
      if (stat.ne.0) print*,'*** error allocating array connect1***'
354
      if (stat.ne.0) print*,'*** error allocating array connect1***'
350
      allocate(connect2(nlon,nlat),stat=stat)
355
      allocate(connect2(nlon,nlat),stat=stat)
351
      if (stat.ne.0) print*,'*** error allocating array connect2***'
356
      if (stat.ne.0) print*,'*** error allocating array connect2***'
352
      allocate(xc(nlon,nlat),stat=stat)
357
      allocate(xc(nlon,nlat),stat=stat)
353
      if (stat.ne.0) print*,'*** error allocating array xc      ***'
358
      if (stat.ne.0) print*,'*** error allocating array xc      ***'
354
      allocate(yc(nlon,nlat),stat=stat)
359
      allocate(yc(nlon,nlat),stat=stat)
355
      if (stat.ne.0) print*,'*** error allocating array yc      ***'
360
      if (stat.ne.0) print*,'*** error allocating array yc      ***'
356
 
361
 
357
c     Init the mapping arrays
362
c     Init the mapping arrays
358
      connectval1 = 0
363
      connectval1 = 0
359
      connectval2 = 0
364
      connectval2 = 0
360
      do i=1,nlon
365
      do i=1,nlon
361
	do j=1,nlat
366
	do j=1,nlat
362
           x(i,j)        = 0.
367
           x(i,j)        = 0.
363
           y(i,j)        = 0.
368
           y(i,j)        = 0.
364
           xc(i,j)       = 0.
369
           xc(i,j)       = 0.
365
           yc(i,j)       = 0.
370
           yc(i,j)       = 0.
366
           connect1(i,j) = 1
371
           connect1(i,j) = 1
367
           connect2(i,j) = 1
372
           connect2(i,j) = 1
368
        enddo
373
        enddo
369
      enddo
374
      enddo
370
 
375
 
371
c     Get the good radius for gridding - avoiding gaps
376
c     Get the good radius for gridding - avoiding gaps
372
      radunit = 'deg'
377
      radunit = 'deg'
373
      radius  = 0.
378
      radius  = 0.
374
      do i=2,nx
379
      do i=2,nx
375
        do j=2,ny
380
        do j=2,ny
376
           if ( abs( lat(i,j)-lat(i,j-1) ).gt.radius ) then
381
           if ( abs( lat(i,j)-lat(i,j-1) ).gt.radius ) then
377
              radius = abs( lat(i,j)-lat(i,j-1) )
382
              radius = abs( lat(i,j)-lat(i,j-1) )
378
           endif
383
           endif
379
           if ( abs( lon(i,j)-lon(i-1,j) ).gt.radius ) then
384
           if ( abs( lon(i,j)-lon(i-1,j) ).gt.radius ) then
380
              radius = abs( lon(i,j)-lon(i-1,j) )
385
              radius = abs( lon(i,j)-lon(i-1,j) )
381
           endif
386
           endif
382
        enddo
387
        enddo
383
      enddo
388
      enddo
384
      radius = 3. * radius 
389
      radius = 3. * radius 
385
 
390
 
386
c     Do the mapping
391
c     Do the mapping
387
      do i=1,nx
392
      do i=1,nx
388
	do j=1,ny
393
	do j=1,ny
389
 
394
 
390
          connectval1 = connectval1 + 1
395
          connectval1 = connectval1 + 1
391
          call gridding1(lat(i,j),lon(i,j),real(i),radius,radunit,
396
          call gridding1(lat(i,j),lon(i,j),real(i),radius,radunit,
392
     >                   connect1,connectval1,
397
     >                   connect1,connectval1,
393
     >                   x,xc,nlon,nlat,lonmin,latmin,dlon,dlat)
398
     >                   x,xc,nlon,nlat,lonmin,latmin,dlon,dlat)
394
 
399
 
395
          connectval2 = connectval2 + 1
400
          connectval2 = connectval2 + 1
396
          call gridding1(lat(i,j),lon(i,j),real(j),radius,radunit,
401
          call gridding1(lat(i,j),lon(i,j),real(j),radius,radunit,
397
     >                   connect2,connectval2,
402
     >                   connect2,connectval2,
398
     >                   y,yc,nlon,nlat,lonmin,latmin,dlon,dlat)
403
     >                   y,yc,nlon,nlat,lonmin,latmin,dlon,dlat)
399
 
404
 
400
 
405
 
401
	enddo
406
	enddo
402
      enddo
407
      enddo
403
 
408
 
404
c     Normalize output and set miising data flag
409
c     Normalize output and set miising data flag
405
      do i=1,nlon
410
      do i=1,nlon
406
         do j=1,nlat
411
         do j=1,nlat
407
            if ( xc(i,j).gt.0. ) then
412
            if ( xc(i,j).gt.0. ) then
408
               x(i,j) = x(i,j)/xc(i,j)
413
               x(i,j) = x(i,j)/xc(i,j)
409
            else
414
            else
410
               x(i,j) = mdv
415
               x(i,j) = mdv
411
            endif
416
            endif
412
            if ( yc(i,j).gt.0. ) then
417
            if ( yc(i,j).gt.0. ) then
413
               y(i,j) = y(i,j)/yc(i,j)
418
               y(i,j) = y(i,j)/yc(i,j)
414
            else
419
            else
415
               y(i,j) = mdv
420
               y(i,j) = mdv
416
            endif
421
            endif
417
         enddo
422
         enddo
418
      enddo
423
      enddo
419
 
424
 
420
c     Write data to netCDF
425
c     Write data to netCDF
421
      cdfname = mapfile
426
      cdfname = mapfile
422
      varname = 'X'
427
      varname = 'X'
423
      call writecdf2D(cdfname,varname,x,0.,
428
      call writecdf2D(cdfname,varname,x,0.,
424
     >                dlon,dlat,lonmin,latmin,nlon,nlat,1,1,1)
429
     >                dlon,dlat,lonmin,latmin,nlon,nlat,1,1,1)
425
 
430
 
426
      cdfname = mapfile
431
      cdfname = mapfile
427
      varname = 'Y'
432
      varname = 'Y'
428
      call writecdf2D(cdfname,varname,y,0.,
433
      call writecdf2D(cdfname,varname,y,0.,
429
     >                dlon,dlat,lonmin,latmin,nlon,nlat,1,0,1)
434
     >                dlon,dlat,lonmin,latmin,nlon,nlat,1,0,1)
430
 
435
 
431
      cdfname = mapfile
436
      cdfname = mapfile
432
      varname = 'LON'
437
      varname = 'LON'
433
      call writecdf2D(cdfname,varname,lon,0.,
438
      call writecdf2D(cdfname,varname,lon,0.,
434
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
439
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
435
 
440
 
436
      cdfname = mapfile
441
      cdfname = mapfile
437
      varname = 'LAT'
442
      varname = 'LAT'
438
      call writecdf2D(cdfname,varname,lat,0.,
443
      call writecdf2D(cdfname,varname,lat,0.,
439
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
444
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
440
 
445
 
441
      cdfname = mapfile
446
      cdfname = mapfile
442
      varname = 'Z'
447
      varname = 'Z'
443
      call writecdf2D(cdfname,varname,z3,0.,
448
      call writecdf2D(cdfname,varname,z3,0.,
444
     >                dx,dy,xmin,ymin,nx,ny,nz,0,1)
449
     >                dx,dy,xmin,ymin,nx,ny,nz,0,1)
445
 
450
 
446
      cdfname = mapfile
451
      cdfname = mapfile
447
      varname = 'P'
452
      varname = 'P'
448
      call writecdf2D(cdfname,varname,p3,0.,
453
      call writecdf2D(cdfname,varname,p3,0.,
449
     >                dx,dy,xmin,ymin,nx,ny,nz,0,1)
454
     >                dx,dy,xmin,ymin,nx,ny,nz,0,1)
450
 
455
 
451
      cdfname = mapfile
456
      cdfname = mapfile
452
      varname = 'TOPO'
457
      varname = 'TOPO'
453
      call writecdf2D(cdfname,varname,zb,0.,
458
      call writecdf2D(cdfname,varname,zb,0.,
454
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
459
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
455
 
460
 
456
 
461
 
457
      endif
462
      endif
458
 
463
 
459
 
464
 
460
c     ------------------------------------------------------------
465
c     ------------------------------------------------------------
461
c     Convert a lat/lon/z list to a x/y/z list
466
c     Convert a lat/lon/z list to a x/y/z list
462
c     ------------------------------------------------------------
467
c     ------------------------------------------------------------
463
 
468
 
464
      if ( mode.eq.'-ll2xy' ) then
469
      if ( mode.eq.'-ll2xy' ) then
465
 
470
 
466
c     Allocate memory for input and output lists
471
c     Allocate memory for input and output lists
467
      allocate(tra(ntra,ntim,ncol),stat=stat)
472
      allocate(tra(ntra,ntim,ncol),stat=stat)
468
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
473
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
469
      allocate(xx0(ntra*ntim),stat=stat)
474
      allocate(xx0(ntra*ntim),stat=stat)
470
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
475
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
471
      allocate(yy0(ntra*ntim),stat=stat)
476
      allocate(yy0(ntra*ntim),stat=stat)
472
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
477
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
473
      allocate(zz0(ntra*ntim),stat=stat)
478
      allocate(zz0(ntra*ntim),stat=stat)
474
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
479
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
475
 
480
 
476
c     Get format of input and output file
481
c     Get format of input and output file
477
      call mode_tra(inpmode,inpfile)
482
      call mode_tra(inpmode,inpfile)
478
      call mode_tra(outmode,outfile)
483
      call mode_tra(outmode,outfile)
479
      if ( outmode.eq.-1 ) outmode = 1
484
      if ( outmode.eq.-1 ) outmode = inpmode
480
 
485
 
481
c     Read coordinates from file - Format (lon,lat,lev)
486
c     Read coordinates from file - Format (lon,lat,lev)
482
      if (inpmode.eq.-1) then
487
      if (inpmode.eq.-1) then
483
         fid = 10
488
         fid = 10
484
         npoints = 0
489
         npoints = 0
485
         open(fid,file=inpfile)
490
         open(fid,file=inpfile)
486
          do i=1,ntra
491
          do i=1,ntra
487
             npoints = npoints + 1
492
             npoints = npoints + 1
488
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
493
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
489
          enddo
494
          enddo
490
         close(fid)
495
         close(fid)
491
 
496
 
492
c     Read coordinates from trajectory file 
497
c     Read coordinates from trajectory file 
493
      else
498
      else
494
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
499
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
495
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
500
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
496
         call close_tra(fid,inpmode)
501
         call close_tra(fid,inpmode)
497
 
502
 
498
         if ( (vars(2).ne.'lon').and.(vars(3).ne.'lat') ) then
503
         if ( (vars(2).ne.'lon').and.(vars(3).ne.'lat') ) then
499
            print*,' ERROR: input must be in lon/lat format... Stop'       
504
            print*,' ERROR: input must be in lon/lat format... Stop'       
500
            stop
505
            stop
501
         endif
506
         endif
502
 
507
 
503
         npoints = 0
508
         npoints = 0
504
         do i=1,ntra
509
         do i=1,ntra
505
            do j=1,ntim
510
            do j=1,ntim
506
               npoints = npoints + 1
511
               npoints = npoints + 1
507
               xx0(npoints) = tra(i,j,2) 
512
               xx0(npoints) = tra(i,j,2) 
508
               yy0(npoints) = tra(i,j,3) 
513
               yy0(npoints) = tra(i,j,3) 
509
               zz0(npoints) = tra(i,j,4) 
514
               zz0(npoints) = tra(i,j,4) 
510
            enddo
515
            enddo
511
         enddo
516
         enddo
512
      endif 
517
      endif 
513
 
518
 
514
c     Transform coordinates
519
c     Transform coordinates
515
      do i=1,npoints
520
      do i=1,npoints
516
 
521
 
517
          rid=(xx0(i)-lonmin)/dlon+1.
522
          rid=(xx0(i)-lonmin)/dlon+1.
518
          rjd=(yy0(i)-latmin)/dlat+1.
523
          rjd=(yy0(i)-latmin)/dlat+1.
519
 
524
 
520
          xx0(i) = int_index3(x,nlon,nlat,1,rid,rjd,1.,mdv)
525
          xx0(i) = int_index3(x,nlon,nlat,1,rid,rjd,1.,mdv)
521
          yy0(i) = int_index3(y,nlon,nlat,1,rid,rjd,1.,mdv)
526
          yy0(i) = int_index3(y,nlon,nlat,1,rid,rjd,1.,mdv)
522
 
527
 
523
      enddo
528
      enddo
524
 
529
 
525
c     Write output to list
530
c     Write output to list
526
      if ( outmode.eq.-1 ) then
531
      if ( outmode.eq.-1 ) then
527
         fid = 10
532
         fid = 10
528
         open(fid,file=outfile)
533
         open(fid,file=outfile)
529
         do i=1,ntra
534
         do i=1,ntra
530
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
535
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
531
         enddo
536
         enddo
532
         close(fid)
537
         close(fid)
533
 
538
 
534
c     Write output to trajectory
539
c     Write output to trajectory
535
      else         
540
      else         
536
         npoints = 0
541
         npoints = 0
537
         do i=1,ntra
542
         do i=1,ntra
538
            do j=1,ntim
543
            do j=1,ntim
539
               npoints = npoints + 1
544
               npoints = npoints + 1
540
               tra(i,j,2) = xx0(npoints)
545
               tra(i,j,2) = xx0(npoints)
541
               tra(i,j,3) = yy0(npoints)
546
               tra(i,j,3) = yy0(npoints)
542
               tra(i,j,4) = zz0(npoints)
547
               tra(i,j,4) = zz0(npoints)
543
            enddo
548
            enddo
544
         enddo
549
         enddo
545
         if ( ncol.eq.3 ) ncol = 4
550
         if ( ncol.eq.3 ) ncol = 4
546
         vars(1) = 'time'
551
         vars(1) = 'time'
547
         vars(2) = 'x'
552
         vars(2) = 'x'
548
         vars(3) = 'y'
553
         vars(3) = 'y'
549
         vars(4) = 'z'
554
         vars(4) = 'z'
550
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
555
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
551
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
556
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
552
         call close_tra(fid,outmode)
557
         call close_tra(fid,outmode)
553
      endif
558
      endif
554
 
559
 
555
      endif
560
      endif
556
 
561
 
557
c     ------------------------------------------------------------
562
c     ------------------------------------------------------------
558
c     Convert a x/y/z list to a lon/lat/z list
563
c     Convert a x/y/z list to a lon/lat/z list
559
c     ------------------------------------------------------------
564
c     ------------------------------------------------------------
560
 
565
 
561
      if ( mode.eq.'-xy2ll' ) then
566
      if ( mode.eq.'-xy2ll' ) then
562
 
567
 
563
c     Allocate memory for input and output lists
568
c     Allocate memory for input and output lists
564
      allocate(tra(ntra,ntim,ncol),stat=stat)
569
      allocate(tra(ntra,ntim,ncol),stat=stat)
565
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
570
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
566
      allocate(xx0(ntra*ntim),stat=stat)
571
      allocate(xx0(ntra*ntim),stat=stat)
567
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
572
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
568
      allocate(yy0(ntra*ntim),stat=stat)
573
      allocate(yy0(ntra*ntim),stat=stat)
569
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
574
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
570
      allocate(zz0(ntra*ntim),stat=stat)
575
      allocate(zz0(ntra*ntim),stat=stat)
571
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
576
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
572
 
577
 
573
c     Get format of input and output file
578
c     Get format of input and output file
574
      call mode_tra(inpmode,inpfile)
579
      call mode_tra(inpmode,inpfile)
575
      call mode_tra(outmode,outfile)
580
      call mode_tra(outmode,outfile)
576
      if ( outmode.eq.-1) outmode=1
581
      if ( outmode.eq.-1) outmode=inpmode
577
 
582
 
578
c     Read coordinates from file - Format (x,y,lev)
583
c     Read coordinates from file - Format (x,y,lev)
579
      if (inpmode.eq.-1) then
584
      if (inpmode.eq.-1) then
580
         fid = 10
585
         fid = 10
581
         npoints = 0
586
         npoints = 0
582
         open(fid,file=inpfile)
587
         open(fid,file=inpfile)
583
          do i=1,ntra
588
          do i=1,ntra
584
             npoints = npoints + 1
589
             npoints = npoints + 1
585
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
590
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
586
          enddo
591
          enddo
587
         close(fid)
592
         close(fid)
588
 
593
 
589
c     Read coordinates from trajectory file 
594
c     Read coordinates from trajectory file 
590
      else
595
      else
591
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
596
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
592
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
597
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
593
         call close_tra(fid,inpmode)
598
         call close_tra(fid,inpmode)
594
 
599
 
595
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
600
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
596
            print*,' ERROR: input must be in x/y format... Stop'       
601
            print*,' ERROR: input must be in x/y format... Stop'       
597
            stop
602
            stop
598
         endif
603
         endif
599
 
604
 
600
         npoints = 0
605
         npoints = 0
601
         do i=1,ntra
606
         do i=1,ntra
602
            do j=1,ntim
607
            do j=1,ntim
603
               npoints = npoints + 1
608
               npoints = npoints + 1
604
               xx0(npoints) = tra(i,j,2) 
609
               xx0(npoints) = tra(i,j,2) 
605
               yy0(npoints) = tra(i,j,3) 
610
               yy0(npoints) = tra(i,j,3) 
606
               zz0(npoints) = tra(i,j,4) 
611
               zz0(npoints) = tra(i,j,4) 
607
            enddo
612
            enddo
608
         enddo
613
         enddo
609
      endif 
614
      endif 
610
 
615
 
611
c     Transform coordinates
616
c     Transform coordinates
612
      do i=1,npoints
617
      do i=1,npoints
613
 
618
 
614
          rid=(xx0(i)-xmin)/dx+1.
619
          rid=(xx0(i)-xmin)/dx+1.
615
          rjd=(yy0(i)-ymin)/dy+1.
620
          rjd=(yy0(i)-ymin)/dy+1.
616
 
621
 
617
          xx0(i) = int_index3(lon,nx,ny,1,rid,rjd,1.,mdv)
622
          xx0(i) = int_index3(lon,nx,ny,1,rid,rjd,1.,mdv)
618
          yy0(i) = int_index3(lat,nx,ny,1,rid,rjd,1.,mdv)
623
          yy0(i) = int_index3(lat,nx,ny,1,rid,rjd,1.,mdv)
619
 
624
 
620
      enddo
625
      enddo
621
 
626
 
622
c     Write output to list
627
c     Write output to list
623
      if ( outmode.eq.-1 ) then
628
      if ( outmode.eq.-1 ) then
624
         fid = 10
629
         fid = 10
625
         open(fid,file=outfile)
630
         open(fid,file=outfile)
626
         do i=1,ntra
631
         do i=1,ntra
627
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
632
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
628
         enddo
633
         enddo
629
         close(fid)
634
         close(fid)
630
 
635
 
631
c     Write output to trajectory
636
c     Write output to trajectory
632
      else         
637
      else         
633
         npoints = 0
638
         npoints = 0
634
         do i=1,ntra
639
         do i=1,ntra
635
            do j=1,ntim
640
            do j=1,ntim
636
               npoints = npoints + 1
641
               npoints = npoints + 1
637
               tra(i,j,2) = xx0(npoints)
642
               tra(i,j,2) = xx0(npoints)
638
               tra(i,j,3) = yy0(npoints)
643
               tra(i,j,3) = yy0(npoints)
639
               tra(i,j,4) = zz0(npoints)
644
               tra(i,j,4) = zz0(npoints)
640
            enddo
645
            enddo
641
         enddo
646
         enddo
642
         if ( ncol.eq.3 ) ncol = 4
647
         if ( ncol.eq.3 ) ncol = 4
643
         vars(1) = 'time'
648
         vars(1) = 'time'
644
         vars(2) = 'lon'
649
         vars(2) = 'lon'
645
         vars(3) = 'lat'
650
         vars(3) = 'lat'
646
         vars(4) = 'z'
651
         vars(4) = 'z'
647
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
652
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
648
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
653
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
649
         call close_tra(fid,outmode)
654
         call close_tra(fid,outmode)
650
      endif
655
      endif
651
 
656
 
652
      endif
657
      endif
653
 
658
 
654
c     ------------------------------------------------------------
659
c     ------------------------------------------------------------
655
c     Convert a single lat/lon/z list to a x/y/z list
660
c     Convert a single lat/lon/z list to a x/y/z list
656
c     ------------------------------------------------------------
661
c     ------------------------------------------------------------
657
 
662
 
658
      if ( mode.eq.'-ll2xy.single' ) then
663
      if ( mode.eq.'-ll2xy.single' ) then
659
 
664
 
660
c     Transform coordinates
665
c     Transform coordinates
661
      rid  = (lonpos-lonmin)/dlon+1.
666
      rid  = (lonpos-lonmin)/dlon+1.
662
      rjd  = (latpos-latmin)/dlat+1.
667
      rjd  = (latpos-latmin)/dlat+1.
663
      xpos = int_index3(x,nlon,nlat,1,rid,rjd,1.,mdv)
668
      xpos = int_index3(x,nlon,nlat,1,rid,rjd,1.,mdv)
664
      ypos = int_index3(y,nlon,nlat,1,rid,rjd,1.,mdv)
669
      ypos = int_index3(y,nlon,nlat,1,rid,rjd,1.,mdv)
665
 
670
 
666
c	  Write result to screen
671
c	  Write result to screen
667
      print*,xpos,ypos
672
      print*,xpos,ypos
668
 
673
 
669
      endif
674
      endif
670
 
675
 
671
c     ------------------------------------------------------------
676
c     ------------------------------------------------------------
672
c     Convert a single x/y/z list to a lon/lat/z list
677
c     Convert a single x/y/z list to a lon/lat/z list
673
c     ------------------------------------------------------------
678
c     ------------------------------------------------------------
674
 
679
 
675
      if ( mode.eq.'-xy2ll.single' ) then
680
      if ( mode.eq.'-xy2ll.single' ) then
676
 
681
 
677
c     Transform coordinates
682
c     Transform coordinates
678
      rid    = (xpos-xmin)/dx+1.
683
      rid    = (xpos-xmin)/dx+1.
679
      rjd    = (ypos-ymin)/dy+1.
684
      rjd    = (ypos-ymin)/dy+1.
680
      lonpos = int_index3(lon,nx,ny,1,rid,rjd,1.,mdv)
685
      lonpos = int_index3(lon,nx,ny,1,rid,rjd,1.,mdv)
681
      latpos = int_index3(lat,nx,ny,1,rid,rjd,1.,mdv)
686
      latpos = int_index3(lat,nx,ny,1,rid,rjd,1.,mdv)
682
 
687
 
683
c	  Write result to screen
688
c	  Write result to screen
684
      print*,lonpos,latpos
689
      print*,lonpos,latpos
685
 
690
 
686
      endif
691
      endif
687
 
692
 
688
c     ------------------------------------------------------------
693
c     ------------------------------------------------------------
689
c     Calculate numerically the maps scale factor
694
c     Calculate numerically the maps scale factor
690
c     ------------------------------------------------------------
695
c     ------------------------------------------------------------
691
 
696
 
692
      if ( mode.eq.'-mapscale' ) then
697
      if ( mode.eq.'-mapscale' ) then
693
 
698
 
694
c	  Allocate memory for map scale factors
699
c	  Allocate memory for map scale factors
695
      allocate(mpx(nx,ny),stat=stat)
700
      allocate(mpx(nx,ny),stat=stat)
696
      if (stat.ne.0) print*,'*** error allocating array mpx       ***'
701
      if (stat.ne.0) print*,'*** error allocating array mpx       ***'
697
      allocate(mpy(nx,ny),stat=stat)
702
      allocate(mpy(nx,ny),stat=stat)
698
      if (stat.ne.0) print*,'*** error allocating array mpy       ***'
703
      if (stat.ne.0) print*,'*** error allocating array mpy       ***'
699
 
704
 
700
c     Get map scale for interior points
705
c     Get map scale for interior points
701
      do i=2,nx-1
706
      do i=2,nx-1
702
         do j=2,ny-1
707
         do j=2,ny-1
703
 
708
 
704
c           Map scale in x direction
709
c           Map scale in x direction
705
            lon1     = lon(i-1,j)
710
            lon1     = lon(i-1,j)
706
            lat1     = lat(i-1,j)
711
            lat1     = lat(i-1,j)
707
            lon2     = lon(i+1,j)
712
            lon2     = lon(i+1,j)
708
            lat2     = lat(i+1,j)
713
            lat2     = lat(i+1,j)
709
            radunit  = 'km.haversine'
714
            radunit  = 'km.haversine'
710
            mpx(i,j) = 0.5 * 1000. * sdis(lon1,lat1,lon2,lat2,radunit)
715
            mpx(i,j) = 0.5 * 1000. * sdis(lon1,lat1,lon2,lat2,radunit)
711
 
716
 
712
c           Map scale in y direction
717
c           Map scale in y direction
713
            lon1     = lon(i,j-1)
718
            lon1     = lon(i,j-1)
714
            lat1     = lat(i,j-1)
719
            lat1     = lat(i,j-1)
715
            lon2     = lon(i,j+1)
720
            lon2     = lon(i,j+1)
716
            lat2     = lat(i,j+1)
721
            lat2     = lat(i,j+1)
717
            radunit  = 'km.haversine'
722
            radunit  = 'km.haversine'
718
            mpy(i,j) = 0.5 * 1000. * sdis(lon1,lat1,lon2,lat2,radunit)
723
            mpy(i,j) = 0.5 * 1000. * sdis(lon1,lat1,lon2,lat2,radunit)
719
 
724
 
720
         enddo
725
         enddo
721
      enddo
726
      enddo
722
 
727
 
723
c     Copy map scale for boundary line points
728
c     Copy map scale for boundary line points
724
      do i=2,nx-1
729
      do i=2,nx-1
725
        mpx(i, 1) = mpx(i,   2)
730
        mpx(i, 1) = mpx(i,   2)
726
        mpx(i,ny) = mpx(i,ny-1)
731
        mpx(i,ny) = mpx(i,ny-1)
727
        mpy(i, 1) = mpy(i,   2)
732
        mpy(i, 1) = mpy(i,   2)
728
        mpy(i,ny) = mpy(i,ny-1)
733
        mpy(i,ny) = mpy(i,ny-1)
729
      enddo
734
      enddo
730
      do j=2,ny-1
735
      do j=2,ny-1
731
        mpx(1, j) = mpx(2,   j)
736
        mpx(1, j) = mpx(2,   j)
732
        mpx(nx,j) = mpx(nx-1,j)
737
        mpx(nx,j) = mpx(nx-1,j)
733
        mpy(1, j) = mpy(2,   j)
738
        mpy(1, j) = mpy(2,   j)
734
        mpy(nx,j) = mpy(nx-1,j)
739
        mpy(nx,j) = mpy(nx-1,j)
735
      enddo
740
      enddo
736
 
741
 
737
c     Copy map scale factor for boundary corner points
742
c     Copy map scale factor for boundary corner points
738
      mpx( 1, 1) = mpx(   2,   2)
743
      mpx( 1, 1) = mpx(   2,   2)
739
      mpy( 1, 1) = mpy(   2,   2)
744
      mpy( 1, 1) = mpy(   2,   2)
740
      mpx(nx, 1) = mpx(nx-1,   2)
745
      mpx(nx, 1) = mpx(nx-1,   2)
741
      mpy(nx, 1) = mpy(nx-1,   2)
746
      mpy(nx, 1) = mpy(nx-1,   2)
742
      mpx(nx,ny) = mpx(nx-1,ny-1)
747
      mpx(nx,ny) = mpx(nx-1,ny-1)
743
      mpy(nx,ny) = mpy(nx-1,ny-1)
748
      mpy(nx,ny) = mpy(nx-1,ny-1)
744
      mpx( 1,ny) = mpx(   2,ny-1)
749
      mpx( 1,ny) = mpx(   2,ny-1)
745
      mpy( 1,ny) = mpy(   2,ny-1)
750
      mpy( 1,ny) = mpy(   2,ny-1)
746
 
751
 
-
 
752
c     Apply a diffuive filter
-
 
753
      do i=1,nfilter
-
 
754
         call filt2d (mpx,mpx,nx,ny,1.0,-999.,0,0,0,0)
-
 
755
         call filt2d (mpy,mpy,nx,ny,1.0,-999.,0,0,0,0)
-
 
756
      enddo
-
 
757
 
747
c     Write map factors to mapping file
758
c     Write map factors to mapping file
748
      cdfname = mapfile
759
      cdfname = mapfile
749
      varname = 'MAPSCALE_X'
760
      varname = 'MAPSCALE_X'
750
      call writecdf2D(cdfname,varname,mpx,0.,
761
      call writecdf2D(cdfname,varname,mpx,0.,
751
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
762
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
752
      cdfname = mapfile
763
      cdfname = mapfile
753
      varname = 'MAPSCALE_Y'
764
      varname = 'MAPSCALE_Y'
754
      call writecdf2D(cdfname,varname,mpy,0.,
765
      call writecdf2D(cdfname,varname,mpy,0.,
755
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
766
     >                dx,dy,xmin,ymin,nx,ny,1,0,1)
756
 
767
 
757
 
768
 
758
      endif
769
      endif
759
 
770
 
760
c     ------------------------------------------------------------
771
c     ------------------------------------------------------------
761
c     Convert from pressure to height
772
c     Convert from pressure to height
762
c     ------------------------------------------------------------
773
c     ------------------------------------------------------------
763
 
774
 
764
      if ( mode.eq.'-p2z' ) then
775
      if ( mode.eq.'-p2z' ) then
765
 
776
 
766
c     Allocate memory for input and output lists
777
c     Allocate memory for input and output lists
767
      allocate(tra(ntra,ntim,ncol),stat=stat)
778
      allocate(tra(ntra,ntim,ncol),stat=stat)
768
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
779
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
769
      allocate(xx0(ntra*ntim),stat=stat)
780
      allocate(xx0(ntra*ntim),stat=stat)
770
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
781
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
771
      allocate(yy0(ntra*ntim),stat=stat)
782
      allocate(yy0(ntra*ntim),stat=stat)
772
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
783
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
773
      allocate(zz0(ntra*ntim),stat=stat)
784
      allocate(zz0(ntra*ntim),stat=stat)
774
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
785
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
775
 
786
 
776
c     Get format of input and output file
787
c     Get format of input and output file
777
      call mode_tra(inpmode,inpfile)
788
      call mode_tra(inpmode,inpfile)
778
      call mode_tra(outmode,outfile)
789
      call mode_tra(outmode,outfile)
779
      if ( outmode.eq.-1) outmode=1
790
      if ( outmode.eq.-1) outmode=inpmode
780
 
791
 
781
c     Read coordinates from file - Format (x,y,lev)
792
c     Read coordinates from file - Format (x,y,lev)
782
      if (inpmode.eq.-1) then
793
      if (inpmode.eq.-1) then
783
         fid = 10
794
         fid = 10
784
         npoints = 0
795
         npoints = 0
785
         open(fid,file=inpfile)
796
         open(fid,file=inpfile)
786
          do i=1,ntra
797
          do i=1,ntra
787
             npoints = npoints + 1
798
             npoints = npoints + 1
788
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
799
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
789
          enddo
800
          enddo
790
         close(fid)
801
         close(fid)
791
 
802
 
792
c     Read coordinates from trajectory file
803
c     Read coordinates from trajectory file
793
      else
804
      else
794
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
805
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
795
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
806
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
796
         call close_tra(fid,inpmode)
807
         call close_tra(fid,inpmode)
797
 
808
 
798
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
809
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
799
            print*,' ERROR: input must be in x/y format... Stop'
810
            print*,' ERROR: input must be in x/y format... Stop'
800
            stop
811
            stop
801
         endif
812
         endif
802
 
813
 
803
         npoints = 0
814
         npoints = 0
804
         do i=1,ntra
815
         do i=1,ntra
805
            do j=1,ntim
816
            do j=1,ntim
806
               npoints = npoints + 1
817
               npoints = npoints + 1
807
               xx0(npoints) = tra(i,j,2)
818
               xx0(npoints) = tra(i,j,2)
808
               yy0(npoints) = tra(i,j,3)
819
               yy0(npoints) = tra(i,j,3)
809
               zz0(npoints) = tra(i,j,4)
820
               zz0(npoints) = tra(i,j,4)
810
            enddo
821
            enddo
811
         enddo
822
         enddo
812
      endif
823
      endif
813
 
824
 
814
c     Transform coordinates
825
c     Transform coordinates
815
      do i=1,npoints
826
      do i=1,npoints
816
 
827
 
817
          call get_index3 (rid,rjd,rkd,xx0(i),yy0(i),-zz0(i),1,
828
          call get_index3 (rid,rjd,rkd,xx0(i),yy0(i),-zz0(i),1,
818
     >                     -p3,-ps,nx,ny,nz,xmin,ymin,dx,dy)
829
     >                     -p3,-ps,nx,ny,nz,xmin,ymin,dx,dy)
819
 
830
 
820
          zz0(i) = int_index3(z3,nx,ny,nz,rid,rjd,rkd,mdv)
831
          zz0(i) = int_index3(z3,nx,ny,nz,rid,rjd,rkd,mdv)
821
 
832
 
822
      enddo
833
      enddo
823
 
834
 
824
c     Write output to list
835
c     Write output to list
825
      if ( outmode.eq.-1 ) then
836
      if ( outmode.eq.-1 ) then
826
         fid = 10
837
         fid = 10
827
         open(fid,file=outfile)
838
         open(fid,file=outfile)
828
         do i=1,ntra
839
         do i=1,ntra
829
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
840
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
830
         enddo
841
         enddo
831
         close(fid)
842
         close(fid)
832
 
843
 
833
c     Write output to trajectory
844
c     Write output to trajectory
834
      else
845
      else
835
         npoints = 0
846
         npoints = 0
836
         do i=1,ntra
847
         do i=1,ntra
837
            do j=1,ntim
848
            do j=1,ntim
838
               npoints = npoints + 1
849
               npoints = npoints + 1
839
               tra(i,j,2) = xx0(npoints)
850
               tra(i,j,2) = xx0(npoints)
840
               tra(i,j,3) = yy0(npoints)
851
               tra(i,j,3) = yy0(npoints)
841
               tra(i,j,4) = zz0(npoints)
852
               tra(i,j,4) = zz0(npoints)
842
            enddo
853
            enddo
843
         enddo
854
         enddo
844
         if ( ncol.eq.3 ) ncol = 4
855
         if ( ncol.eq.3 ) ncol = 4
845
         vars(1) = 'time'
856
         vars(1) = 'time'
846
         vars(2) = 'x'
857
         vars(2) = 'x'
847
         vars(3) = 'y'
858
         vars(3) = 'y'
848
         vars(4) = 'z'
859
         vars(4) = 'z'
849
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
860
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
850
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
861
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
851
         call close_tra(fid,outmode)
862
         call close_tra(fid,outmode)
852
      endif
863
      endif
853
 
864
 
854
      endif
865
      endif
855
 
866
 
856
c     ------------------------------------------------------------
867
c     ------------------------------------------------------------
857
c     Convert single x/y/p to x/y/z
868
c     Convert single x/y/p to x/y/z
858
c     ------------------------------------------------------------
869
c     ------------------------------------------------------------
859
 
870
 
860
      if ( mode.eq.'-p2z.single' ) then
871
      if ( mode.eq.'-p2z.single' ) then
861
 
872
 
862
c     Transform coordinates - change from descending to ascending (minus sign)
873
c     Transform coordinates - change from descending to ascending (minus sign)
863
      call get_index3 (rid,rjd,rkd,xpos,ypos,-ppos,1,
874
      call get_index3 (rid,rjd,rkd,xpos,ypos,-ppos,1,
864
     >                 -p3,-ps,nx,ny,nz,xmin,ymin,dx,dy)
875
     >                 -p3,-ps,nx,ny,nz,xmin,ymin,dx,dy)
865
 
876
 
866
      zpos = int_index3(z3,nx,ny,nz,rid,rjd,rkd,mdv)
877
      zpos = int_index3(z3,nx,ny,nz,rid,rjd,rkd,mdv)
867
 
878
 
868
c	  Write result to screen
879
c	  Write result to screen
869
      print*,xpos,ypos,zpos
880
      print*,xpos,ypos,zpos
870
 
881
 
871
      endif
882
      endif
872
 
883
 
873
c     ------------------------------------------------------------
884
c     ------------------------------------------------------------
874
c     Convert from height to pressure
885
c     Convert from height to pressure
875
c     ------------------------------------------------------------
886
c     ------------------------------------------------------------
876
 
887
 
877
      if ( mode.eq.'-z2p' ) then
888
      if ( mode.eq.'-z2p' ) then
878
 
889
 
879
c     Allocate memory for input and output lists
890
c     Allocate memory for input and output lists
880
      allocate(tra(ntra,ntim,ncol),stat=stat)
891
      allocate(tra(ntra,ntim,ncol),stat=stat)
881
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
892
      if (stat.ne.0) print*,'*** error allocating array tra         ***'
882
      allocate(xx0(ntra*ntim),stat=stat)
893
      allocate(xx0(ntra*ntim),stat=stat)
883
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
894
      if (stat.ne.0) print*,'*** error allocating array xx0         ***'
884
      allocate(yy0(ntra*ntim),stat=stat)
895
      allocate(yy0(ntra*ntim),stat=stat)
885
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
896
      if (stat.ne.0) print*,'*** error allocating array yy0         ***'
886
      allocate(zz0(ntra*ntim),stat=stat)
897
      allocate(zz0(ntra*ntim),stat=stat)
887
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
898
      if (stat.ne.0) print*,'*** error allocating array zz0         ***'
888
 
899
 
889
c     Get format of input and output file
900
c     Get format of input and output file
890
      call mode_tra(inpmode,inpfile)
901
      call mode_tra(inpmode,inpfile)
891
      call mode_tra(outmode,outfile)
902
      call mode_tra(outmode,outfile)
892
      if ( outmode.eq.-1) outmode=1
903
      if ( outmode.eq.-1) outmode=inpmode
893
 
904
 
894
c     Read coordinates from file - Format (x,y,lev)
905
c     Read coordinates from file - Format (x,y,lev)
895
      if (inpmode.eq.-1) then
906
      if (inpmode.eq.-1) then
896
         fid = 10
907
         fid = 10
897
         npoints = 0
908
         npoints = 0
898
         open(fid,file=inpfile)
909
         open(fid,file=inpfile)
899
          do i=1,ntra
910
          do i=1,ntra
900
             npoints = npoints + 1
911
             npoints = npoints + 1
901
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
912
             read(fid,*) xx0(npoints),yy0(npoints),zz0(npoints)
902
          enddo
913
          enddo
903
         close(fid)
914
         close(fid)
904
 
915
 
905
c     Read coordinates from trajectory file
916
c     Read coordinates from trajectory file
906
      else
917
      else
907
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
918
         call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode)
908
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
919
         call read_tra (fid,tra,ntra,ntim,ncol,inpmode)
909
         call close_tra(fid,inpmode)
920
         call close_tra(fid,inpmode)
910
 
921
 
911
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
922
         if ( (vars(2).ne.'x').and.(vars(3).ne.'y') ) then
912
            print*,' ERROR: input must be in x/y format... Stop'
923
            print*,' ERROR: input must be in x/y format... Stop'
913
            stop
924
            stop
914
         endif
925
         endif
915
 
926
 
916
         npoints = 0
927
         npoints = 0
917
         do i=1,ntra
928
         do i=1,ntra
918
            do j=1,ntim
929
            do j=1,ntim
919
               npoints = npoints + 1
930
               npoints = npoints + 1
920
               xx0(npoints) = tra(i,j,2)
931
               xx0(npoints) = tra(i,j,2)
921
               yy0(npoints) = tra(i,j,3)
932
               yy0(npoints) = tra(i,j,3)
922
               zz0(npoints) = tra(i,j,4)
933
               zz0(npoints) = tra(i,j,4)
923
            enddo
934
            enddo
924
         enddo
935
         enddo
925
      endif
936
      endif
926
 
937
 
927
c     Transform coordinates
938
c     Transform coordinates
928
      do i=1,npoints
939
      do i=1,npoints
929
 
940
 
930
          call get_index3 (rid,rjd,rkd,xx0(i),yy0(i),zz0(i),1,
941
          call get_index3 (rid,rjd,rkd,xx0(i),yy0(i),zz0(i),1,
931
     >                     z3,zb,nx,ny,nz,xmin,ymin,dx,dy)
942
     >                     z3,zb,nx,ny,nz,xmin,ymin,dx,dy)
932
 
943
 
933
          zz0(i) = int_index3(p3,nx,ny,nz,rid,rjd,rkd,mdv)
944
          zz0(i) = int_index3(p3,nx,ny,nz,rid,rjd,rkd,mdv)
934
 
945
 
935
      enddo
946
      enddo
936
 
947
 
937
c     Write output to list
948
c     Write output to list
938
      if ( outmode.eq.-1 ) then
949
      if ( outmode.eq.-1 ) then
939
         fid = 10
950
         fid = 10
940
         open(fid,file=outfile)
951
         open(fid,file=outfile)
941
         do i=1,ntra
952
         do i=1,ntra
942
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
953
            write(fid,'(f9.2,f8.2,i6)') xx0(i),yy0(i),nint(zz0(i))
943
         enddo
954
         enddo
944
         close(fid)
955
         close(fid)
945
 
956
 
946
c     Write output to trajectory
957
c     Write output to trajectory
947
      else
958
      else
948
         npoints = 0
959
         npoints = 0
949
         do i=1,ntra
960
         do i=1,ntra
950
            do j=1,ntim
961
            do j=1,ntim
951
               npoints = npoints + 1
962
               npoints = npoints + 1
952
               tra(i,j,2) = xx0(npoints)
963
               tra(i,j,2) = xx0(npoints)
953
               tra(i,j,3) = yy0(npoints)
964
               tra(i,j,3) = yy0(npoints)
954
               tra(i,j,4) = zz0(npoints)
965
               tra(i,j,4) = zz0(npoints)
955
            enddo
966
            enddo
956
         enddo
967
         enddo
957
         if ( ncol.eq.3 ) ncol = 4
968
         if ( ncol.eq.3 ) ncol = 4
958
         vars(1) = 'time'
969
         vars(1) = 'time'
959
         vars(2) = 'x'
970
         vars(2) = 'x'
960
         vars(3) = 'y'
971
         vars(3) = 'y'
961
         vars(4) = 'p'
972
         vars(4) = 'p'
962
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
973
         call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
963
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
974
         call write_tra(fid,tra,ntra,ntim,ncol,outmode)
964
         call close_tra(fid,outmode)
975
         call close_tra(fid,outmode)
965
      endif
976
      endif
966
 
977
 
967
      endif
978
      endif
968
 
979
 
969
c     ------------------------------------------------------------
980
c     ------------------------------------------------------------
970
c     Convert single x/y/z to x/y/p
981
c     Convert single x/y/z to x/y/p
971
c     ------------------------------------------------------------
982
c     ------------------------------------------------------------
972
 
983
 
973
      if ( mode.eq.'-z2p.single' ) then
984
      if ( mode.eq.'-z2p.single' ) then
974
 
985
 
975
c     Transform coordinates - change from descending to ascending (minus sign)
986
c     Transform coordinates - change from descending to ascending (minus sign)
976
      call get_index3 (rid,rjd,rkd,xpos,ypos,zpos,1,
987
      call get_index3 (rid,rjd,rkd,xpos,ypos,zpos,1,
977
     >                 z3,zb,nx,ny,nz,xmin,ymin,dx,dy)
988
     >                 z3,zb,nx,ny,nz,xmin,ymin,dx,dy)
978
 
989
 
979
      ppos = int_index3(p3,nx,ny,nz,rid,rjd,rkd,mdv)
990
      ppos = int_index3(p3,nx,ny,nz,rid,rjd,rkd,mdv)
980
 
991
 
981
c	  Write result to screen
992
c	  Write result to screen
982
      print*,xpos,ypos,ppos
993
      print*,xpos,ypos,ppos
983
 
994
 
984
      endif
995
      endif
985
 
996
 
986
      end
997
      end
987
 
998
 
988
 
999
 
989
c     ********************************************************************
1000
c     ********************************************************************
990
c     * GRIDDING SUBROUTINES                                             *
1001
c     * GRIDDING SUBROUTINES                                             *
991
c     ********************************************************************
1002
c     ********************************************************************
992
 
1003
 
993
c     ---------------------------------------------------------------------
1004
c     ---------------------------------------------------------------------
994
c     Gridding of one single data point (smoothing in km, deg, gridp)
1005
c     Gridding of one single data point (smoothing in km, deg, gridp)
995
c     ---------------------------------------------------------------------
1006
c     ---------------------------------------------------------------------
996
 
1007
 
997
      subroutine gridding1 (lat,lon,addval,radius,unit,
1008
      subroutine gridding1 (lat,lon,addval,radius,unit,
998
     >                      connect,connectval,
1009
     >                      connect,connectval,
999
     >                      out,outc,nx,ny,xmin,ymin,dx,dy)
1010
     >                      out,outc,nx,ny,xmin,ymin,dx,dy)
1000
 
1011
 
1001
      implicit none
1012
      implicit none
1002
 
1013
 
1003
c     Declaration of subroutine parameters
1014
c     Declaration of subroutine parameters
1004
      real         lat,lon
1015
      real         lat,lon
1005
      integer      nx,ny
1016
      integer      nx,ny
1006
      real         xmin,ymin,dx,dy
1017
      real         xmin,ymin,dx,dy
1007
      real         out(nx,ny),outc(nx,ny)
1018
      real         out(nx,ny),outc(nx,ny)
1008
      real         radius
1019
      real         radius
1009
      character*80 unit
1020
      character*80 unit
1010
      integer      connectval
1021
      integer      connectval
1011
      integer      connect(nx,ny)
1022
      integer      connect(nx,ny)
1012
      real         addval
1023
      real         addval
1013
 
1024
 
1014
c     Auxiliary variables
1025
c     Auxiliary variables
1015
      integer   i,j,k
1026
      integer   i,j,k
1016
      integer   mu,md,nr,nl,n,m
1027
      integer   mu,md,nr,nl,n,m
1017
      integer   stackx(nx*ny),stacky(nx*ny)
1028
      integer   stackx(nx*ny),stacky(nx*ny)
1018
      integer   tab_x(nx*ny),tab_y(nx*ny)
1029
      integer   tab_x(nx*ny),tab_y(nx*ny)
1019
      real      tab_r(nx*ny)
1030
      real      tab_r(nx*ny)
1020
      integer   sp
1031
      integer   sp
1021
      real      lat2,lon2
1032
      real      lat2,lon2
1022
      real      dist,sum
1033
      real      dist,sum
1023
      real      xmax
1034
      real      xmax
1024
      integer   periodic
1035
      integer   periodic
1025
      integer   test
1036
      integer   test
1026
      character ch
1037
      character ch
1027
 
1038
 
1028
c     Numerical epsilon
1039
c     Numerical epsilon
1029
      real      eps
1040
      real      eps
1030
      parameter (eps=0.01)
1041
      parameter (eps=0.01)
1031
 
1042
 
1032
c     Externals
1043
c     Externals
1033
      real      sdis,weight
1044
      real      sdis,weight
1034
      external  sdis,weight
1045
      external  sdis,weight
1035
 
1046
 
1036
c     Check whether lat/lon point is valid
1047
c     Check whether lat/lon point is valid
1037
      xmax=xmin+real(nx-1)*dx
1048
      xmax=xmin+real(nx-1)*dx
1038
      if (lon.lt.xmin-eps) lon=lon+360.
1049
      if (lon.lt.xmin-eps) lon=lon+360.
1039
      if (lon.gt.xmax+eps) lon=lon-360.
1050
      if (lon.gt.xmax+eps) lon=lon-360.
1040
      if (abs(lat-90).lt.eps) lat=90.
1051
      if (abs(lat-90).lt.eps) lat=90.
1041
      if (abs(lat+90).lt.eps) lat=-90.
1052
      if (abs(lat+90).lt.eps) lat=-90.
1042
      if ((abs(lat).gt.(90.+eps)).or.
1053
      if ((abs(lat).gt.(90.+eps)).or.
1043
     >    (lon.lt.xmin-eps).or.(lon.gt.xmax+eps)) then
1054
     >    (lon.lt.xmin-eps).or.(lon.gt.xmax+eps)) then
1044
         print*,'Invalid lat/lon point ',lat,lon
1055
         print*,'Invalid lat/lon point ',lat,lon
1045
         return
1056
         return
1046
      endif
1057
      endif
1047
 
1058
 
1048
c     Set flag for periodic domain
1059
c     Set flag for periodic domain
1049
      if (abs(xmax-xmin-360.).lt.eps) then
1060
      if (abs(xmax-xmin-360.).lt.eps) then
1050
         periodic=1
1061
         periodic=1
1051
      else if (abs(xmax-xmin-360+dx).lt.eps) then
1062
      else if (abs(xmax-xmin-360+dx).lt.eps) then
1052
         periodic=2
1063
         periodic=2
1053
      else
1064
      else
1054
         periodic=0
1065
         periodic=0
1055
      endif
1066
      endif
1056
 
1067
 
1057
c     Get indices of one coarse grid point within search radius
1068
c     Get indices of one coarse grid point within search radius
1058
      i=nint((lon-xmin)/dx)+1
1069
      i=nint((lon-xmin)/dx)+1
1059
      if ((i.eq.nx).and.(periodic.eq.1)) i=1
1070
      if ((i.eq.nx).and.(periodic.eq.1)) i=1
1060
      j=nint((lat-ymin)/dy)+1
1071
      j=nint((lat-ymin)/dy)+1
1061
      lat2=ymin+real(j-1)*dy
1072
      lat2=ymin+real(j-1)*dy
1062
      lon2=xmin+real(i-1)*dx
1073
      lon2=xmin+real(i-1)*dx
1063
      dist=sdis(lon,lat,lon2,lat2,unit)
1074
      dist=sdis(lon,lat,lon2,lat2,unit)
1064
      if (dist.gt.radius) then
1075
      if (dist.gt.radius) then
1065
         print*,'1: Search radius is too small...'
1076
         print*,'1: Search radius is too small...'
1066
         stop
1077
         stop
1067
      endif
1078
      endif
1068
 
1079
 
1069
c     Get connected points
1080
c     Get connected points
1070
      k=0
1081
      k=0
1071
      stackx(1)=i
1082
      stackx(1)=i
1072
      stacky(1)=j
1083
      stacky(1)=j
1073
      sp    = 1
1084
      sp    = 1
1074
      do while (sp.ne.0) 
1085
      do while (sp.ne.0) 
1075
         
1086
         
1076
c        Get an element from stack
1087
c        Get an element from stack
1077
         n=stackx(sp)
1088
         n=stackx(sp)
1078
         m=stacky(sp)
1089
         m=stacky(sp)
1079
         sp=sp-1
1090
         sp=sp-1
1080
                  
1091
                  
1081
c        Get distance from reference point
1092
c        Get distance from reference point
1082
         lat2=ymin+real(m-1)*dy
1093
         lat2=ymin+real(m-1)*dy
1083
         lon2=xmin+real(n-1)*dx
1094
         lon2=xmin+real(n-1)*dx
1084
         dist=sdis(lon,lat,lon2,lat2,unit)
1095
         dist=sdis(lon,lat,lon2,lat2,unit)
1085
 
1096
 
1086
c        Check whether distance is smaller than search radius: connected
1097
c        Check whether distance is smaller than search radius: connected
1087
         if (dist.lt.radius) then
1098
         if (dist.lt.radius) then
1088
 
1099
 
1089
c           Make entry in filter mask
1100
c           Make entry in filter mask
1090
            k=k+1
1101
            k=k+1
1091
            tab_x(k)=n
1102
            tab_x(k)=n
1092
            tab_y(k)=m
1103
            tab_y(k)=m
1093
            tab_r(k)=weight(dist,radius)
1104
            tab_r(k)=weight(dist,radius)
1094
 
1105
 
1095
c           Mark this point as visited
1106
c           Mark this point as visited
1096
            connect(n,m)=connectval
1107
            connect(n,m)=connectval
1097
                     
1108
                     
1098
c           Get coordinates of neighbouring points
1109
c           Get coordinates of neighbouring points
1099
            nr=n+1
1110
            nr=n+1
1100
            if ((nr.gt.nx)  .and.(periodic.eq.0)) nr=nx
1111
            if ((nr.gt.nx)  .and.(periodic.eq.0)) nr=nx
1101
            if ((nr.gt.nx-1).and.(periodic.eq.1)) nr=1
1112
            if ((nr.gt.nx-1).and.(periodic.eq.1)) nr=1
1102
            if ((nr.gt.nx)  .and.(periodic.eq.2)) nr=1
1113
            if ((nr.gt.nx)  .and.(periodic.eq.2)) nr=1
1103
            nl=n-1
1114
            nl=n-1
1104
            if ((nl.lt.1).and.(periodic.eq.0)) nl=1
1115
            if ((nl.lt.1).and.(periodic.eq.0)) nl=1
1105
            if ((nl.lt.1).and.(periodic.eq.1)) nl=nx-1
1116
            if ((nl.lt.1).and.(periodic.eq.1)) nl=nx-1
1106
            if ((nl.lt.1).and.(periodic.eq.2)) nl=nx
1117
            if ((nl.lt.1).and.(periodic.eq.2)) nl=nx
1107
            mu=m+1
1118
            mu=m+1
1108
            if (mu.gt.ny) mu=ny
1119
            if (mu.gt.ny) mu=ny
1109
            md=m-1
1120
            md=m-1
1110
            if (md.lt.1) md=1
1121
            if (md.lt.1) md=1
1111
 
1122
 
1112
c           Update stack
1123
c           Update stack
1113
            if (connect(nr,m).ne.connectval) then
1124
            if (connect(nr,m).ne.connectval) then
1114
               connect(nr,m)=connectval
1125
               connect(nr,m)=connectval
1115
               sp=sp+1
1126
               sp=sp+1
1116
               stackx(sp)=nr
1127
               stackx(sp)=nr
1117
               stacky(sp)=m
1128
               stacky(sp)=m
1118
            endif
1129
            endif
1119
            if (connect(nl,m).ne.connectval) then
1130
            if (connect(nl,m).ne.connectval) then
1120
               connect(nl,m)=connectval
1131
               connect(nl,m)=connectval
1121
               sp=sp+1
1132
               sp=sp+1
1122
               stackx(sp)=nl
1133
               stackx(sp)=nl
1123
               stacky(sp)=m
1134
               stacky(sp)=m
1124
            endif
1135
            endif
1125
            if (connect(n,mu).ne.connectval) then
1136
            if (connect(n,mu).ne.connectval) then
1126
               connect(n,mu)=connectval
1137
               connect(n,mu)=connectval
1127
               sp=sp+1
1138
               sp=sp+1
1128
               stackx(sp)=n
1139
               stackx(sp)=n
1129
               stacky(sp)=mu
1140
               stacky(sp)=mu
1130
            endif
1141
            endif
1131
            if (connect(n,md).ne.connectval) then
1142
            if (connect(n,md).ne.connectval) then
1132
               connect(n,md)=connectval
1143
               connect(n,md)=connectval
1133
               sp=sp+1
1144
               sp=sp+1
1134
               stackx(sp)=n
1145
               stackx(sp)=n
1135
               stacky(sp)=md
1146
               stacky(sp)=md
1136
            endif
1147
            endif
1137
         endif     
1148
         endif     
1138
 
1149
 
1139
      end do
1150
      end do
1140
 
1151
 
1141
      if (k.ge.1) then
1152
      if (k.ge.1) then
1142
         sum=0.
1153
         sum=0.
1143
         do i=1,k
1154
         do i=1,k
1144
            sum=sum+tab_r(i)
1155
            sum=sum+tab_r(i)
1145
         enddo
1156
         enddo
1146
         do i=1,k
1157
         do i=1,k
1147
            out (tab_x(i),tab_y(i))=out(tab_x(i),tab_y(i))+
1158
            out (tab_x(i),tab_y(i))=out(tab_x(i),tab_y(i))+
1148
     >                             addval*tab_r(i)/sum
1159
     >                             addval*tab_r(i)/sum
1149
            outc(tab_x(i),tab_y(i))=outc(tab_x(i),tab_y(i))+
1160
            outc(tab_x(i),tab_y(i))=outc(tab_x(i),tab_y(i))+
1150
     >                             1.*tab_r(i)/sum
1161
     >                             1.*tab_r(i)/sum
1151
 
1162
 
1152
            if ((tab_x(i).eq.1).and.(periodic.eq.1)) then
1163
            if ((tab_x(i).eq.1).and.(periodic.eq.1)) then
1153
               out(nx,tab_y(i))=out(nx,tab_y(i))+
1164
               out(nx,tab_y(i))=out(nx,tab_y(i))+
1154
     >                             addval*tab_r(i)/sum
1165
     >                             addval*tab_r(i)/sum
1155
               outc(nx,tab_y(i))=outc(nx,tab_y(i))+
1166
               outc(nx,tab_y(i))=outc(nx,tab_y(i))+
1156
     >                             1.*tab_r(i)/sum
1167
     >                             1.*tab_r(i)/sum
1157
 
1168
 
1158
            endif
1169
            endif
1159
         enddo
1170
         enddo
1160
      else
1171
      else
1161
         print*,'2: Search radius is too small...'
1172
         print*,'2: Search radius is too small...'
1162
         stop
1173
         stop
1163
      endif
1174
      endif
1164
 
1175
 
1165
      end
1176
      end
1166
 
1177
 
1167
 
1178
 
1168
c     ----------------------------------------------------------------------
1179
c     ----------------------------------------------------------------------
1169
c     Get spherical distance between lat/lon points
1180
c     Get spherical distance between lat/lon points
1170
c     ----------------------------------------------------------------------
1181
c     ----------------------------------------------------------------------
1171
            
1182
            
1172
      real function sdis(xp,yp,xq,yq,unit)
1183
      real function sdis(xp,yp,xq,yq,unit)
1173
 
1184
 
1174
c     Calculates spherical distance (in km) between two points given
1185
c     Calculates spherical distance (in km) between two points given
1175
c     by their spherical coordinates (xp,yp) and (xq,yq), respectively.
1186
c     by their spherical coordinates (xp,yp) and (xq,yq), respectively.
1176
 
1187
 
1177
      real,parameter ::       re=6371.229
1188
      real,parameter ::       re=6371.229
1178
      real,parameter ::       rad2deg=180./3.14159265
1189
      real,parameter ::       rad2deg=180./3.14159265
1179
      real,parameter ::       deg2rad=3.141592654/180.
1190
      real,parameter ::       deg2rad=3.141592654/180.
1180
 
1191
 
1181
      real         xp,yp,xq,yq,arg
1192
      real         xp,yp,xq,yq,arg
1182
      character*80 unit
1193
      character*80 unit
1183
      real         dlon,dlat,alpha,rlat1,ralt2
1194
      real         dlon,dlat,alpha,rlat1,ralt2
1184
 
1195
 
1185
      if ( unit.eq.'km' ) then
1196
      if ( unit.eq.'km' ) then
1186
 
1197
 
1187
         arg=sind(yp)*sind(yq)+cosd(yp)*cosd(yq)*cosd(xp-xq)
1198
         arg=sind(yp)*sind(yq)+cosd(yp)*cosd(yq)*cosd(xp-xq)
1188
         if (arg.lt.-1.) arg=-1.
1199
         if (arg.lt.-1.) arg=-1.
1189
         if (arg.gt.1.) arg=1.
1200
         if (arg.gt.1.) arg=1.
1190
         sdis=re*acos(arg)
1201
         sdis=re*acos(arg)
1191
         
1202
         
1192
      elseif ( unit.eq.'deg' ) then
1203
      elseif ( unit.eq.'deg' ) then
1193
 
1204
 
1194
         dlon = xp-xq
1205
         dlon = xp-xq
1195
         if ( dlon.gt. 180. ) dlon = dlon - 360.
1206
         if ( dlon.gt. 180. ) dlon = dlon - 360.
1196
         if ( dlon.lt.-180. ) dlon = dlon + 360.
1207
         if ( dlon.lt.-180. ) dlon = dlon + 360.
1197
         sdis = sqrt( dlon**2 + (yp-yq)**2 )
1208
         sdis = sqrt( dlon**2 + (yp-yq)**2 )
1198
 
1209
 
1199
      elseif ( unit.eq.'km.haversine' ) then
1210
      elseif ( unit.eq.'km.haversine' ) then
1200
 
1211
 
1201
        dlat   =  (yp - yq)*deg2rad
1212
        dlat   =  (yp - yq)*deg2rad
1202
        dlon   =  (xp - xq)*deg2rad
1213
        dlon   =  (xp - xq)*deg2rad
1203
        rlat1   =  yp*deg2rad
1214
        rlat1   =  yp*deg2rad
1204
        rlat2   =  yq*deg2rad
1215
        rlat2   =  yq*deg2rad
1205
 
1216
 
1206
        alpha  = ( sin(0.5*dlat)**2 ) +
1217
        alpha  = ( sin(0.5*dlat)**2 ) +
1207
     >           ( sin(0.5*dlon)**2 )*cos(rlat1)*cos(rlat2)
1218
     >           ( sin(0.5*dlon)**2 )*cos(rlat1)*cos(rlat2)
1208
 
1219
 
1209
        sdis = 4. * re * atan2( sqrt(alpha),1. + sqrt( 1. - alpha ) )
1220
        sdis = 4. * re * atan2( sqrt(alpha),1. + sqrt( 1. - alpha ) )
1210
 
1221
 
1211
      endif  
1222
      endif  
1212
 
1223
 
1213
      end
1224
      end
1214
 
1225
 
1215
c     ----------------------------------------------------------------------
1226
c     ----------------------------------------------------------------------
1216
c     Weight function for the filter mask
1227
c     Weight function for the filter mask
1217
c     ----------------------------------------------------------------------
1228
c     ----------------------------------------------------------------------
1218
 
1229
 
1219
      real function weight (r,radius)
1230
      real function weight (r,radius)
1220
 
1231
 
1221
c     Attribute to each distanc r its corresponding weight in the filter mask
1232
c     Attribute to each distanc r its corresponding weight in the filter mask
1222
 
1233
 
1223
      implicit none
1234
      implicit none
1224
 
1235
 
1225
c     Declaration of subroutine parameters
1236
c     Declaration of subroutine parameters
1226
      real r
1237
      real r
1227
      real radius
1238
      real radius
1228
 
1239
 
1229
c     Simple 0/1 mask
1240
c     Simple 0/1 mask
1230
      if (r.lt.radius) then
1241
      if (r.lt.radius) then
1231
          weight=1.-0.65*r/radius 
1242
          weight=1.-0.65*r/radius 
1232
      else
1243
      else
1233
          weight=0.
1244
          weight=0.
1234
      endif
1245
      endif
1235
 
1246
 
1236
      end
1247
      end
1237
 
1248
 
1238
 
1249
 
1239
c     ********************************************************************
1250
c     ********************************************************************
1240
c     * INPUT / OUTPUT SUBROUTINES                                       *
1251
c     * INPUT / OUTPUT SUBROUTINES                                       *
1241
c     ********************************************************************
1252
c     ********************************************************************
1242
 
1253
 
1243
c     --------------------------------------------------------------------
1254
c     --------------------------------------------------------------------
1244
c     Subroutines to write the netcdf output file
1255
c     Subroutines to write the netcdf output file
1245
c     --------------------------------------------------------------------
1256
c     --------------------------------------------------------------------
1246
 
1257
 
1247
      subroutine writecdf2D(cdfname,
1258
      subroutine writecdf2D(cdfname,
1248
     >                      varname,arr,time,
1259
     >                      varname,arr,time,
1249
     >                      dx,dy,xmin,ymin,nx,ny,nz,
1260
     >                      dx,dy,xmin,ymin,nx,ny,nz,
1250
     >                      crefile,crevar)
1261
     >                      crefile,crevar)
1251
 
1262
 
1252
      IMPLICIT NONE
1263
      IMPLICIT NONE
1253
 
1264
 
1254
c     Declaration of input parameters
1265
c     Declaration of input parameters
1255
      character*80 cdfname,varname
1266
      character*80 cdfname,varname
1256
      integer nx,ny,nz
1267
      integer nx,ny,nz
1257
      real arr(nx,ny,nz)
1268
      real arr(nx,ny,nz)
1258
      real dx,dy,xmin,ymin
1269
      real dx,dy,xmin,ymin
1259
      real time
1270
      real time
1260
      integer crefile,crevar
1271
      integer crefile,crevar
1261
 
1272
 
1262
c     Further variables
1273
c     Further variables
1263
      real varmin(4),varmax(4),stag(4)
1274
      real varmin(4),varmax(4),stag(4)
1264
      integer ierr,cdfid,ndim,vardim(4)
1275
      integer ierr,cdfid,ndim,vardim(4)
1265
      character*80 cstname
1276
      character*80 cstname
1266
      real mdv
1277
      real mdv
1267
      integer i
1278
      integer i
-
 
1279
      integer nvars
-
 
1280
      character*80 vars(300)
1268
 
1281
 
1269
C     Definitions
1282
C     Definitions
1270
      varmin(1)=xmin
1283
      varmin(1)=xmin
1271
      varmin(2)=ymin
1284
      varmin(2)=ymin
1272
      varmin(3)=1050.
1285
      varmin(3)=1050.
1273
      varmax(1)=xmin+real(nx-1)*dx
1286
      varmax(1)=xmin+real(nx-1)*dx
1274
      varmax(2)=ymin+real(ny-1)*dy
1287
      varmax(2)=ymin+real(ny-1)*dy
1275
      varmax(3)=1050.
1288
      varmax(3)=1050.
1276
      cstname='no_constants_file'
1289
      cstname='no_constants_file'
1277
      ndim=4
1290
      ndim=4
1278
      vardim(1)=nx
1291
      vardim(1)=nx
1279
      vardim(2)=ny
1292
      vardim(2)=ny
1280
      vardim(3)=nz
1293
      vardim(3)=nz
1281
      stag(1)=0.
1294
      stag(1)=0.
1282
      stag(2)=0.
1295
      stag(2)=0.
1283
      stag(3)=0.
1296
      stag(3)=0.
1284
      mdv=-999.98999
1297
      mdv=-999.98999
1285
 
1298
 
1286
C     Create the file
1299
C     Create the file
1287
      if (crefile.eq.0) then
1300
      if (crefile.eq.0) then
1288
         call cdfwopn(cdfname,cdfid,ierr)
1301
         call cdfwopn(cdfname,cdfid,ierr)
1289
         if (ierr.ne.0) goto 906
1302
         if (ierr.ne.0) goto 906
1290
      else if (crefile.eq.1) then
1303
      else if (crefile.eq.1) then
1291
         call crecdf(cdfname,cdfid,
1304
         call crecdf(cdfname,cdfid,
1292
     >        varmin,varmax,ndim,cstname,ierr)
1305
     >        varmin,varmax,ndim,cstname,ierr)
1293
         if (ierr.ne.0) goto 903
1306
         if (ierr.ne.0) goto 903
1294
      endif
1307
      endif
1295
 
1308
 
-
 
1309
c     Check whether the variable is already on the file
-
 
1310
      call getvars(cdfid,nvars,vars,ierr)
-
 
1311
      if (ierr.ne.0) goto 906
-
 
1312
      do i=1,nvars
-
 
1313
         if ( vars(i).eq.varname ) crevar = 0
-
 
1314
      enddo
-
 
1315
 
1296
c     Write the data to the netcdf file, and close the file
1316
c     Write the data to the netcdf file, and close the file
1297
      if (crevar.eq.1) then
1317
      if (crevar.eq.1) then
1298
         call putdef(cdfid,varname,ndim,mdv,
1318
         call putdef(cdfid,varname,ndim,mdv,
1299
     >        vardim,varmin,varmax,stag,ierr)
1319
     >        vardim,varmin,varmax,stag,ierr)
1300
         if (ierr.ne.0) goto 904
1320
         if (ierr.ne.0) goto 904
1301
      endif
1321
      endif
1302
      call putdat(cdfid,varname,time,0,arr,ierr)
1322
      call putdat(cdfid,varname,time,0,arr,ierr)
1303
      if (ierr.ne.0) goto 905
1323
      if (ierr.ne.0) goto 905
1304
      call clscdf(cdfid,ierr)
1324
      call clscdf(cdfid,ierr)
1305
 
1325
 
1306
      return
1326
      return
1307
 
1327
 
1308
c     Error handling
1328
c     Error handling
1309
 903  print*,'*** Problem to create netcdf file ***'
1329
 903  print*,'*** Problem to create netcdf file ***'
1310
      stop
1330
      stop
1311
 904  print*,'*** Problem to write definition ***'
1331
 904  print*,'*** Problem to write definition ***'
1312
      stop
1332
      stop
1313
 905  print*,'*** Problem to write data ***'
1333
 905  print*,'*** Problem to write data ***'
1314
      stop
1334
      stop
1315
 906  print*,'*** Problem to open netcdf file ***'
1335
 906  print*,'*** Problem to open netcdf file ***'
1316
      stop
1336
      stop
1317
 
1337
 
1318
      end
1338
      end
1319
 
1339
 
1320
 
1340
 
1321
c     -----------------------------------------------
1341
c     -----------------------------------------------
1322
c     Subroutine to read a netcdf output file
1342
c     Subroutine to read a netcdf output file
1323
c     -----------------------------------------------
1343
c     -----------------------------------------------
1324
 
1344
 
1325
      subroutine readcdf2D(cdfname,varname,arr,time,
1345
      subroutine readcdf2D(cdfname,varname,arr,time,
1326
     >                     dx,dy,xmin,ymin,nx,ny,nz)
1346
     >                     dx,dy,xmin,ymin,nx,ny,nz)
1327
 
1347
 
1328
      implicit none
1348
      implicit none
1329
 
1349
 
1330
c     Declaration of input parameters
1350
c     Declaration of input parameters
1331
      character*80 cdfname,varname
1351
      character*80 cdfname,varname
1332
      integer      nx,ny,nz
1352
      integer      nx,ny,nz
1333
      real         arr(nx,ny,nz)
1353
      real         arr(nx,ny,nz)
1334
      real         dx,dy,xmin,ymin
1354
      real         dx,dy,xmin,ymin
1335
      real         time
1355
      real         time
1336
 
1356
 
1337
c     Internal variables for the netcdf file
1357
c     Internal variables for the netcdf file
1338
      real         varmin(4),varmax(4),stag(4)
1358
      real         varmin(4),varmax(4),stag(4)
1339
      integer      ierr,cdfid,ndim,vardim(4)
1359
      integer      ierr,cdfid,ndim,vardim(4)
1340
      real         mdv
1360
      real         mdv
1341
      real         delx,dely
1361
      real         delx,dely
1342
      real         times(500)
1362
      real         times(500)
1343
      integer      ntimes,flag
1363
      integer      ntimes,flag
1344
 
1364
 
1345
c     Numerical epsilon
1365
c     Numerical epsilon
1346
      real         eps
1366
      real         eps
1347
      parameter    (eps=0.01)
1367
      parameter    (eps=0.01)
1348
 
1368
 
1349
c     Auxiliary variables
1369
c     Auxiliary variables
1350
      integer      i,j,k
1370
      integer      i,j,k
1351
 
1371
 
1352
c     Initialize the ouput array
1372
c     Initialize the ouput array
1353
      do i=1,nx
1373
      do i=1,nx
1354
         do j=1,ny
1374
         do j=1,ny
1355
            do k=1,nz
1375
            do k=1,nz
1356
               arr(i,j,k)=0.
1376
               arr(i,j,k)=0.
1357
            enddo
1377
            enddo
1358
         enddo
1378
         enddo
1359
      enddo
1379
      enddo
1360
 
1380
 
1361
c     Try to open the netcdf file and to read the variable
1381
c     Try to open the netcdf file and to read the variable
1362
      call cdfopn(cdfname,cdfid,ierr)
1382
      call cdfopn(cdfname,cdfid,ierr)
1363
      if (ierr.ne.0) goto 801
1383
      if (ierr.ne.0) goto 801
1364
 
1384
 
1365
c     Check whether the specifieed time is available
1385
c     Check whether the specifieed time is available
1366
      call gettimes(cdfid,times,ntimes,ierr)
1386
      call gettimes(cdfid,times,ntimes,ierr)
1367
      if (ierr.ne.0) goto 801
1387
      if (ierr.ne.0) goto 801
1368
      flag=0
1388
      flag=0
1369
      do i=1,ntimes
1389
      do i=1,ntimes
1370
          if (abs(times(i)-time).lt.eps) flag=1
1390
          if (abs(times(i)-time).lt.eps) flag=1
1371
      enddo
1391
      enddo
1372
      if (flag.eq.0) then
1392
      if (flag.eq.0) then
1373
         print*,'No such time on cdf',time
1393
         print*,'No such time on cdf',time
1374
         stop
1394
         stop
1375
      endif
1395
      endif
1376
 
1396
 
1377
c     Get the variable definition, and the grid
1397
c     Get the variable definition, and the grid
1378
      call getdef(cdfid,varname,ndim,mdv,vardim,varmin,varmax,
1398
      call getdef(cdfid,varname,ndim,mdv,vardim,varmin,varmax,
1379
     >     stag,ierr)
1399
     >     stag,ierr)
1380
      if (ierr.ne.0) goto 801
1400
      if (ierr.ne.0) goto 801
1381
 
1401
 
1382
c     Set parameters or read parameters - depending on nx,ny
1402
c     Set parameters or read parameters - depending on nx,ny
1383
      if ( (nx.eq.1).and.(ny.eq.1) ) then
1403
      if ( (nx.eq.1).and.(ny.eq.1) ) then
1384
         dx   = (varmax(1)-varmin(1))/real(vardim(1)-1)
1404
         dx   = (varmax(1)-varmin(1))/real(vardim(1)-1)
1385
         dy   = (varmax(2)-varmin(2))/real(vardim(2)-1)
1405
         dy   = (varmax(2)-varmin(2))/real(vardim(2)-1)
1386
         nx   = vardim(1)
1406
         nx   = vardim(1)
1387
         ny   = vardim(2)
1407
         ny   = vardim(2)
1388
         nz   = vardim(3)
1408
         nz   = vardim(3)
1389
         xmin = varmin(1)
1409
         xmin = varmin(1)
1390
         ymin = varmin(2)
1410
         ymin = varmin(2)
1391
      else
1411
      else
1392
         call getdat(cdfid,varname,time,0,arr,ierr)
1412
         call getdat(cdfid,varname,time,0,arr,ierr)
1393
         if (ierr.ne.0) goto 801
1413
         if (ierr.ne.0) goto 801
1394
      endif
1414
      endif
1395
 
1415
 
1396
c     Close data file
1416
c     Close data file
1397
      call clscdf(cdfid,ierr)
1417
      call clscdf(cdfid,ierr)
1398
 
1418
 
1399
      return
1419
      return
1400
      
1420
      
1401
c     Exception handling
1421
c     Exception handling
1402
 801  print*,'Problems in reading netcdf file'
1422
 801  print*,'Problems in reading netcdf file'
1403
      stop
1423
      stop
1404
      
1424
      
1405
      end
1425
      end
1406
 
1426
 
1407
 
1427
 
-
 
1428
c     -----------------------------------------------
-
 
1429
c     Diffusive filter
-
 
1430
c     -----------------------------------------------
-
 
1431
 
-
 
1432
      subroutine filt2d (a,af,nx,ny,fil,misdat,
-
 
1433
     &                   iperx,ipery,ispol,inpol)
1408
 
1434
 
-
 
1435
c     Apply a conservative diffusion operator onto the 2d field a,
-
 
1436
c     with full missing data checking.
-
 
1437
c
-
 
1438
c     a     real   inp  array to be filtered, dimensioned (nx,ny)
-
 
1439
c     af    real   out  filtered array, dimensioned (nx,ny), can be
-
 
1440
c                       equivalenced with array a in the calling routine
-
 
1441
c     f1    real        workarray, dimensioned (nx+1,ny)
-
 
1442
c     f2    real        workarray, dimensioned (nx,ny+1)
-
 
1443
c     fil   real   inp  filter-coeff., 0<afil<=1. Maximum filtering with afil=1
-
 
1444
c                       corresponds to one application of the linear filter.
-
 
1445
c     misdat real  inp  missing-data value, a(i,j)=misdat indicates that
-
 
1446
c                       the corresponding value is not available. The
-
 
1447
c                       misdat-checking can be switched off with with misdat=0.
-
 
1448
c     iperx int    inp  periodic boundaries in the x-direction (1=yes,0=no)
-
 
1449
c     ipery int    inp  periodic boundaries in the y-direction (1=yes,0=no)
-
 
1450
c     inpol int    inp  northpole at j=ny  (1=yes,0=no)
-
 
1451
c     ispol int    inp  southpole at j=1   (1=yes,0=no)
-
 
1452
c
-
 
1453
c     Christoph Schaer, 1993
-
 
1454
 
-
 
1455
c     argument declaration
-
 
1456
      integer     nx,ny
-
 
1457
      real        a(nx,ny),af(nx,ny),fil,misdat
-
 
1458
      integer     iperx,ipery,inpol,ispol
-
 
1459
 
-
 
1460
c     local variable declaration
-
 
1461
      integer     i,j,is
-
 
1462
      real        fh
-
 
1463
      real        f1(nx+1,ny),f2(nx,ny+1)
-
 
1464
 
-
 
1465
c     compute constant fh
-
 
1466
      fh=0.125*fil
-
 
1467
 
-
 
1468
c     compute fluxes in x-direction
-
 
1469
      if (misdat.eq.0.) then
-
 
1470
        do j=1,ny
-
 
1471
        do i=2,nx
-
 
1472
          f1(i,j)=a(i-1,j)-a(i,j)
-
 
1473
        enddo
-
 
1474
        enddo
-
 
1475
      else
-
 
1476
        do j=1,ny
-
 
1477
        do i=2,nx
-
 
1478
          if ((a(i,j).eq.misdat).or.(a(i-1,j).eq.misdat)) then
-
 
1479
            f1(i,j)=0.
-
 
1480
          else
-
 
1481
            f1(i,j)=a(i-1,j)-a(i,j)
-
 
1482
          endif
-
 
1483
        enddo
-
 
1484
        enddo
-
 
1485
      endif
-
 
1486
      if (iperx.eq.1) then
-
 
1487
c       do periodic boundaries in the x-direction
-
 
1488
        do j=1,ny
-
 
1489
          f1(1,j)=f1(nx,j)
-
 
1490
          f1(nx+1,j)=f1(2,j)
-
 
1491
        enddo
-
 
1492
      else
-
 
1493
c       set boundary-fluxes to zero
-
 
1494
        do j=1,ny
-
 
1495
          f1(1,j)=0.
-
 
1496
          f1(nx+1,j)=0.
-
 
1497
        enddo
-
 
1498
      endif
-
 
1499
 
-
 
1500
c     compute fluxes in y-direction
-
 
1501
      if (misdat.eq.0.) then
-
 
1502
        do j=2,ny
-
 
1503
        do i=1,nx
-
 
1504
          f2(i,j)=a(i,j-1)-a(i,j)
-
 
1505
        enddo
-
 
1506
        enddo
-
 
1507
      else
-
 
1508
        do j=2,ny
-
 
1509
        do i=1,nx
-
 
1510
          if ((a(i,j).eq.misdat).or.(a(i,j-1).eq.misdat)) then
-
 
1511
            f2(i,j)=0.
-
 
1512
          else
-
 
1513
            f2(i,j)=a(i,j-1)-a(i,j)
-
 
1514
          endif
-
 
1515
        enddo
-
 
1516
        enddo
-
 
1517
      endif
-
 
1518
c     set boundary-fluxes to zero
-
 
1519
      do i=1,nx
-
 
1520
        f2(i,1)=0.
-
 
1521
        f2(i,ny+1)=0.
-
 
1522
      enddo
-
 
1523
      if (ipery.eq.1) then
-
 
1524
c       do periodic boundaries in the x-direction
-
 
1525
        do i=1,nx
-
 
1526
          f2(i,1)=f2(i,ny)
-
 
1527
          f2(i,ny+1)=f2(i,2)
-
 
1528
        enddo
-
 
1529
      endif
-
 
1530
      if (iperx.eq.1) then
-
 
1531
        if (ispol.eq.1) then
-
 
1532
c         do south-pole
-
 
1533
          is=(nx-1)/2
-
 
1534
          do i=1,nx
-
 
1535
            f2(i,1)=-f2(mod(i-1+is,nx)+1,2)
-
 
1536
          enddo
-
 
1537
        endif
-
 
1538
        if (inpol.eq.1) then
-
 
1539
c         do north-pole
-
 
1540
          is=(nx-1)/2
-
 
1541
          do i=1,nx
-
 
1542
            f2(i,ny+1)=-f2(mod(i-1+is,nx)+1,ny)
-
 
1543
          enddo
-
 
1544
        endif
-
 
1545
      endif
-
 
1546
 
-
 
1547
c     compute flux-convergence -> filter
-
 
1548
      if (misdat.eq.0.) then
-
 
1549
        do j=1,ny
-
 
1550
        do i=1,nx
-
 
1551
            af(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1))
-
 
1552
        enddo
-
 
1553
        enddo
-
 
1554
      else
-
 
1555
        do j=1,ny
-
 
1556
        do i=1,nx
-
 
1557
          if (a(i,j).eq.misdat) then
-
 
1558
            af(i,j)=misdat
-
 
1559
          else
-
 
1560
            af(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1))
-
 
1561
          endif
-
 
1562
        enddo
-
 
1563
        enddo
-
 
1564
      endif
-
 
1565
      end
1409
 
1566
 
1410
 
1567
 
1411
 
1568
 
1412
 
1569
 
1413
 
1570
 
1414
 
1571
 
1415
 
1572
 
1416
 
1573
 
1417
 
1574
 
1418
 
1575
 
1419
 
1576
 
1420
 
1577
 
1421
 
1578
 
1422
 
1579
 
1423
 
1580
 
1424
 
1581
 
1425
 
1582
 
1426
 
1583
 
1427
 
1584
 
1428
 
1585
 
1429
 
1586
 
1430
 
1587
 
1431
 
1588
 
1432
 
1589
 
1433
 
1590
 
1434
 
1591