Subversion Repositories lagranto.ecmwf

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 michaesp 1
 
2
      PROGRAM difference
3
 
4
c     ***********************************************************************
5
c     * Get the difference between tow trajectory files                     *
6
c     * Michael Sprenger / Spring, summer, autumn 2010                      *
7
c     ***********************************************************************
8
 
9
      implicit none
10
 
11
c     ----------------------------------------------------------------------
12
c     Declaration of variables
13
c     ----------------------------------------------------------------------
14
 
15
c     Field name and mode for difference calculation
16
      character*80                           mode                     ! Difference mode
17
      character*80                           fieldname                ! Name of differencing
18
 
19
c     Input and output format for trajectories (see iotra.f)
20
      character*80                           inpfile1                 ! Input filename 1
21
      character*80                           inpfile2                 ! Input filename 2
22
      character*80                           outfile                  ! Output filename
23
 
24
c     Input trajectories
25
      integer                                ntra1      ,ntra2        ! Number of trajectories
26
      integer                                ntim1      ,ntim2        ! Number of times
27
      integer                                ncol1      ,ncol2        ! Number of columns
28
      real,allocatable, dimension (:,:,:) :: trainp1    ,trainp2      ! Trajectories (ntra,ntim,ncol)
29
      character*80                           vars1(100) ,vars2(100)   ! Variable names
30
      integer                                refdate1(6),refdate2(6)  ! Reference date
31
 
32
c     Output/comparison trajectory
33
      integer                                ntra                    ! Number of trajectories
34
      integer                                ntim                    ! Number of times
35
      integer                                ncol                    ! Number of columns
36
      real,allocatable, dimension (:,:,:) :: traout                  ! Trajectories (ntra,ntim,ncol)
37
      character*80                           vars(100)               ! Variable names
38
      integer                                refdate(6)              ! Reference date
39
 
40
c     Auxiliary variables
41
      integer                                inpmode1,inpmode2
42
      integer                                outmode
43
      integer                                stat
44
      integer                                fid
45
      integer                                i,j,k
46
      integer                                ind1,ind2
47
      integer                                isok
48
      character                              ch
49
      real,allocatable, dimension (:) ::     diff
50
      integer                                outind
51
 
52
c     Externals 
53
      real,external                   ::     sdis
54
 
55
c     ----------------------------------------------------------------------
56
c     Preparations
57
c     ----------------------------------------------------------------------
58
 
59
c     Read parameters
60
      open(10,file='difference.param')
61
       read(10,*) inpfile1
62
       read(10,*) inpfile2
63
       read(10,*) outfile
64
       read(10,*) ntra1,ntim1,ncol1
65
       read(10,*) ntra2,ntim2,ncol2
66
       read(10,*) mode
67
       read(10,*) fieldname
68
      close(10)
69
 
70
c     Determine the formats
71
      call mode_tra(inpmode1,inpfile1)
72
      if (inpmode1.eq.-1) inpmode1=1
73
 
74
      call mode_tra(inpmode2,inpfile2)
75
      if (inpmode2.eq.-1) inpmode2=1
76
 
77
      call mode_tra(outmode,outfile)
78
      if (outmode.eq.-1) outmode=1
79
 
80
c     Set number of trajectories for output
81
      if ( ntra1.lt.ntra2) then
82
         ntra = ntra1
83
      else
84
         ntra = ntra2
85
      endif
86
 
87
c     Set number of times for output
88
      if ( mode.eq.'single' ) then
89
         ntim = ntim1
90
      else
91
         ntim = 1
92
      endif
93
 
94
c     Set the column names for output 
95
      if ( fieldname.eq.'LATLON') then         
96
         ncol    = 1 + 3 + 3     + 1
97
         vars(1) = 'time'
98
         vars(2) = 'lon[1]'
99
         vars(3) = 'lat[1]'
100
         vars(4) = 'p[1]'
101
         vars(5) = 'lon[2]'
102
         vars(6) = 'lat[2]'
103
         vars(7) = 'p[2]'
104
         vars(8) = 'SDIS'
105
      else
106
         ncol = 1 + 3 + 3 + 2 + 1
107
         vars( 1) = 'time'
108
         vars( 2) = 'lon[1]'
109
         vars( 3) = 'lat[1]'
110
         vars( 4) = 'p[1]'
111
         vars( 5) = 'lon[2]'
112
         vars( 6) = 'lat[2]'
113
         vars( 7) = 'p[2]'
114
         vars( 8) = trim(fieldname)//'[1]'
115
         vars( 9) = trim(fieldname)//'[2]'
116
         vars(10) = trim(fieldname)//'[1-2]'
117
      endif
118
 
119
c     Allocate memory
120
      allocate(trainp1(ntra1,ntim1,ncol1),stat=stat)
