Subversion Repositories lagranto.wrf

Rev

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

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