121
      if (stat.ne.0) print*,'*** error allocating array trainp1   ***' 
122
      allocate(trainp2(ntra2,ntim2,ncol2),stat=stat)
123
      if (stat.ne.0) print*,'*** error allocating array trainp2   ***' 
124
      allocate(traout(ntra,ntim,ncol),stat=stat)
125
      if (stat.ne.0) print*,'*** error allocating array traout    ***' 
126
      allocate(diff(ntim1),stat=stat)
127
      if (stat.ne.0) print*,'*** error allocating array diff      ***' 
128
 
129
c     Read inpufiles
130
      call ropen_tra(fid,inpfile1,ntra1,ntim1,ncol1,
131
     >                   refdate1,vars1,inpmode1)
132
      call read_tra (fid,trainp1,ntra1,ntim1,ncol1,inpmode1)
133
      call close_tra(fid,inpmode1)
134
 
135
      call ropen_tra(fid,inpfile2,ntra2,ntim2,ncol2,
136
     >                   refdate2,vars2,inpmode2)
137
      call read_tra (fid,trainp2,ntra2,ntim2,ncol2,inpmode2)
138
      call close_tra(fid,inpmode2)
139
 
140
c     Check dimensions of the two trajectory files (#tim hard check)
141
      if (ntim1.ne.ntim2) then
142
         print*,'Trajectoy files have different time dimensions... Stop'
143
         stop
144
      endif
145
 
146
c     Check dimensions of the two trajectory files (#tra soft check)
147
      if (ntra1.ne.ntra2) then
148
         print*,'Differing number of trajectories... proceed [y/n]'
149
         read*,ch
150
         if (ch.eq.'n') stop
151
      endif
152
 
153
c     Check whether difference field is available on both files 
154
      if ( fieldname.ne.'LATLON') then
155
         ind1 = 0
156
         ind2 = 0
157
         do i=1,ncol
158
            if ( fieldname.eq.vars1(i) ) ind1 = i
159
            if ( fieldname.eq.vars2(i) ) ind2 = i
160
         enddo
161
         if ( (ind1.eq.0).or.(ind2.eq.0) ) then
162
            print*,'Field ',trim(fieldname),' not available... Stop'
163
            stop
164
         endif
165
      endif
166
 
167
c     Check reference dates (soft check)
168
      isok = 1
169
      do i=1,6
170
         if ( refdate1(i).ne.refdate2(i) ) isok = 0
171
      enddo
172
      if ( isok.eq.0 ) then
173
         print*,'Warning: reference dates differ... proceed [y/n]'
174
         read*,ch
175
         if (ch.eq.'n') stop
176
      endif
177
 
178
c     Check trajectory times (soft check)
179
      isok = 1
180
      do i=1,ntim
181
         if ( trainp1(1,i,1).ne.trainp2(1,i,1) ) isok = 0
182
      enddo
183
      if ( isok.eq.0 ) then
184
         print*,'Warning: trajectory times differ... proceed [y/n]'
185
         read*,ch
186
         if (ch.eq.'n') stop
187
      endif
188
 
189
c     Copy reference date to output
190
      do i=1,6
191
         refdate(i) = refdate1(i)
192
      enddo
193
 
194
c     ----------------------------------------------------------------------
195
c     Calculate the difference (depending on mode)
196
c     ----------------------------------------------------------------------
197
 
198
c     Loop over all trajectories
199
      do i=1,ntra
200
 
201
c        Calculate difference for all times
202
         do j=1,ntim1
203
 
204
c           Calculate the difference (distance or absolute value)
205
            if (fieldname.eq.'LATLON') then
206
               diff(j) = sdis( trainp1(i,j,2),trainp1(i,j,3),
207
     >                         trainp2(i,j,2),trainp2(i,j,3) )         
208
            else
209
               diff(j) = abs(trainp1(i,j,ind1) - trainp2(i,j,ind2))
210
            endif
211
 
212
         enddo
213
 
214
c        Save output for each time
215
         if ( mode.eq.'single' ) then
216
 
217
            do j=1,ntim
218
 
219
               if ( fieldname.eq.'LATLON' ) then
220
                  traout(i,j, 1) = trainp1(i,j,1)    ! time
221
                  traout(i,j, 2) = trainp1(i,j,2)    ! lon[1]
222
                  traout(i,j, 3) = trainp1(i,j,3)    ! lat[1]
223
                  traout(i,j, 4) = trainp1(i,j,4)    ! p[1]
224
                  traout(i,j, 5) = trainp2(i,j,2)    ! lon[2]
225
                  traout(i,j, 6) = trainp2(i,j,3)    ! lat[2]
226
                  traout(i,j, 7) = trainp2(i,j,4)    ! p[2]
227
                  traout(i,j, 8) = diff(j)           ! SDIS(j)
228
               else
229
                  traout(i,j, 1) = trainp1(i,j,1)    ! time
230
                  traout(i,j, 2) = trainp1(i,j,2)    ! lon[1]
231
                  traout(i,j, 3) = trainp1(i,j,3)    ! lat[1]
232
                  traout(i,j, 4) = trainp1(i,j,4)    ! p[1]
233
                  traout(i,j, 5) = trainp2(i,j,2)    ! lon[2]
234
                  traout(i,j, 6) = trainp2(i,j,3)    ! lat[2]
235
                  traout(i,j, 7) = trainp2(i,j,4)    ! p[2]
236
                  traout(i,j, 8) = trainp1(i,j,ind1) ! field[1]
237
                  traout(i,j, 9) = trainp2(i,j,ind2) ! field[2]
238
                  traout(i,j,10) = diff(j)           ! SDIS(j)
239
               endif
240
 
241
            enddo
242
 
243
c        Save only maximum
244
         elseif ( mode.eq.'max') then
245
 
246
            outind  = 1
247
            do j=2,ntim1
248
               if ( diff(j).gt.diff(outind) ) outind = j
249
            enddo
250
 
251
            if ( fieldname.eq.'LATLON' ) then
252
               traout(i,1, 1) = trainp1(i,outind,1)     ! time
253
               traout(i,1, 2) = trainp1(i,outind,2)     ! lon[1]
254
               traout(i,1, 3) = trainp1(i,outind,3)     ! lat[1]
255
               traout(i,1, 4) = trainp1(i,outind,4)     ! p[1]
256
               traout(i,1, 5) = trainp2(i,outind,2)     ! lon[2]
257
               traout(i,1, 6) = trainp2(i,outind,3)     ! lat[2]
258
               traout(i,1, 7) = trainp2(i,outind,4)     ! p[2]
259
               traout(i,1, 8) = diff(outind)            ! SDIS
260
            else
261
               traout(i,1, 1) = trainp1(i,outind,1)     ! time
262
               traout(i,1, 2) = trainp1(i,outind,2)     ! lon[1]
263
               traout(i,1, 3) = trainp1(i,outind,3)     ! lat[1]
264
               traout(i,1, 4) = trainp1(i,outind,4)     ! p[1]
265
               traout(i,1, 5) = trainp2(i,outind,2)     ! lon[2]
266
               traout(i,1, 6) = trainp2(i,outind,3)     ! lat[2]
267
               traout(i,1, 7) = trainp2(i,outind,4)     ! p[2]
268
               traout(i,1, 8) = trainp1(i,outind,ind1)  ! field[1]
269
               traout(i,1, 9) = trainp2(i,outind,ind2)  ! field[2]
270
               traout(i,1,10) = diff(outind)            ! SDIS(j)
271
            endif
272
 
273
         endif
274
 
275
      enddo
276
 
277
c     ----------------------------------------------------------------------
278
c     Write output
279
c     ----------------------------------------------------------------------
280
 
281
c     Write output file
282
      call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode)
283
      call write_tra(fid,traout,ntra,ntim,ncol,outmode)
284
      call close_tra(fid,outmode)
285
 
286
      end
287
 
288
 
289
 
290
 
291
c     ***********************************************************************
292
c     * Subroutines                                                         *
293
c     ***********************************************************************
294
 
295
c     ----------------------------------------------------------------------
296
c     Spherical distance
297
c     ----------------------------------------------------------------------
298
 
299
      real function sdis(xp,yp,xq,yq)
300
c
301
c     calculates spherical distance (in km) between two points given
302
c     by their spherical coordinates (xp,yp) and (xq,yq), respectively.
303
c
304
      real      pi180
305
      parameter (pi180=3.14159/180.)
306
      real      re
307
      parameter (re=6370.)
308
      real      degkm
309
      parameter (degkm=111.1775)
310
      real      xp,yp,xq,yq,arg
311
 
312
      if ( (abs(xp-xq).gt.0.05).and.(abs(yp-yq).gt.0.05) ) then
313
         arg=sin(pi180*yp)*sin(pi180*yq)+
314
     >       cos(pi180*yp)*cos(pi180*yq)*cos(pi180*(xp-xq))
315
         if (arg.lt.-1.) arg=-1.
316
         if (arg.gt.1.) arg=1.
317
         sdis=re*acos(arg)
318
      else
319
         sdis= (yp-yq)**2 + ( (xp-xq) * cos( pi180*0.5*(yp+yq) ) )**2
320
         sdis = deg2km * sqrt(sdis)
321
      endif
322
 
323
      end
324
 
325
 
326