Subversion Repositories lagranto.ecmwf

Rev

Rev 15 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 15 Rev 19
1
      PROGRAM select
1
      PROGRAM select
2
 
2
 
3
c     **************************************************************
3
c     **************************************************************
4
c     * Select trajectories from LSL file                          *
4
c     * Select trajectories from LSL file                          *
5
c     * Michael Sprenger / January, February 2008                  *
5
c     * Michael Sprenger / January, February 2008                  *
6
c     **************************************************************
6
c     **************************************************************
7
 
7
 
8
      implicit none
8
      implicit none
9
 
9
 
10
c     -------------------------------------------------------------- 
10
c     -------------------------------------------------------------- 
11
c     Declaration of parameters
11
c     Declaration of parameters
12
c     --------------------------------------------------------------
12
c     --------------------------------------------------------------
13
 
13
 
14
c     Maximum number of columns per trajectory
14
c     Maximum number of columns per trajectory
15
      integer          maxcol
15
      integer          maxcol
16
      parameter        (maxcol=100)
16
      parameter        (maxcol=100)
17
      
17
      
18
c     Maximum number of commands
18
c     Maximum number of commands
19
      integer          maxcmd
19
      integer          maxcmd
20
      parameter        (maxcmd=10000)
20
      parameter        (maxcmd=10000)
21
 
21
 
22
c     -------------------------------------------------------------- 
22
c     -------------------------------------------------------------
23
c     Declaration of variables
23
c     Declaration of variables
24
c     --------------------------------------------------------------
24
c     --------------------------------------------------------------
25
 
25
 
26
c     Input and output files
26
c     Input and output files
27
      character*120     inp_lslfile                  ! Input lsl file
27
      character*120     inp_lslfile                  ! Input lsl file
28
      character*120     out_lslfile                  ! Output lsl file
28
      character*120     out_lslfile                  ! Output lsl file
29
      character*120     inp_criteria                 ! Input file with criteria
29
      character*120     inp_criteria                 ! Input file with criteria
30
      integer           inpmode                      ! Format of input file
30
      integer           inpmode                      ! Format of input file
31
      integer           outmode                      ! Format of output file
31
      integer           outmode                      ! Format of output file
32
      character*80      outformat                    ! Trajectory/Boolean/Index of output   
32
      character*80      outformat                    ! Trajectory/Boolean/Index of output   
33
      character*80      regionf                      ! Name of the regionfile
33
      character*80      regionf                      ! Name of the regionfile
34
 
34
 
35
c     Trajectories
35
c     Trajectories
36
      integer          ntim                          ! Number of times 
36
      integer          ntim                          ! Number of times 
37
      integer          ncol                          ! Number of columns (including time...)
37
      integer          ncol                          ! Number of columns (including time...)
38
      integer          ntrainp,ntraout               ! Number of trajectories
38
      integer          ntrainp,ntraout               ! Number of trajectories
39
      character*80     vars(maxcol)                  ! Names of trajectory columns
39
      character*80     vars(maxcol)                  ! Names of trajectory columns
40
      integer          basetime(6)                   ! Base time of trajectory (first line in lsl)
40
      integer          basetime(6)                   ! Base time of trajectory (first line in lsl)
41
      real,allocatable, dimension (:,:,:) :: trainp  ! Input trajectories
41
      real,allocatable, dimension (:,:,:) :: trainp  ! Input trajectories
42
      real,allocatable, dimension (:,:,:) :: traout  ! Output trajectories
42
      real,allocatable, dimension (:,:,:) :: traout  ! Output trajectories
43
      integer,allocatable,dimension (:)   :: selflag ! Flag for selection
43
      integer,allocatable,dimension (:)   :: selflag ! Flag for selection
44
      real,allocatable, dimension (:)     :: time    ! Times of the trajectory
44
      real,allocatable, dimension (:)     :: time    ! Times of the trajectory
45
      integer,allocatable,dimension (:,:) :: trigger ! Trigger column 
45
      integer,allocatable,dimension (:,:) :: trigger ! Trigger column 
46
      integer          itrigger                      ! Column index for trigger
46
      integer          itrigger                      ! Column index for trigger
47
      character*80     addtrigger                    ! Flag whether to add trigger column
47
      character*80     addtrigger                    ! Flag whether to add trigger column
48
 
48
 
49
c     Command stack
49
c     Command stack
50
      real             cmd(maxcmd)                   ! Decoded slection criterion
50
      real             cmd(maxcmd)                   ! Decoded slection criterion
51
      integer          ncmd                          ! Number of commands
51
      integer          ncmd                          ! Number of commands
52
 
52
 
53
c     Common block for initialisation of polygon check
53
c     Common block for initialisation of polygon check
54
      real    tlonv(2000),vlat_c(2000),vlon_c(2000)
54
      real    tlonv(2000),vlat_c(2000),vlon_c(2000)
55
      real    xlat_c,xlon_c
55
      real    xlat_c,xlon_c
56
      integer ibndry,nv_c
56
      integer ibndry,nv_c
57
      data    ibndry/0/
57
      data    ibndry/0/
58
      common  /spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry
58
      common  /spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry
59
 
59
 
60
c     Auxiliary variables
60
c     Auxiliary variables
61
      integer          stat                          ! Logical (state) variable
61
      integer          stat                          ! Logical (state) variable
62
      integer          fid,fod,fcr                   ! File identifier for input and output
62
      integer          fid,fod,fcr                   ! File identifier for input and output
63
      integer          i,j,k                         ! Index counter
63
      integer          i,j,k                         ! Index counter
64
      integer          isok                          ! Flag for selected trajectory
64
      integer          isok                          ! Flag for selected trajectory
65
      real             param(1000)                   ! List of parameters
65
      real             param(1000)                   ! List of parameters
66
      integer          nparam                        ! Number of parameters
66
      integer          nparam                        ! Number of parameters
67
      character*80     specialstr                    ! Name of special command
67
      character*80     specialstr                    ! Name of special command
68
      integer          len
68
      integer          len
69
      integer,allocatable,dimension (:) :: trigger1  ! Trigger column 
69
      integer,allocatable,dimension (:) :: trigger1  ! Trigger column 
70
      real,allocatable,dimension (:,:) :: trainp1    ! A single trajectory
70
      real,allocatable,dimension (:,:) :: trainp1    ! A single trajectory
71
      character        ch
71
      character        ch
72
 
72
 
73
c     -------------------------------------------------------------- 
73
c     -------------------------------------------------------------- 
74
c     Preparations
74
c     Preparations
75
c     --------------------------------------------------------------
75
c     --------------------------------------------------------------
76
 
76
 
77
c     Write start message
77
c     Write start message
78
      print*,'========================================================='
78
      print*,'========================================================='
79
      print*,'              *** START OF PROGRAM SELECT ***'
79
      print*,'              *** START OF PROGRAM SELECT ***'
80
      print*
80
      print*
81
 
81
 
82
c     Read parameter file
82
c     Read parameter file
83
      open(10,file='select.param')
83
      open(10,file='select.param')
84
       read(10,*) inp_lslfile
84
       read(10,*) inp_lslfile
85
       read(10,*) out_lslfile
85
       read(10,*) out_lslfile
86
       read(10,*) outformat
86
       read(10,*) outformat
87
       read(10,*) inp_criteria
87
       read(10,*) inp_criteria
88
       read(10,*) ntrainp
88
       read(10,*) ntrainp
89
       read(10,*) ntim
89
       read(10,*) ntim
90
       read(10,*) ncol
90
       read(10,*) ncol
91
       read(10,*) regionf
91
       read(10,*) regionf
92
       read(10,*) addtrigger
92
       read(10,*) addtrigger
93
      close(10)
93
      close(10)
94
      
94
      
95
c     Set the formats of the input and output files
95
c     Set the formats of the input and output files
96
      call mode_tra(inpmode,inp_lslfile)
96
      call mode_tra(inpmode,inp_lslfile)
97
      if (inpmode.eq.-1) inpmode=1
97
      if (inpmode.eq.-1) inpmode=1
98
      call mode_tra(outmode,out_lslfile)
98
      call mode_tra(outmode,out_lslfile)
99
      if ( (outmode.eq.-1).and.(outformat.ne.'startf') ) then
99
      if ( (outmode.eq.-1).and.(outformat.ne.'startf') ) then
100
         outmode=1
100
         outmode=1
101
      endif
101
      endif
102
 
102
 
103
c     Allocate memory for a single trajectory
103
c     Allocate memory for a single trajectory
104
      allocate(trainp(ntrainp,ntim,ncol),stat=stat)
104
      allocate(trainp(ntrainp,ntim,ncol),stat=stat)
105
      if (stat.ne.0) stop '*** error allocating array trainp   ***'
105
      if (stat.ne.0) stop '*** error allocating array trainp   ***'
106
      allocate(time(ntim),stat=stat)
106
      allocate(time(ntim),stat=stat)
107
      if (stat.ne.0) stop '*** error allocating array time     ***'
107
      if (stat.ne.0) stop '*** error allocating array time     ***'
108
      allocate(selflag(ntrainp),stat=stat)
108
      allocate(selflag(ntrainp),stat=stat)
109
      if (stat.ne.0) stop '*** error allocating array selflag  ***'
109
      if (stat.ne.0) stop '*** error allocating array selflag  ***'
110
      allocate(trigger(ntrainp,ntim),stat=stat)
110
      allocate(trigger(ntrainp,ntim),stat=stat)
111
      if (stat.ne.0) stop '*** error allocating array trigger  ***'
111
      if (stat.ne.0) stop '*** error allocating array trigger  ***'
112
      allocate(trigger1(ntim),stat=stat)
112
      allocate(trigger1(ntim),stat=stat)
113
      if (stat.ne.0) stop '*** error allocating array trigger1 ***'
113
      if (stat.ne.0) stop '*** error allocating array trigger1 ***'
114
      allocate(trainp1(ntim,ncol),stat=stat)
114
      allocate(trainp1(ntim,ncol),stat=stat)
115
      if (stat.ne.0) stop '*** error allocating array trainp1  ***'
115
      if (stat.ne.0) stop '*** error allocating array trainp1  ***'
116
 
116
 
117
c     Read the input trajectory file
117
c     Read the input trajectory file
118
      call ropen_tra(fid,inp_lslfile,ntrainp,ntim,ncol,
118
      call ropen_tra(fid,inp_lslfile,ntrainp,ntim,ncol,
119
     >               basetime,vars,inpmode)
119
     >               basetime,vars,inpmode)
120
      call read_tra (fid,trainp,ntrainp,ntim,ncol,inpmode)
120
      call read_tra (fid,trainp,ntrainp,ntim,ncol,inpmode)
121
      call close_tra(fid,inpmode)
121
      call close_tra(fid,inpmode)
122
 
122
 
123
c     Check that first four columns correspond to time,lon,lat,p
123
c     Check that first four columns correspond to time,lon,lat,p
124
      if ( (vars(1).ne.'time' ).or.
124
      if ( (vars(1).ne.'time' ).or.
125
     >     (vars(2).ne.'xpos' ).and.(vars(2).ne.'lon' ).or.
125
     >     (vars(2).ne.'xpos' ).and.(vars(2).ne.'lon' ).or.
126
     >     (vars(3).ne.'ypos' ).and.(vars(3).ne.'lat' ).or.
126
     >     (vars(3).ne.'ypos' ).and.(vars(3).ne.'lat' ).or.
127
     >     (vars(4).ne.'ppos' ).and.(vars(4).ne.'p'   ) )
127
     >     (vars(4).ne.'ppos' ).and.(vars(4).ne.'p'   ) )
128
     >then
128
     >then
129
         print*,' ERROR: problem with input trajectories ...'
129
         print*,' ERROR: problem with input trajectories ...'
130
         stop
130
         stop
131
      endif
131
      endif
132
      vars(1) = 'time'
132
      vars(1) = 'time'
133
      vars(2) = 'lon'
133
      vars(2) = 'lon'
134
      vars(3) = 'lat'
134
      vars(3) = 'lat'
135
      vars(4) = 'p'
135
      vars(4) = 'p'
136
 
136
 
137
c     Get the trajectory times from first trajectory
137
c     Get the trajectory times from first trajectory
138
      do i=1,ntim
138
      do i=1,ntim
139
         time(i)=trainp(1,i,1)
139
         time(i)=trainp(1,i,1)
140
      enddo
140
      enddo
141
 
141
 
142
c     Init the trigger field - first check whether it is already available
142
c     Init the trigger field - first check whether it is already available
143
      itrigger = 0
143
      itrigger = 0
144
      do i=1,ncol
144
      do i=1,ncol
145
         if ( vars(i).eq.'TRIGGER' ) itrigger = i
145
         if ( vars(i).eq.'TRIGGER' ) itrigger = i
146
      enddo
146
      enddo
147
 
147
 
148
      if ( itrigger.ne.0 ) then
148
      if ( itrigger.ne.0 ) then
149
         do i=1,ntrainp
149
         do i=1,ntrainp
150
            do j=1,ntim
150
            do j=1,ntim
151
               trigger(i,j) = nint( trainp(i,j,itrigger) )
151
               trigger(i,j) = nint( trainp(i,j,itrigger) )
152
            enddo
152
            enddo
153
         enddo
153
         enddo
154
      else
154
      else
155
         do i=1,ntrainp
155
         do i=1,ntrainp
156
            do j=1,ntim
156
            do j=1,ntim
157
               trigger(i,j) = 0
157
               trigger(i,j) = 0
158
            enddo
158
            enddo
159
         enddo
159
         enddo
160
      endif
160
      endif
161
 
161
 
162
c     Write some info about the trajectory
162
c     Write some info about the trajectory
163
      print*,'---- INPUT PARAMETERS -----------------------------------'
163
      print*,'---- INPUT PARAMETERS -----------------------------------'
164
      write(*,*) 
164
      write(*,*) 
165
      write(*,*) 'Input file    : ',trim(inp_lslfile)
165
      write(*,*) 'Input file    : ',trim(inp_lslfile)
166
      write(*,*) 'Output file   : ',trim(out_lslfile)
166
      write(*,*) 'Output file   : ',trim(out_lslfile)
167
      write(*,*) 'Output format : ',trim(outformat)
167
      write(*,*) 'Output format : ',trim(outformat)
168
      write(*,*) 'Criteria file : ',trim(inp_criteria)
168
      write(*,*) 'Criteria file : ',trim(inp_criteria)
169
      write(*,*) '# tra         : ',ntrainp
169
      write(*,*) '# tra         : ',ntrainp
170
      write(*,*) '# time        : ',ntim
170
      write(*,*) '# time        : ',ntim
171
      write(*,*) '# col         : ',ncol
171
      write(*,*) '# col         : ',ncol
172
      write(*,*) 'Region file   : ',trim(regionf)
172
      write(*,*) 'Region file   : ',trim(regionf)
173
      write(*,*) 'Add trigger   : ',trim(addtrigger)
173
      write(*,*) 'Add trigger   : ',trim(addtrigger)
174
      
174
      
175
      print*
175
      print*
176
      print*,'---- INPUT TRAJECTORY FILE ------------------------------'
176
      print*,'---- INPUT TRAJECTORY FILE ------------------------------'
177
      print*
177
      print*
178
      write(*,'(1x,a12,i4,a10)') 'Vars       : ',1,trim(vars(1))
178
      write(*,'(1x,a12,i4,a10)') 'Vars       : ',1,trim(vars(1))
179
      do i=2,ncol
179
      do i=2,ncol
180
         write(*,'(1x,a12,i4,a10)') '             ',i,trim(vars(i))
180
         write(*,'(1x,a12,i4,a10)') '             ',i,trim(vars(i))
181
      enddo
181
      enddo
182
      print*
182
      print*
183
      write(*,'(1x,a12,i4,f10.2)') 'Time       : ',1,time(1)
183
      write(*,'(1x,a12,i4,f10.2)') 'Time       : ',1,time(1)
184
      do i=2,ntim
184
      do i=2,ntim
185
         write(*,'(1x,a12,i4,f10.2)') '             ',i,time(i)
185
         write(*,'(1x,a12,i4,f10.2)') '             ',i,time(i)
186
      enddo
186
      enddo
187
      print*
187
      print*
188
      write(*,'(1x,a12,i4,i10)') 'Base date  : ',1,basetime(1)
188
      write(*,'(1x,a12,i4,i10)') 'Base date  : ',1,basetime(1)
189
      write(*,'(1x,a12,i4,i10)') '             ',2,basetime(2)
189
      write(*,'(1x,a12,i4,i10)') '             ',2,basetime(2)
190
      write(*,'(1x,a12,i4,i10)') '             ',3,basetime(3)
190
      write(*,'(1x,a12,i4,i10)') '             ',3,basetime(3)
191
      write(*,'(1x,a12,i4,i10)') '             ',4,basetime(4)
191
      write(*,'(1x,a12,i4,i10)') '             ',4,basetime(4)
192
      write(*,'(1x,a12,i4,i10)') '             ',5,basetime(5)      
192
      write(*,'(1x,a12,i4,i10)') '             ',5,basetime(5)      
193
      print*
193
      print*
194
      write(*,'(1x,a12,i4,i10)') 'Time range : ',6,basetime(6)
194
      write(*,'(1x,a12,i4,i10)') 'Time range : ',6,basetime(6)
195
      print*
195
      print*
196
      if ( itrigger.ne.0 ) then
196
      if ( itrigger.ne.0 ) then
197
         print*,'TRIGGER FIELD FOUND IN COLUMN ',itrigger
197
         print*,'TRIGGER FIELD FOUND IN COLUMN ',itrigger
198
         print*
198
         print*
199
      endif
199
      endif
200
 
200
 
201
c     Read and decode the selection criterion
201
c     Read and decode the selection criterion
202
      fcr = 10
202
      fcr = 10
203
      open(fcr,file=inp_criteria)
203
      open(fcr,file=inp_criteria)
204
      ncmd=maxcmd
204
      ncmd=maxcmd
205
      call decode(fcr,cmd,ncmd,vars,ncol,time,ntim,regionf)
205
      call decode(fcr,cmd,ncmd,vars,ncol,time,ntim,regionf)
206
      close(fcr)
206
      close(fcr)
207
 
207
 
208
      print*
208
      print*
209
      print*,'---- PSEUDO CODE FOR SELECTION --------------------------'
209
      print*,'---- PSEUDO CODE FOR SELECTION --------------------------'
210
      print*
210
      print*
211
      call dumpcode(cmd,ncmd,vars,ncol,time,ntim)
211
      call dumpcode(cmd,ncmd,vars,ncol,time,ntim)
212
 
212
 
213
c     -------------------------------------------------------------- 
213
c     -------------------------------------------------------------- 
214
c     Loop over all trajectories - selection
214
c     Loop over all trajectories - selection
215
c     --------------------------------------------------------------
215
c     --------------------------------------------------------------
216
 
216
 
217
c     Prepare string and parameters for SPECIAL commands
217
c     Prepare string and parameters for SPECIAL commands
218
      if ( cmd(1).eq.0 ) then
218
      if ( cmd(1).eq.0 ) then
219
 
219
 
220
c        Get command string
220
c        Get command string
221
         j   = 2
221
         j   = 2
222
         len = nint(cmd(j))
222
         len = nint(cmd(j))
223
         specialstr = ''
223
         specialstr = ''
224
         do k=1,len
224
         do k=1,len
225
            j = j + 1
225
            j = j + 1
226
            specialstr = trim(specialstr)//char(nint(cmd(j)))
226
            specialstr = trim(specialstr)//char(nint(cmd(j)))
227
         enddo
227
         enddo
228
         
228
         
229
c        Get paramters
229
c        Get paramters
230
         j      = j + 1
230
         j      = j + 1
231
         nparam = nint(cmd(j))
231
         nparam = nint(cmd(j))
232
         do k=1,nparam
232
         do k=1,nparam
233
            j        = j + 1
233
            j        = j + 1
234
            param(k) = cmd(j)
234
            param(k) = cmd(j)
235
         enddo
235
         enddo
236
         
236
         
237
      endif
237
      endif
238
        
238
        
239
c     Init the counter for selected trajectories
239
c     Init the counter for selected trajectories
240
      ntraout = 0
240
      ntraout = 0
241
 
241
 
242
c     Loop over all trajectories
242
c     Loop over all trajectories
243
      do i=1,ntrainp
243
      do i=1,ntrainp
244
 
244
 
245
c       Copy a single trajectory to <trainp1> and <trigger1>
245
c       Copy a single trajectory to <trainp1> and <trigger1>
246
        do j=1,ntim
246
        do j=1,ntim
247
           do k=1,ncol
247
           do k=1,ncol
248
              trainp1(j,k) = trainp(i,j,k)
248
              trainp1(j,k) = trainp(i,j,k)
249
           enddo
249
           enddo
250
           trigger1(j) = trigger(i,j)
250
           trigger1(j) = trigger(i,j)
251
        enddo
251
        enddo
252
 
252
 
253
C	    Skip the trajectory if missing data are found for positions
253
C	    Skip the trajectory if missing data are found for positions
254
        isok = 1
254
        isok = 1
255
        do j=1,ntim
255
        do j=1,ntim
256
           if ( trainp1(j,4).lt.0. ) isok = 0
256
           if ( trainp1(j,4).lt.0. ) isok = 0
257
        enddo
257
        enddo
258
 
258
 
259
c       Decide whether the trajectory is selected (handle SPECIAL commands)
259
c       Decide whether the trajectory is selected (handle SPECIAL commands)
260
        if ( isok.eq.1 ) then
260
        if ( isok.eq.1 ) then
261
           if (cmd(1).ne.0 ) then
261
           if (cmd(1).ne.0 ) then
262
              call select_tra (isok,cmd,ncmd,trainp1,trigger1,ntim,ncol)
262
              call select_tra (isok,cmd,ncmd,trainp1,trigger1,ntim,ncol)
263
 
263
 
264
           else
264
           else
265
              call special    (isok,specialstr,trainp1,ntim,ncol,
265
              call special    (isok,specialstr,trainp1,ntim,ncol,
266
     >                         vars,time,param,nparam)
266
     >                         vars,time,param,nparam)
267
           endif
267
           endif
268
	    endif
268
	    endif
269
 
269
 
270
c       The trigger might be changed in the selection - copy it
270
c       The trigger might be changed in the selection - copy it
271
        do j=1,ntim
271
        do j=1,ntim
272
            trigger(i,j) = trigger1(j)
272
            trigger(i,j) = trigger1(j)
273
        enddo
273
        enddo
274
 
274
 
275
c       Set flag for selected trajectories
275
c       Set flag for selected trajectories
276
        if (isok.eq.1) then
276
        if (isok.eq.1) then
277
           selflag(i)          = 1
277
           selflag(i)          = 1
278
           ntraout             = ntraout + 1
278
           ntraout             = ntraout + 1
279
        else
279
        else
280
           selflag(i)          = 0
280
           selflag(i)          = 0
281
        endif
281
        endif
282
 
282
 
283
      enddo
283
      enddo
284
 
284
 
285
c     -------------------------------------------------------------- 
285
c     -------------------------------------------------------------- 
286
c     Write output trajectories
286
c     Write output trajectories
287
c     --------------------------------------------------------------
287
c     --------------------------------------------------------------
288
 
288
 
289
c     ------ Write output trajectories -----------------------------
289
c     ------ Write output trajectories -----------------------------
290
      if ( outformat.eq.'trajectory' ) then
290
      if ( outformat.eq.'trajectory' ) then
291
 
291
 
292
 
292
 
293
c        Define the trigger field if it is not yet defined
293
c        Define the trigger field if it is not yet defined
294
         if ( ( addtrigger.eq.'-trigger' ).and.(itrigger.eq.0) ) then
294
         if ( ( addtrigger.eq.'-trigger' ).and.(itrigger.eq.0) ) then
295
            ncol       = ncol + 1
295
            ncol       = ncol + 1
296
            vars(ncol) = 'TRIGGER'
296
            vars(ncol) = 'TRIGGER'
297
            itrigger   = ncol
297
            itrigger   = ncol
298
         endif
298
         endif
299
 
299
 
300
c        Allocate memory for output trajectory
300
c        Allocate memory for output trajectory
301
         allocate(traout(ntraout,ntim,ncol),stat=stat)
301
         allocate(traout(ntraout,ntim,ncol),stat=stat)
302
         if (stat.ne.0) stop '*** error allocating array apply   ***'
302
         if (stat.ne.0) stop '*** error allocating array apply   ***'
303
 
303
 
304
c        Set output trajectories
304
c        Set output trajectories
305
         j = 0
305
         j = 0
306
         do i=1,ntrainp
306
         do i=1,ntrainp
307
            if (selflag(i).eq.1) then
307
            if (selflag(i).eq.1) then
308
               j             = j + 1 
308
               j             = j + 1 
309
               traout(j,1:ntim,1:ncol) = trainp(i,1:ntim,1:ncol)
309
               traout(j,1:ntim,1:ncol) = trainp(i,1:ntim,1:ncol)
310
               if ( itrigger.ne.0 ) then
310
               if ( itrigger.ne.0 ) then
311
                  traout(j,1:ntim,itrigger) = real(trigger(i,1:ntim))
311
                  traout(j,1:ntim,itrigger) = real(trigger(i,1:ntim))
312
               endif
312
               endif
313
            endif
313
            endif
314
         enddo
314
         enddo
315
 
315
 
316
c        Write trajectories
316
c        Write trajectories
317
         call wopen_tra(fod,out_lslfile,ntraout,ntim,ncol,
317
         call wopen_tra(fod,out_lslfile,ntraout,ntim,ncol,
318
     >        basetime,vars,outmode)
318
     >        basetime,vars,outmode)
319
         call write_tra(fod,traout,ntraout,ntim,ncol,outmode)
319
         call write_tra(fod,traout,ntraout,ntim,ncol,outmode)
320
         call close_tra(fod,outmode)
320
         call close_tra(fod,outmode)
321
         
321
         
322
c     ------ Write index list -------------------------------------
322
c     ------ Write index list -------------------------------------
323
      elseif ( outformat.eq.'index' ) then
323
      elseif ( outformat.eq.'index' ) then
324
         
324
         
325
         open(10,file=out_lslfile)
325
         open(10,file=out_lslfile)
326
          do i=1,ntrainp
326
          do i=1,ntrainp
327
             if ( selflag(i).eq.1) write(10,*) i
327
             if ( selflag(i).eq.1) write(10,*) i
328
          enddo
328
          enddo
329
         close(10)
329
         close(10)
330
 
330
 
331
c     ------ Write boolean list -----------------------------------
331
c     ------ Write boolean list -----------------------------------
332
      elseif ( outformat.eq.'boolean' ) then
332
      elseif ( outformat.eq.'boolean' ) then
333
         
333
         
334
         open(10,file=out_lslfile)
334
         open(10,file=out_lslfile)
335
          do i=1,ntrainp
335
          do i=1,ntrainp
336
             write(10,'(i1)') selflag(i)
336
             write(10,'(i1)') selflag(i)
337
          enddo
337
          enddo
338
         close(10)
338
         close(10)
339
 
339
 
340
c     ------ Write count -------------------------------------------
340
c     ------ Write count -------------------------------------------
341
      elseif ( outformat.eq.'count' ) then
341
      elseif ( outformat.eq.'count' ) then
342
 
342
 
343
         open(10,file=out_lslfile)
343
         open(10,file=out_lslfile)
344
          write(10,'(i7)') ntraout
344
          write(10,'(i7)') ntraout
345
         close(10)
345
         close(10)
346
 
346
 
347
c     ------ Write starting positions -----------------------------
347
c     ------ Write starting positions -----------------------------
348
      elseif ( outformat.eq.'startf' ) then
348
      elseif ( outformat.eq.'startf' ) then
349
 
349
 
350
c        Allocate memory for output trajectory
350
c        Allocate memory for output trajectory
351
         allocate(traout(ntraout,1,ncol),stat=stat)
351
         allocate(traout(ntraout,1,ncol),stat=stat)
352
         if (stat.ne.0) stop '*** error allocating array apply   ***'
352
         if (stat.ne.0) stop '*** error allocating array apply   ***'
353
 
353
 
354
c        Set output trajectories
354
c        Set output trajectories
355
         j = 0
355
         j = 0
356
         do i=1,ntrainp
356
         do i=1,ntrainp
357
            if (selflag(i).eq.1) then
357
            if (selflag(i).eq.1) then
358
               j             = j + 1 
358
               j             = j + 1 
359
               traout(j,1,:) = trainp(i,1,:)
359
               traout(j,1,:) = trainp(i,1,:)
360
            endif
360
            endif
361
         enddo
361
         enddo
362
 
362
 
363
c        Write trajectories
363
c        Write trajectories
364
         if (outmode.ne.-1) then
364
         if (outmode.ne.-1) then
365
            
365
            
366
           call wopen_tra(fod,out_lslfile,ntraout,1,ncol,
366
           call wopen_tra(fod,out_lslfile,ntraout,1,ncol,
367
     >                    basetime,vars,outmode)
367
     >                    basetime,vars,outmode)
368
           call write_tra(fod,traout,ntraout,1,ncol,outmode)
368
           call write_tra(fod,traout,ntraout,1,ncol,outmode)
369
           call close_tra(fod,outmode)       
369
           call close_tra(fod,outmode)       
370
 
370
 
371
c        Output as a triple list (corresponding to <startf> file)
371
c        Output as a triple list (corresponding to <startf> file)
372
         else
372
         else
373
         
373
         
374
           fid = 10
374
           fid = 10
375
           open(fid,file=out_lslfile)
375
           open(fid,file=out_lslfile)
376
            do i=1,ntraout
376
            do i=1,ntraout
377
              write(fid,'(3f10.3)') traout(i,1,2),   ! longitude
377
              write(fid,'(3f10.3)') traout(i,1,2),   ! longitude
378
     >                            traout(i,1,3),   ! latitude
378
     >                            traout(i,1,3),   ! latitude
379
     >                            traout(i,1,4)    ! pressure
379
     >                            traout(i,1,4)    ! pressure
380
            enddo
380
            enddo
381
           close(fid)
381
           close(fid)
382
 
382
 
383
        endif
383
        endif
384
  
384
  
385
      endif
385
      endif
386
 
386
 
387
c     Write some status information, and end of program message
387
c     Write some status information, and end of program message
388
      print*  
388
      print*  
389
      print*,'---- STATUS INFORMATION --------------------------------'
389
      print*,'---- STATUS INFORMATION --------------------------------'
390
      print*
390
      print*
391
      print*,' # input trajectories  : ',ntrainp
391
      print*,' # input trajectories  : ',ntrainp
392
      print*,' # output trajectories : ',ntraout
392
      print*,' # output trajectories : ',ntraout
393
      print*
393
      print*
394
      print*,'              *** END OF PROGRAM SELECT ***'
394
      print*,'              *** END OF PROGRAM SELECT ***'
395
      print*,'========================================================='
395
      print*,'========================================================='
396
 
396
 
397
      stop
397
      stop
398
      
398
      
399
c     Exception handling
399
c     Exception handling
400
 100  stop 'select: First column in input trajectory must be <time>'
400
 100  stop 'select: First column in input trajectory must be <time>'
401
 101  stop 'select: Input trajectory file is empty'
401
 101  stop 'select: Input trajectory file is empty'
402
 
402
 
403
      end
403
      end
404
 
404
 
405
c     -------------------------------------------------------------- 
405
c     -------------------------------------------------------------- 
406
c     Dump the command list
406
c     Dump the command list
407
c     --------------------------------------------------------------
407
c     --------------------------------------------------------------
408
      
408
      
409
      subroutine dumpcode(out,n,vars,nvars,times,ntimes)
409
      subroutine dumpcode(out,n,vars,nvars,times,ntimes)
410
 
410
 
411
c     Write the command list to screen. The command list is decoded
411
c     Write the command list to screen. The command list is decoded
412
c     by call to <decode>
412
c     by call to <decode>
413
 
413
 
414
      implicit none
414
      implicit none
415
 
415
 
416
c     Declaration of subroutine parameters
416
c     Declaration of subroutine parameters
417
      integer      n
417
      integer      n
418
      real         out(n)
418
      real         out(n)
419
      integer      nvars
419
      integer      nvars
420
      character*80 vars(nvars)
420
      character*80 vars(nvars)
421
      integer      ntimes
421
      integer      ntimes
422
      real         times(ntimes)
422
      real         times(ntimes)
423
 
423
 
424
c     A single command
424
c     A single command
425
      character*80 cmd
425
      character*80 cmd
426
      character*80 var,mode,strtim
426
      character*80 var,mode,strtim
427
      integer      nval
427
      integer      nval
428
      integer      ntim
428
      integer      ntim
429
      integer      ivar,imode,icmd,itime
429
      integer      ivar,imode,icmd,itime
430
 
430
 
431
c     Auxiliary variables
431
c     Auxiliary variables
432
      integer      i,j
432
      integer      i,j
433
 
433
 
434
c     Loop through the complete list
434
c     Loop through the complete list
435
      i=0
435
      i=0
436
 100  if (i.lt.n) then 
436
 100  if (i.lt.n) then 
437
 
437
 
438
         write(*,*) '---------------------------------------'
438
         write(*,*) '---------------------------------------'
439
 
439
 
440
c        Get command
440
c        Get command
441
         i=i+1
441
         i=i+1
442
         icmd=nint(out(i))
442
         icmd=nint(out(i))
443
 
443
 
444
c        Special handling of SPECIAL commands
444
c        Special handling of SPECIAL commands
445
         if ( icmd.eq.0 ) then
445
         if ( icmd.eq.0 ) then
446
 
446
 
447
c           Write 'header' for SPECIAL command
447
c           Write 'header' for SPECIAL command
448
            write(*,'(i5,f15.4,10x,a10)') i,out(i),'SPECIAL'
448
            write(*,'(i5,f15.4,10x,a10)') i,out(i),'SPECIAL'
449
 
449
 
450
c           Write command string
450
c           Write command string
451
            i = i + 1
451
            i = i + 1
452
            icmd = nint(out(i))
452
            icmd = nint(out(i))
453
            write(*,'(i5,f15.4,10x,a10)') i,out(i),'LEN(CMD)'
453
            write(*,'(i5,f15.4,10x,a10)') i,out(i),'LEN(CMD)'
454
            do j=1,icmd
454
            do j=1,icmd
455
               i    = i + 1
455
               i    = i + 1
456
               ivar = nint(out(i))
456
               ivar = nint(out(i))
457
               write(*,'(i5,f15.4,10x,a10)') i,out(i),char(ivar)
457
               write(*,'(i5,f15.4,10x,a10)') i,out(i),char(ivar)
458
            enddo
458
            enddo
459
 
459
 
460
c           Write parameters
460
c           Write parameters
461
            i    = i + 1
461
            i    = i + 1
462
            nval = nint(out(i))
462
            nval = nint(out(i))
463
            write(*,'(i5,f15.4,10x,a10)') i,out(i),'#PARAMETER'
463
            write(*,'(i5,f15.4,10x,a10)') i,out(i),'#PARAMETER'
464
            do j=1,nval
464
            do j=1,nval
465
               i=i+1
465
               i=i+1
466
               if ( var.ne.'INPOLYGON' ) then
466
               if ( var.ne.'INPOLYGON' ) then
467
                  write(*,'(i5,f15.4)') i,out(i)
467
                  write(*,'(i5,f15.4)') i,out(i)
468
               else
468
               else
469
                  write(*,'(i5,f15.4,a2)') i,out(i),char(nint(out(i)))
469
                  write(*,'(i5,f15.4,a2)') i,out(i),char(nint(out(i)))
470
               endif
470
               endif
471
            enddo
471
            enddo
472
 
472
 
473
c           Nothing else to do - exit
473
c           Nothing else to do - exit
474
            goto 200
474
            goto 200
475
            
475
            
476
         endif
476
         endif
477
 
477
 
478
c        Set the command
478
c        Set the command
479
         if (icmd.eq.  1) cmd='GT'
479
         if (icmd.eq.  1) cmd='GT'
480
         if (icmd.eq.  2) cmd='LT'
480
         if (icmd.eq.  2) cmd='LT'
481
         if (icmd.eq.  3) cmd='IN'
481
         if (icmd.eq.  3) cmd='IN'
482
         if (icmd.eq.  4) cmd='OUT'
482
         if (icmd.eq.  4) cmd='OUT'
483
         if (icmd.eq.  5) cmd='EQ'
483
         if (icmd.eq.  5) cmd='EQ'
484
         if (icmd.eq.  6) cmd='TRUE'
484
         if (icmd.eq.  6) cmd='TRUE'
485
         if (icmd.eq.  7) cmd='FALSE'
485
         if (icmd.eq.  7) cmd='FALSE'
486
         if (icmd.eq.  8) cmd='ALL'
486
         if (icmd.eq.  8) cmd='ALL'
487
         if (icmd.eq.  9) cmd='ANY'
487
         if (icmd.eq.  9) cmd='ANY'
488
         if (icmd.eq. 10) cmd='NONE'
488
         if (icmd.eq. 10) cmd='NONE'
489
         if (icmd.eq. -1) cmd='BEGIN'
489
         if (icmd.eq. -1) cmd='BEGIN'
490
         if (icmd.eq. -2) cmd='END'
490
         if (icmd.eq. -2) cmd='END'
491
         if (icmd.eq. -3) cmd='AND'
491
         if (icmd.eq. -3) cmd='AND'
492
         if (icmd.eq. -4) cmd='OR'
492
         if (icmd.eq. -4) cmd='OR'
493
         write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(cmd)
493
         write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(cmd)
494
         if (icmd.lt.0) goto 100
494
         if (icmd.lt.0) goto 100
495
 
495
 
496
c        Get variable
496
c        Get variable
497
         i=i+1
497
         i=i+1
498
         ivar=nint(out(i))
498
         ivar=nint(out(i))
499
         if ( ivar.eq. -1 ) then
499
         if ( ivar.eq. -1 ) then
500
            var = 'DIST'
500
            var = 'DIST'
501
         elseif ( ivar.eq. -2 ) then
501
         elseif ( ivar.eq. -2 ) then
502
            var = 'DIST0'
502
            var = 'DIST0'
503
         elseif ( ivar.eq. -3 ) then
503
         elseif ( ivar.eq. -3 ) then
504
            var = 'INPOLYGON'
504
            var = 'INPOLYGON'
505
         elseif ( ivar.eq. -4 ) then
505
         elseif ( ivar.eq. -4 ) then
506
            var = 'INBOX'
506
            var = 'INBOX'
507
         elseif ( ivar.eq. -5 ) then
507
         elseif ( ivar.eq. -5 ) then
508
            var = 'INCIRCLE'
508
            var = 'INCIRCLE'
509
         elseif ( ivar.eq. -6 ) then
509
         elseif ( ivar.eq. -6 ) then
510
            var = 'INREGION'
510
            var = 'INREGION'
511
         elseif ( ivar.eq. -7 ) then
511
         elseif ( ivar.eq. -7 ) then
512
            var = 'TRIGGER'
512
            var = 'TRIGGER'
513
         elseif ( ivar.eq. -8 ) then
513
         elseif ( ivar.eq. -8 ) then
514
            var = 'VERT0'
514
            var = 'VERT0'
515
         else
515
         else
516
            var=vars(ivar)
516
            var=vars(ivar)
517
         endif
517
         endif
518
         write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(var)
518
         write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(var)
519
 
519
 
520
c        Get variable mode
520
c        Get variable mode
521
         i=i+1
521
         i=i+1
522
         imode=nint(out(i))
522
         imode=nint(out(i))
523
         if (imode.eq.1 ) mode='VALUE'
523
         if (imode.eq.1 ) mode='VALUE'
524
         if (imode.eq.2 ) mode='MEAN'
524
         if (imode.eq.2 ) mode='MEAN'
525
         if (imode.eq.3 ) mode='MAX'
525
         if (imode.eq.3 ) mode='MAX'
526
         if (imode.eq.4 ) mode='MIN'
526
         if (imode.eq.4 ) mode='MIN'
527
         if (imode.eq.5 ) mode='VAR'
527
         if (imode.eq.5 ) mode='VAR'
528
         if (imode.eq.6 ) mode='SUM'
528
         if (imode.eq.6 ) mode='SUM'
529
         if (imode.eq.7 ) mode='CHANGE'
529
         if (imode.eq.7 ) mode='CHANGE'
530
         if (imode.eq.8 ) mode='DIFF'
530
         if (imode.eq.8 ) mode='DIFF'
531
         if (imode.eq.9 ) mode='RANGE'
531
         if (imode.eq.9 ) mode='RANGE'
532
         if (imode.eq.10) mode='ABS'
532
         if (imode.eq.10) mode='ABS'
533
         write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(mode)
533
         write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(mode)
534
 
534
 
535
c        Get values
535
c        Get values
536
         i=i+1
536
         i=i+1
537
         nval=nint(out(i))
537
         nval=nint(out(i))
538
         write(*,'(i5,f15.4,10x,a10)') i,out(i),'#PARAMETER'
538
         write(*,'(i5,f15.4,10x,a10)') i,out(i),'#PARAMETER'
539
         do j=1,nval
539
         do j=1,nval
540
            i=i+1
540
            i=i+1
541
 
541
 
542
            if ( var.ne.'INPOLYGON' ) then
542
            if ( var.ne.'INPOLYGON' ) then
543
               write(*,'(i5,f15.4)') i,out(i)
543
               write(*,'(i5,f15.4)') i,out(i)
544
            else
544
            else
545
               write(*,'(i5,f15.4,a2)') i,out(i),char(nint(out(i)))
545
               write(*,'(i5,f15.4,a2)') i,out(i),char(nint(out(i)))
546
            endif
546
            endif
547
         enddo
547
         enddo
548
 
548
 
549
c        Get the number of times
549
c        Get the number of times
550
         i=i+1
550
         i=i+1
551
         ntim=nint(out(i))
551
         ntim=nint(out(i))
552
 
552
 
553
c        the number of times is variable - depending on TRIGGER
553
c        the number of times is variable - depending on TRIGGER
554
         if ( ntim .eq. -993 ) then
554
         if ( ntim .eq. -993 ) then
555
            write(*,'(i5,f15.4,7x,7x,a15)') i,out(i),'TIMES @ TRIGGER'
555
            write(*,'(i5,f15.4,7x,7x,a15)') i,out(i),'TIMES @ TRIGGER'
556
 
556
 
557
c        Get the detailed list of times
557
c        Get the detailed list of times
558
         else
558
         else
559
            write(*,'(i5,f15.4,7x,7x,a6)') i,out(i),'#TIMES'
559
            write(*,'(i5,f15.4,7x,7x,a6)') i,out(i),'#TIMES'
560
            do j=1,ntim
560
            do j=1,ntim
561
               i=i+1
561
               i=i+1
562
               write(*,'(i5,f15.4,f7.0)') i,out(i),times(nint(out(i)))
562
               write(*,'(i5,f15.4,f7.0)') i,out(i),times(nint(out(i)))
563
            enddo
563
            enddo
564
         endif
564
         endif
565
 
565
 
566
c        Get time mode
566
c        Get time mode
567
         i=i+1
567
         i=i+1
568
         itime=nint(out(i))
568
         itime=nint(out(i))
569
         if (itime.eq.1) strtim='ALL'
569
         if (itime.eq.1) strtim='ALL'
570
         if (itime.eq.2) strtim='ANY'         
570
         if (itime.eq.2) strtim='ANY'         
571
         if (itime.eq.3) strtim='NONE'
571
         if (itime.eq.3) strtim='NONE'
572
         if (itime.lt.0) strtim='TRIGGER'
572
         if (itime.lt.0) strtim='TRIGGER'
573
 
573
 
574
         if ( strtim.ne.'TRIGGER' ) then
574
         if ( strtim.ne.'TRIGGER' ) then
575
            write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(strtim)
575
            write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(strtim)
576
         else
576
         else
577
            write(*,'(i5,f15.4,10x,a10,a3,i3)') i,out(i),trim(strtim),
577
            write(*,'(i5,f15.4,10x,a10,a3,i3)') i,out(i),trim(strtim),
578
     >                                        ' ->',abs(itime)
578
     >                                        ' ->',abs(itime)
579
         endif
579
         endif
580
 
580
 
581
         goto 100
581
         goto 100
582
         
582
         
583
      endif
583
      endif
584
 
584
 
585
c     Exit point
585
c     Exit point
586
 200  continue
586
 200  continue
587
 
587
 
588
      write(*,*) '---------------------------------------'
588
      write(*,*) '---------------------------------------'
589
 
589
 
590
      end
590
      end
591
         
591
         
592
 
592
 
593
c     -------------------------------------------------------------- 
593
c     -------------------------------------------------------------- 
594
c     Read and decode a selection set
594
c     Read and decode a selection set
595
c     --------------------------------------------------------------
595
c     --------------------------------------------------------------
596
 
596
 
597
      subroutine decode(fid,out,n,vars,nvars,times,ntimes,regionf)
597
      subroutine decode(fid,out,n,vars,nvars,times,ntimes,regionf)
598
 
598
 
599
c     A selection file is opened with file id <fid> and transformed
599
c     A selection file is opened with file id <fid> and transformed
600
c     into a set of commands applied to the trajectories. On input
600
c     into a set of commands applied to the trajectories. On input
601
c     <n> sets the maximum dimension of <out>, on output it gives the
601
c     <n> sets the maximum dimension of <out>, on output it gives the
602
c     total length of the command string. The output is a list of
602
c     total length of the command string. The output is a list of
603
c     commands with the following format:
603
c     commands with the following format:
604
c     
604
c     
605
c        out(i)             = Command 
605
c        out(i)             = Command 
606
c        out(i+1)           = Column index of variable
606
c        out(i+1)           = Column index of variable
607
c        out(i+2)           = Mode for variable
607
c        out(i+2)           = Mode for variable
608
c        out(i+3)           = Number of parameters (n)
608
c        out(i+3)           = Number of parameters (n)
609
c        out(i+4:i+4+n)     = Parameters
609
c        out(i+4:i+4+n)     = Parameters
610
c        out(i+5+n)         = Number of times 
610
c        out(i+5+n)         = Number of times 
611
c        out(i+6+n:i+6+n+m) = List of time indices (m)
611
c        out(i+6+n:i+6+n+m) = List of time indices (m)
612
c        out(i+7+n+m)       = Time mode
612
c        out(i+7+n+m)       = Time mode
613
c     
613
c     
614
c     For SPECIAL commands (to be coded in <special.f>) the format is:
614
c     For SPECIAL commands (to be coded in <special.f>) the format is:
615
c     
615
c     
616
c        out(i)             = Length of command string (n)
616
c        out(i)             = Length of command string (n)
617
c        out(i+1:i+n)       = Command string      
617
c        out(i+1:i+n)       = Command string      
618
c        out(i+n+1)         = Number of parameters (m)
618
c        out(i+n+1)         = Number of parameters (m)
619
c        out(i+n+2:i+n+1+m) = List of parameters
619
c        out(i+n+2:i+n+1+m) = List of parameters
620
c     
620
c     
621
c     The following coding is used
621
c     The following coding is used
622
c      
622
c      
623
c        Command        Variable mode    Time mode
623
c        Command        Variable mode    Time mode
624
c        ----------     -------------    ---------
624
c        ----------     -------------    ---------
625
c        GT       1     VALUE    1       ALL      1
625
c        GT       1     VALUE    1       ALL      1
626
c        LT       2     MEAN     2       ANY      2
626
c        LT       2     MEAN     2       ANY      2
627
c        IN       3     MAX      3       NONE     3
627
c        IN       3     MAX      3       NONE     3
628
c        OUT      4     MIN      4       TRIGGER -i (i the trigger index)
628
c        OUT      4     MIN      4       TRIGGER -i (i the trigger index)
629
c        EQ       5     VAR      5
629
c        EQ       5     VAR      5
630
c        BEGIN   -1     SUM      6
630
c        BEGIN   -1     SUM      6
631
c        END     -2     CHANGE   7 
631
c        END     -2     CHANGE   7 
632
c        AND     -3     DIFF     8
632
c        AND     -3     DIFF     8
633
c        OR      -4     RANGE    9
633
c        OR      -4     RANGE    9
634
c        TRUE     6     ABS     10
634
c        TRUE     6     ABS     10
635
c        FALSE    7
635
c        FALSE    7
636
c        SPECIAL  0
636
c        SPECIAL  0
637
c        ALL      8 (TRIGGER)
637
c        ALL      8 (TRIGGER)
638
c        ANY      9 (TRIGGER)
638
c        ANY      9 (TRIGGER)
639
c        NONE    10 (TRIGGER)
639
c        NONE    10 (TRIGGER)
640
 
640
 
641
 
641
 
642
c     Several "implicit variables" are supported - out(i+1):
642
c     Several "implicit variables" are supported - out(i+1):
643
c     
643
c     
644
c        DIST      -1 : Path length of the trajectory
644
c        DIST      -1 : Path length of the trajectory
645
c        DIST0     -2 : Distance from starting position
645
c        DIST0     -2 : Distance from starting position
646
c        INPOLYGON -3 : Specified polygon region
646
c        INPOLYGON -3 : Specified polygon region
647
c        INBOX     -4 : Longitude/latitude rectangle
647
c        INBOX     -4 : Longitude/latitude rectangle
648
c        INCIRCLE  -5 : Within a specified radius 
648
c        INCIRCLE  -5 : Within a specified radius 
649
c        INREGION  -6 : Within a specified rehion on the region file
649
c        INREGION  -6 : Within a specified rehion on the region file
650
c        TRIGGER   -7 : Trigger field
650
c        TRIGGER   -7 : Trigger field
651
c        VERT0     -8 : Vertical distance from starting position
651
c        VERT0     -8 : Vertical distance from starting position
652
c         
652
c         
653
c     For the special commands BEGIN, END, AND and OR, only one field
653
c     For the special commands BEGIN, END, AND and OR, only one field
654
c     in <out> is used.
654
c     in <out> is used.
655
 
655
 
656
      implicit none
656
      implicit none
657
 
657
 
658
c     Declaration of subroutine parameters
658
c     Declaration of subroutine parameters
659
      integer      fid
659
      integer      fid
660
      integer      n
660
      integer      n
661
      real         out(n)
661
      real         out(n)
662
      integer      nvars
662
      integer      nvars
663
      character*80 vars(nvars)
663
      character*80 vars(nvars)
664
      integer      ntimes
664
      integer      ntimes
665
      real         times(ntimes)
665
      real         times(ntimes)
666
      character*80 regionf
666
      character*80 regionf
667
 
667
 
668
c     Numerical epsilon
668
c     Numerical epsilon
669
      real         eps
669
      real         eps
670
      parameter    (eps=0.001)
670
      parameter    (eps=0.001)
671
 
671
 
672
c     A single command term
672
c     A single command term
673
      character*80 cmd
673
      character*80 cmd
674
      character*80 var,mode
674
      character*80 var,mode
675
      integer      nval
675
      integer      nval
676
      real         val(1000)
676
      real         val(1000)
677
      integer      ntim
677
      integer      ntim
678
      real         tim(1000)
678
      real         tim(1000)
679
      character*80 tmode
679
      character*80 tmode
680
 
680
 
681
c     Specification of a polygon
681
c     Specification of a polygon
682
      character*80 filename
682
      character*80 filename
683
      integer      pn                             ! Number of entries in lat/lon poly
683
      integer      pn                             ! Number of entries in lat/lon poly
684
      real         latpoly(1000)                  ! List of polygon latitudes
684
      real         latpoly(1000)                  ! List of polygon latitudes
685
      real         lonpoly(1000)                  ! List of polygon longitudes
685
      real         lonpoly(1000)                  ! List of polygon longitudes
686
      real         loninpoly,latinpoly            ! Lon/lat inside polygon
686
      real         loninpoly,latinpoly            ! Lon/lat inside polygon
687
 
687
 
688
c     Specification of a region
688
c     Specification of a region
689
      real         xcorner(4)
689
      real         xcorner(4)
690
      real         ycorner(4)
690
      real         ycorner(4)
691
      integer      iregion
691
      integer      iregion
692
      character*80 string
692
      character*80 string
693
 
693
 
694
c     Transformation to UPN (handling of logical operators)
694
c     Transformation to UPN (handling of logical operators)
695
      integer      nlogical
695
      integer      nlogical
696
      integer      ilogical(n)
696
      integer      ilogical(n)
697
      real         tmp(n)
697
      real         tmp(n)
698
      integer      mlogical
698
      integer      mlogical
699
      integer      isor
699
      integer      isor
700
 
700
 
701
c     Auxiliary variables
701
c     Auxiliary variables
702
      integer      i,j
702
      integer      i,j
703
      integer      j1,j2
703
      integer      j1,j2
704
      integer      flag(ntimes)
704
      integer      flag(ntimes)
705
      integer      count
705
      integer      count
706
      integer      ok
706
      integer      ok
707
      integer      itrigger,ttrigger
707
      integer      itrigger,ttrigger
708
 
708
 
709
c     Common block for initialisation of polygon check
709
c     Common block for initialisation of polygon check
710
      real    tlonv(1000),vlat_c(1000),vlon_c(1000)
710
      real    tlonv(1000),vlat_c(1000),vlon_c(1000)
711
      real    xlat_c,xlon_c
711
      real    xlat_c,xlon_c
712
      integer ibndry,nv_c
712
      integer ibndry,nv_c
713
      common  /spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry
713
      common  /spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry
714
 
714
 
715
c     ------ Decode single commands ---------------------
715
c     ------ Decode single commands ---------------------
716
 
716
 
717
c     Reset the filename for polygons
717
c     Reset the filename for polygons
718
      filename='nil'
718
      filename='nil'
719
 
719
 
720
c     Reset the counter for logical commands
720
c     Reset the counter for logical commands
721
      nlogical=0
721
      nlogical=0
722
 
722
 
723
c     Loop through all commands
723
c     Loop through all commands
724
 100  continue
724
 100  continue
725
 
725
 
726
c       Read next command (handle special cases)
726
c       Read next command (handle special cases)
727
        read(fid,*) cmd
727
        read(fid,*) cmd
728
 
728
 
729
c       Special handling of SPECIAL commands
729
c       Special handling of SPECIAL commands
730
        if ( cmd.eq.'SPECIAL' ) then
730
        if ( cmd.eq.'SPECIAL' ) then
731
 
731
 
732
c          Set the flag for SPECIAL command
732
c          Set the flag for SPECIAL command
733
           n      = 1
733
           n      = 1
734
           out(n) = 0.
734
           out(n) = 0.
735
 
735
 
736
c          Read the command string
736
c          Read the command string
737
           read(fid,*) var
737
           read(fid,*) var
738
 
738
 
739
c          Add the command string
739
c          Add the command string
740
           n      = n + 1
740
           n      = n + 1
741
           out(n) = len_trim(var)
741
           out(n) = len_trim(var)
742
           do j=1,len_trim(var)
742
           do j=1,len_trim(var)
743
              n      = n + 1
743
              n      = n + 1
744
              out(n) = ichar(var(j:j))
744
              out(n) = ichar(var(j:j))
745
           enddo
745
           enddo
746
 
746
 
747
c          Read the parameters
747
c          Read the parameters
748
           read(fid,*) nval
748
           read(fid,*) nval
749
           read(fid,*) (val(i),i=1,nval)
749
           read(fid,*) (val(i),i=1,nval)
750
 
750
 
751
c          Add the parameters
751
c          Add the parameters
752
           n = n + 1
752
           n = n + 1
753
           out(n)=real(nval)
753
           out(n)=real(nval)
754
           do i=1,nval
754
           do i=1,nval
755
              n=n+1
755
              n=n+1
756
              out(n)=val(i)
756
              out(n)=val(i)
757
           enddo
757
           enddo
758
 
758
 
759
c          Goto exit point - nothing more top do
759
c          Goto exit point - nothing more top do
760
           goto 350
760
           goto 350
761
 
761
 
762
        endif
762
        endif
763
 
763
 
764
c       Handle structure commands
764
c       Handle structure commands
765
        if ( cmd.eq.'BEGIN') then
765
        if ( cmd.eq.'BEGIN') then
766
           out(1)=-1.
766
           out(1)=-1.
767
           n=1
767
           n=1
768
           nlogical=1
768
           nlogical=1
769
           ilogical(1)=n
769
           ilogical(1)=n
770
           goto 200
770
           goto 200
771
        elseif ( cmd.eq.'AND'  ) then
771
        elseif ( cmd.eq.'AND'  ) then
772
           n=n+1
772
           n=n+1
773
           out(n)=-3.
773
           out(n)=-3.
774
           nlogical=nlogical+1
774
           nlogical=nlogical+1
775
           ilogical(nlogical)=n
775
           ilogical(nlogical)=n
776
           goto 200
776
           goto 200
777
        elseif ( cmd.eq.'OR'   ) then
777
        elseif ( cmd.eq.'OR'   ) then
778
           n=n+1
778
           n=n+1
779
           out(n)=-4.
779
           out(n)=-4.
780
           nlogical=nlogical+1
780
           nlogical=nlogical+1
781
           ilogical(nlogical)=n
781
           ilogical(nlogical)=n
782
           goto 200
782
           goto 200
783
        elseif ( cmd.eq.'END'  ) then
783
        elseif ( cmd.eq.'END'  ) then
784
           n=n+1
784
           n=n+1
785
           out(n)=-2.
785
           out(n)=-2.
786
           nlogical=nlogical+1
786
           nlogical=nlogical+1
787
           ilogical(nlogical)=n
787
           ilogical(nlogical)=n
788
           goto 300
788
           goto 300
789
        endif
789
        endif
790
 
790
 
791
c       Read other fields associated with the command
791
c       Read other fields associated with the command
792
        read(fid,*) var,mode
792
        read(fid,*) var,mode
793
 
793
 
794
c       Read parameter
794
c       Read parameter
795
        if ( var.eq.'INPOLYGON' ) then 
795
        if ( var.eq.'INPOLYGON' ) then 
796
           read(fid,*) nval
796
           read(fid,*) nval
797
           read(fid,*) filename
797
           read(fid,*) filename
798
           filename = trim(filename)
798
           filename = trim(filename)
799
        else
799
        else
800
           read(fid,*) nval
800
           read(fid,*) nval
801
           read(fid,*) (val(i),i=1,nval)
801
           read(fid,*) (val(i),i=1,nval)
802
        endif
802
        endif
803
 
803
 
804
c       Read times (on request, change to special trigger times)
804
c       Read times (on request, change to special trigger times)
805
        read(fid,*) ntim
805
        read(fid,*) ntim
806
        if ( ntim.eq.-993 ) then
806
        if ( ntim.eq.-993 ) then
807
           ttrigger = 1
807
           ttrigger = 1
808
           ntim     = 1
808
           ntim     = 1
809
           tim(1)   = -999.
809
           tim(1)   = -999.
810
        else
810
        else
811
           ttrigger = 0
811
           ttrigger = 0
812
           read(fid,*) (tim(i),i=1,ntim)
812
           read(fid,*) (tim(i),i=1,ntim)
813
        endif
813
        endif
814
        read(fid,*) tmode
814
        read(fid,*) tmode
815
 
815
 
816
c       Bring CAPITAL "TIME,LAT,LON,P" into "time,lat,lon,p"
816
c       Bring CAPITAL "TIME,LAT,LON,P" into "time,lat,lon,p"
817
        if (var.eq.'TIME') var='time'
817
        if (var.eq.'TIME') var='time'
818
        if (var.eq.'LAT' ) var='lat'
818
        if (var.eq.'LAT' ) var='lat'
819
        if (var.eq.'LON' ) var='lon'
819
        if (var.eq.'LON' ) var='lon'
820
        if (var.eq.'P'   ) var='p'
820
        if (var.eq.'P'   ) var='p'
821
 
821
 
822
c       If the time mode is 'TRIGGER', all times of a trajectory
822
c       If the time mode is 'TRIGGER', all times of a trajectory
823
c       must be considered
823
c       must be considered
824
        if ( tmode.eq.'TRIGGER' ) then
824
        if ( tmode.eq.'TRIGGER' ) then
825
           itrigger = nint(tim(1))
825
           itrigger = nint(tim(1))
826
           ntim     = 1
826
           ntim     = 1
827
           tim(1)   = -999.
827
           tim(1)   = -999.
828
        endif
828
        endif
829
 
829
 
830
c       Special times: transform into real time
830
c       Special times: transform into real time
831
        do i=1,ntim
831
        do i=1,ntim
832
           if ( abs(tim(i)+996.).lt.eps ) tim(i)=times(1)
832
           if ( abs(tim(i)+996.).lt.eps ) tim(i)=times(1)
833
           if ( abs(tim(i)+995.).lt.eps ) tim(i)=times(ntimes)
833
           if ( abs(tim(i)+995.).lt.eps ) tim(i)=times(ntimes)
834
        enddo
834
        enddo
835
 
835
 
836
c       Check whether times are valid 
836
c       Check whether times are valid 
837
        ok=0
837
        ok=0
838
        do i=1,ntim
838
        do i=1,ntim
839
           if ( (abs(tim(i)+994.).gt.eps).and.
839
           if ( (abs(tim(i)+994.).gt.eps).and.
840
     >          (abs(tim(i)+999.).gt.eps) )
840
     >          (abs(tim(i)+999.).gt.eps) )
841
     >     then
841
     >     then
842
              do j=1,ntimes
842
              do j=1,ntimes
843
                 if ( abs(tim(i)-times(j)).lt.eps ) then
843
                 if ( abs(tim(i)-times(j)).lt.eps ) then
844
                    ok=ok+1
844
                    ok=ok+1
845
                 endif
845
                 endif
846
              enddo
846
              enddo
847
           else
847
           else
848
              ok=ok+1
848
              ok=ok+1
849
           endif
849
           endif
850
        enddo
850
        enddo
851
        if (ok.ne.ntim) goto 400
851
        if (ok.ne.ntim) goto 400
852
        
852
        
853
c       Select all times which are included in the criterion
853
c       Select all times which are included in the criterion
854
        do i=1,ntimes
854
        do i=1,ntimes
855
           flag(i)=0
855
           flag(i)=0
856
        enddo
856
        enddo
857
        i=1
857
        i=1
858
 150    if (i.le.ntim) then
858
 150    if (i.le.ntim) then
859
           
859
           
860
c          A list of times
860
c          A list of times
861
           if ( (abs(tim(i)+994.).lt.eps) ) then
861
           if ( (abs(tim(i)+994.).lt.eps) ) then
862
              j1=0
862
              j1=0
863
              do j=1,ntimes
863
              do j=1,ntimes
864
                 if ( abs(tim(i-1)-times(j)).lt.eps ) then
864
                 if ( abs(tim(i-1)-times(j)).lt.eps ) then
865
                    j1=j
865
                    j1=j
866
                 endif
866
                 endif
867
              enddo
867
              enddo
868
              j2=0
868
              j2=0
869
              do j=1,ntimes
869
              do j=1,ntimes
870
                 if ( abs(tim(i+1)-times(j)).lt.eps ) then
870
                 if ( abs(tim(i+1)-times(j)).lt.eps ) then
871
                    j2=j
871
                    j2=j
872
                 endif
872
                 endif
873
              enddo   
873
              enddo   
874
              if ( (j1.eq.0).or.(j2.eq.0) ) goto 400
874
              if ( (j1.eq.0).or.(j2.eq.0) ) goto 400
875
              do j=j1,j2
875
              do j=j1,j2
876
                 flag(j)=1
876
                 flag(j)=i
877
              enddo
877
              enddo
878
              i=i+1
878
              i=i+1
879
 
879
 
880
c          Explicitly given time value
880
c          Explicitly given time value
881
           else
881
           else
882
              do j=1,ntimes
882
              do j=1,ntimes
883
                 if ( abs(tim(i)-times(j)).lt.eps ) then
883
                 if ( abs(tim(i)-times(j)).lt.eps ) then
884
                    flag(j)=1
884
                    flag(j)=i
885
                 endif
885
                 endif
886
              enddo
886
              enddo
887
              
887
              
888
           endif
888
           endif
889
 
889
 
890
           i=i+1
890
           i=i+1
891
           goto 150
891
           goto 150
892
 
892
 
893
        endif
893
        endif
894
 
894
 
895
c       Write command identifier
895
c       Write command identifier
896
        n=n+1
896
        n=n+1
897
        if (cmd.eq.'GT'    ) out(n)= 1.
897
        if (cmd.eq.'GT'    ) out(n)= 1.
898
        if (cmd.eq.'LT'    ) out(n)= 2.
898
        if (cmd.eq.'LT'    ) out(n)= 2.
899
        if (cmd.eq.'IN'    ) out(n)= 3.
899
        if (cmd.eq.'IN'    ) out(n)= 3.
900
        if (cmd.eq.'OUT'   ) out(n)= 4.
900
        if (cmd.eq.'OUT'   ) out(n)= 4.
901
        if (cmd.eq.'EQ'    ) out(n)= 5.
901
        if (cmd.eq.'EQ'    ) out(n)= 5.
902
        if (cmd.eq.'TRUE'  ) out(n)= 6.
902
        if (cmd.eq.'TRUE'  ) out(n)= 6.
903
        if (cmd.eq.'FALSE' ) out(n)= 7.
903
        if (cmd.eq.'FALSE' ) out(n)= 7.
904
        if (cmd.eq.'ALL  ' ) out(n)= 8.
904
        if (cmd.eq.'ALL  ' ) out(n)= 8.
905
        if (cmd.eq.'ANY  ' ) out(n)= 9.
905
        if (cmd.eq.'ANY  ' ) out(n)= 9.
906
        if (cmd.eq.'NONE ' ) out(n)=10.
906
        if (cmd.eq.'NONE ' ) out(n)=10.
907
 
907
 
908
c       Write index for variable - force implicit trigger
908
c       Write index for variable - force implicit trigger
909
        ok=0
909
        ok=0
910
        do j=1,nvars
910
        do j=1,nvars
911
           if (vars(j).eq.var) ok=j
911
           if (vars(j).eq.var) ok=j
912
        enddo
912
        enddo
913
 
913
 
914
        if (var.eq.'TRIGGER') ok = 0
914
        if (var.eq.'TRIGGER') ok = 0
915
        
915
        
916
        if (ok.eq.0) then
916
        if (ok.eq.0) then
917
           if (var.eq.'DIST') then
917
           if (var.eq.'DIST') then
918
              ok = -1
918
              ok = -1
919
           elseif (var.eq.'DIST0') then
919
           elseif (var.eq.'DIST0') then
920
              ok = -2
920
              ok = -2
921
           elseif (var.eq.'INPOLYGON') then
921
           elseif (var.eq.'INPOLYGON') then
922
              ok = -3
922
              ok = -3
923
           elseif (var.eq.'INBOX') then
923
           elseif (var.eq.'INBOX') then
924
              ok = -4
924
              ok = -4
925
           elseif (var.eq.'INCIRCLE') then
925
           elseif (var.eq.'INCIRCLE') then
926
              ok = -5
926
              ok = -5
927
           elseif (var.eq.'INREGION') then
927
           elseif (var.eq.'INREGION') then
928
              ok = -6
928
              ok = -6
929
           elseif (var.eq.'TRIGGER') then
929
           elseif (var.eq.'TRIGGER') then
930
              ok = -7
930
              ok = -7
931
           elseif (var.eq.'VERT0') then
931
           elseif (var.eq.'VERT0') then
932
              ok = -8
932
              ok = -8
933
           else
933
           else
934
             goto 400
934
             goto 400
935
          endif
935
          endif
936
        endif
936
        endif
937
        n=n+1
937
        n=n+1
938
        out(n)=real(ok)
938
        out(n)=real(ok)
939
 
939
 
940
c       Write mode for variable
940
c       Write mode for variable
941
        ok=0
941
        ok=0
942
        if (mode.eq.'VALUE'  ) ok=1
942
        if (mode.eq.'VALUE'  ) ok=1
943
        if (mode.eq.'MEAN'   ) ok=2
943
        if (mode.eq.'MEAN'   ) ok=2
944
        if (mode.eq.'MAX'    ) ok=3
944
        if (mode.eq.'MAX'    ) ok=3
945
        if (mode.eq.'MIN'    ) ok=4
945
        if (mode.eq.'MIN'    ) ok=4
946
        if (mode.eq.'VAR'    ) ok=5
946
        if (mode.eq.'VAR'    ) ok=5
947
        if (mode.eq.'SUM'    ) ok=6
947
        if (mode.eq.'SUM'    ) ok=6
948
        if (mode.eq.'CHANGE' ) ok=7
948
        if (mode.eq.'CHANGE' ) ok=7
949
        if (mode.eq.'DIFF'   ) ok=8
949
        if (mode.eq.'DIFF'   ) ok=8
950
        if (mode.eq.'RANGE'  ) ok=9
950
        if (mode.eq.'RANGE'  ) ok=9
951
        if (mode.eq.'ABS'    ) ok=10
951
        if (mode.eq.'ABS'    ) ok=10
952
        if (ok.eq.0) goto 400
952
        if (ok.eq.0) goto 400
953
        n=n+1
953
        n=n+1
954
        out(n)=real(ok)
954
        out(n)=real(ok)
955
 
955
 
956
c       Write the parameter values: INPOLYGON 
956
c       Write the parameter values: INPOLYGON 
957
        if ( var.eq.'INPOLYGON' ) then
957
        if ( var.eq.'INPOLYGON' ) then
958
 
958
 
959
           n      = n+1
959
           n      = n+1
960
           out(n) = len_trim(filename)
960
           out(n) = len_trim(filename)
961
           do j=1,len_trim(filename)
961
           do j=1,len_trim(filename)
962
              n      = n + 1
962
              n      = n + 1
963
              out(n) = ichar(filename(j:j))
963
              out(n) = ichar(filename(j:j))
964
           enddo
964
           enddo
965
 
965
 
966
c       Write parameter value: INREGION 
966
c       Write parameter value: INREGION 
967
        elseif ( var.eq.'INREGION' ) then
967
        elseif ( var.eq.'INREGION' ) then
968
 
968
 
969
           iregion = nint(val(1))
969
           iregion = nint(val(1))
970
 
970
 
971
           open(fid+1,file=regionf)          
971
           open(fid+1,file=regionf)          
972
 
972
 
973
 50        read(fid+1,*,end=51) string
973
 50        read(fid+1,*,end=51) string
974
 
974
 
975
           if ( string(1:1).ne.'#' ) then
975
           if ( string(1:1).ne.'#' ) then
976
              call regionsplit(string,i,xcorner,ycorner)
976
              call regionsplit(string,i,xcorner,ycorner)
977
              if ( i.eq.iregion ) goto 52
977
              if ( i.eq.iregion ) goto 52
978
           endif
978
           endif
979
 
979
 
980
           goto 50
980
           goto 50
981
           
981
           
982
 51        close(fid+1)        
982
 51        close(fid+1)        
983
 
983
 
984
           print*,' ERROR: region ',iregion,' not found on ',
984
           print*,' ERROR: region ',iregion,' not found on ',
985
     >                                         trim(regionf)
985
     >                                         trim(regionf)
986
           stop
986
           stop
987
 
987
 
988
 52        continue
988
 52        continue
989
           
989
           
990
           n      = n + 1
990
           n      = n + 1
991
           out(n) = 8                   ! Number of parameters
991
           out(n) = 8                   ! Number of parameters
992
           do i=1,4
992
           do i=1,4
993
              n      = n + 1
993
              n      = n + 1
994
              out(n) = xcorner(i)
994
              out(n) = xcorner(i)
995
           enddo
995
           enddo
996
           do i=1,4
996
           do i=1,4
997
              n      = n + 1
997
              n      = n + 1
998
              out(n) = ycorner(i)
998
              out(n) = ycorner(i)
999
           enddo
999
           enddo
1000
 
1000
 
1001
c       Write parameter values: all other cases
1001
c       Write parameter values: all other cases
1002
        else
1002
        else
1003
           n=n+1
1003
           n=n+1
1004
           out(n)=real(nval)
1004
           out(n)=real(nval)
1005
           do i=1,nval
1005
           do i=1,nval
1006
              n=n+1
1006
              n=n+1
1007
              out(n)=val(i)
1007
              out(n)=val(i)
1008
           enddo
1008
           enddo
1009
        endif
1009
        endif
1010
 
1010
 
1011
c       Special time handling: only trigger times are cosidered
1011
c       Special time handling: only trigger times are cosidered
1012
        if ( ttrigger.eq.1 ) then
1012
        if ( ttrigger.eq.1 ) then
1013
           n = n+1
1013
           n = n+1
1014
           out(n)=-993.
1014
           out(n)=-993.
1015
 
1015
 
1016
c       All times are selected
1016
c       All times are selected
1017
        elseif ( abs(tim(1)+999.).lt.eps ) then
1017
        elseif ( abs(tim(1)+999.).lt.eps ) then
1018
           n=n+1
1018
           n=n+1
1019
           out(n)=real(ntimes)
1019
           out(n)=real(ntimes)
1020
           do i=1,ntimes
1020
           do i=1,ntimes
1021
              n=n+1
1021
              n=n+1
1022
              out(n)=real(i)
1022
              out(n)=real(i)
1023
           enddo
1023
           enddo
1024
 
1024
 
1025
c       A selection of times is given 
1025
c       A selection of times is given 
1026
        else
1026
        else
1027
           count=0
1027
           count=0
1028
           do i=1,ntimes
1028
           do i=1,ntimes
-
 
1029
              if ( flag(i).ne.0 ) then
1029
              count=count+flag(i)
1030
                 count=count+1
-
 
1031
              endif
1030
           enddo
1032
           enddo
1031
           n=n+1
1033
           n=n+1
1032
           out(n)=real(count)
1034
           out(n)=real(count)
-
 
1035
           do i=1,count
1033
           do i=1,ntimes
1036
             do j=1,ntimes
1034
              if (flag(i).eq.1) then
1037
               if (flag(j).eq.i) then
1035
                 n=n+1
1038
                 n      = n + 1
1036
                 out(n)=real(i)
1039
                 out(n) = real(j)
1037
              endif
1040
               endif
-
 
1041
             enddo
1038
           enddo
1042
           enddo
-
 
1043
 
1039
        endif
1044
        endif
1040
 
1045
 
1041
c       Write the time mode
1046
c       Write the time mode
1042
        if ( tmode.eq.'ALL') then
1047
        if ( tmode.eq.'ALL') then
1043
           n=n+1
1048
           n=n+1
1044
           out(n)=1.
1049
           out(n)=1.
1045
        elseif ( tmode.eq.'ANY') then
1050
        elseif ( tmode.eq.'ANY') then
1046
           n=n+1
1051
           n=n+1
1047
           out(n)=2.
1052
           out(n)=2.
1048
        elseif ( tmode.eq.'NONE') then
1053
        elseif ( tmode.eq.'NONE') then
1049
           n=n+1
1054
           n=n+1
1050
           out(n)=3.
1055
           out(n)=3.
1051
        elseif ( tmode.eq.'TRIGGER') then
1056
        elseif ( tmode.eq.'TRIGGER') then
1052
           n=n+1
1057
           n=n+1
1053
           out(n)=-real(itrigger)
1058
           out(n)=-real(itrigger)
1054
        endif
1059
        endif
1055
           
1060
           
1056
c     End loop: handle single command
1061
c     End loop: handle single command
1057
 200  continue
1062
 200  continue
1058
      goto 100
1063
      goto 100
1059
 
1064
 
1060
c     End loop: loop over all commands 
1065
c     End loop: loop over all commands 
1061
 300  continue
1066
 300  continue
1062
 
1067
 
1063
c     ------ Read polygon file, if requested -----------
1068
c     ------ Read polygon file, if requested -----------
1064
      if ( filename.ne.'nil' ) then
1069
      if ( filename.ne.'nil' ) then
1065
 
1070
 
1066
        print*
1071
        print*
1067
        print*,
1072
        print*,
1068
     >     '---- POLYGON --------------------------------------------'
1073
     >     '---- POLYGON --------------------------------------------'
1069
 
1074
 
1070
           print*
1075
           print*
1071
           print*,'Filename = ',trim(filename)
1076
           print*,'Filename = ',trim(filename)
1072
           print*
1077
           print*
1073
         
1078
         
1074
c        Read list of polygon coordinates from file
1079
c        Read list of polygon coordinates from file
1075
         pn = 0
1080
         pn = 0
1076
         open(fid+1,file=filename)
1081
         open(fid+1,file=filename)
1077
           read(fid+1,*) loninpoly,latinpoly
1082
           read(fid+1,*) loninpoly,latinpoly
1078
           print*,'Inside (lon/lat) =',loninpoly,latinpoly
1083
           print*,'Inside (lon/lat) =',loninpoly,latinpoly
1079
           print*
1084
           print*
1080
 510       continue
1085
 510       continue
1081
              pn = pn + 1
1086
              pn = pn + 1
1082
              read(fid+1,*,end=511) lonpoly(pn),
1087
              read(fid+1,*,end=511) lonpoly(pn),
1083
     >                              latpoly(pn)
1088
     >                              latpoly(pn)
1084
 
1089
 
1085
              print*,pn,lonpoly(pn),latpoly(pn)
1090
              print*,pn,lonpoly(pn),latpoly(pn)
1086
              
1091
              
1087
              goto 510
1092
              goto 510
1088
 511       continue
1093
 511       continue
1089
           pn = pn - 1
1094
           pn = pn - 1
1090
         close(fid+1)
1095
         close(fid+1)
1091
 
1096
 
1092
c        Define the polygon boundaries
1097
c        Define the polygon boundaries
1093
         call DefSPolyBndry(latpoly,lonpoly,pn,latinpoly,loninpoly)
1098
         call DefSPolyBndry(latpoly,lonpoly,pn,latinpoly,loninpoly)
1094
 
1099
 
1095
      endif
1100
      endif
1096
 
1101
 
1097
c     ------ Transform to UPN --------------------------
1102
c     ------ Transform to UPN --------------------------
1098
 
1103
 
1099
c     Check whether logical commands are ok
1104
c     Check whether logical commands are ok
1100
      mlogical=nint(out(ilogical(1)))
1105
      mlogical=nint(out(ilogical(1)))
1101
      if ( mlogical.ne.-1) goto 400
1106
      if ( mlogical.ne.-1) goto 400
1102
      mlogical=nint(out(ilogical(nlogical)))
1107
      mlogical=nint(out(ilogical(nlogical)))
1103
      if ( mlogical.ne.-2) goto 400
1108
      if ( mlogical.ne.-2) goto 400
1104
 
1109
 
1105
c     No transformation necessary if only one command
1110
c     No transformation necessary if only one command
1106
      if (nlogical.eq.2) goto 350
1111
      if (nlogical.eq.2) goto 350
1107
      
1112
      
1108
c     Copy the output to temporary list
1113
c     Copy the output to temporary list
1109
      do i=1,n
1114
      do i=1,n
1110
         tmp(i)=out(i)
1115
         tmp(i)=out(i)
1111
      enddo
1116
      enddo
1112
 
1117
 
1113
c     Set BEGIN statement
1118
c     Set BEGIN statement
1114
      n=1
1119
      n=1
1115
      out(n)=-1.
1120
      out(n)=-1.
1116
 
1121
 
1117
c     Reorder commands and transform to UPN
1122
c     Reorder commands and transform to UPN
1118
      isor=0
1123
      isor=0
1119
      do i=1,nlogical-1
1124
      do i=1,nlogical-1
1120
 
1125
 
1121
c        Get the logical command
1126
c        Get the logical command
1122
         mlogical=nint(out(ilogical(i)))
1127
         mlogical=nint(out(ilogical(i)))
1123
 
1128
 
1124
c        Connecting OR
1129
c        Connecting OR
1125
         if (mlogical.eq.-4) then
1130
         if (mlogical.eq.-4) then
1126
            if (isor.eq.1) then
1131
            if (isor.eq.1) then
1127
               n=n+1
1132
               n=n+1
1128
               out(n)=-4.
1133
               out(n)=-4.
1129
            else
1134
            else
1130
               isor=1
1135
               isor=1
1131
            endif
1136
            endif
1132
         endif
1137
         endif
1133
 
1138
 
1134
c        Put the command onto the stack
1139
c        Put the command onto the stack
1135
         do j=ilogical(i)+1,ilogical(i+1)-1
1140
         do j=ilogical(i)+1,ilogical(i+1)-1
1136
            n=n+1
1141
            n=n+1
1137
            out(n)=tmp(j)
1142
            out(n)=tmp(j)
1138
         enddo
1143
         enddo
1139
 
1144
 
1140
c        Connecting AND operator
1145
c        Connecting AND operator
1141
         if ( mlogical.eq.-3 ) then
1146
         if ( mlogical.eq.-3 ) then
1142
            n=n+1
1147
            n=n+1
1143
            out(n)=-3.
1148
            out(n)=-3.
1144
         endif
1149
         endif
1145
         
1150
         
1146
      enddo
1151
      enddo
1147
      
1152
      
1148
c     Set final connecting OR
1153
c     Set final connecting OR
1149
      if (isor.eq.1) then
1154
      if (isor.eq.1) then
1150
         n=n+1
1155
         n=n+1
1151
         out(n)=-4.
1156
         out(n)=-4.
1152
      endif
1157
      endif
1153
 
1158
 
1154
c     Set END statement
1159
c     Set END statement
1155
      n=n+1
1160
      n=n+1
1156
      out(n)=-2.
1161
      out(n)=-2.
1157
 
1162
 
1158
c     ------ Exit point ---------------------------------
1163
c     ------ Exit point ---------------------------------
1159
 
1164
 
1160
 350  continue
1165
 350  continue
1161
      return
1166
      return
1162
 
1167
 
1163
c     ----- Exception handling --------------------------
1168
c     ----- Exception handling --------------------------
1164
 400  print*,'Invalid selection criterion... Stop'
1169
 400  print*,'Invalid selection criterion... Stop'
1165
      stop
1170
      stop
1166
 
1171
 
1167
      end
1172
      end
1168
 
1173
 
1169
 
1174
 
1170
c     -------------------------------------------------------------- 
1175
c     -------------------------------------------------------------- 
1171
c     Decide whether a trajectory is selected or not
1176
c     Decide whether a trajectory is selected or not
1172
c     --------------------------------------------------------------
1177
c     --------------------------------------------------------------
1173
 
1178
 
1174
      subroutine select_tra (select,cmd,n,tra,trigger,ntim,ncol)
1179
      subroutine select_tra (select,cmd,n,tra,trigger,ntim,ncol)
1175
 
1180
 
1176
c     Decide whether a single trajectory is selected (<select=1>) or
1181
c     Decide whether a single trajectory is selected (<select=1>) or
1177
c     is not selected <select=0> according to the selection criterion
1182
c     is not selected <select=0> according to the selection criterion
1178
c     given in <cmd(ncmd)>. The selection criterion <cmd(ncmd)> is 
1183
c     given in <cmd(ncmd)>. The selection criterion <cmd(ncmd)> is 
1179
c     returned from the call to the subroutine <decode>. The trajectory
1184
c     returned from the call to the subroutine <decode>. The trajectory
1180
c     is given in <tra(ntim,ncol)> where <ntim> is the number of times
1185
c     is given in <tra(ntim,ncol)> where <ntim> is the number of times
1181
c     and <ncol> is the number of columns.
1186
c     and <ncol> is the number of columns.
1182
c     
1187
c     
1183
c     Important note: the structure of <tra(ntim,ncol)> must match to the
1188
c     Important note: the structure of <tra(ntim,ncol)> must match to the
1184
c     call parameter <vars,nvars,times,ntimes> in subroutine <decode>.
1189
c     call parameter <vars,nvars,times,ntimes> in subroutine <decode>.
1185
 
1190
 
1186
      implicit none
1191
      implicit none
1187
 
1192
 
1188
c     Declaration of subroutine parameters
1193
c     Declaration of subroutine parameters
1189
      integer   select
1194
      integer   select
1190
      integer   n
1195
      integer   n
1191
      real      cmd(n)
1196
      real      cmd(n)
1192
      integer   ntim,ncol
1197
      integer   ntim,ncol
1193
      real      tra(ntim,ncol)
1198
      real      tra(ntim,ncol)
1194
      integer   trigger(ntim)
1199
      integer   trigger(ntim)
1195
 
1200
 
1196
c     Numerical epsilon (for test of equality)
1201
c     Numerical epsilon (for test of equality)
1197
      real      eps
1202
      real      eps
1198
      parameter (eps=0.000001)
1203
      parameter (eps=0.000001)
1199
 
1204
 
1200
c     A single command and the associated field
1205
c     A single command and the associated field
1201
      integer   icmd,ivar,imode,itime,nsel,nval
1206
      integer   icmd,ivar,imode,itime,nsel,nval
1202
      integer   time(ntim)
1207
      integer   time(ntim)
1203
      real      param(100)
1208
      real      param(100)
1204
      real      var   (ntim)
1209
      real      var   (ntim)
1205
      integer   intvar(ntim)
1210
      integer   intvar(ntim)
1206
 
1211
 
1207
c     Boolean values for a single time, a single command and build-up
1212
c     Boolean values for a single time, a single command and build-up
1208
      integer   stack(100)
1213
      integer   stack(100)
1209
      integer   nstack
1214
      integer   nstack
1210
      integer   istrue(ntim)
1215
      integer   istrue(ntim)
1211
      integer   decision
1216
      integer   decision
1212
 
1217
 
1213
c     Auxiliary variables
1218
c     Auxiliary variables
1214
      integer   i,j,k
1219
      integer   i,j,k
1215
      real      tmp,mea
1220
      real      tmp,mea
1216
      integer   istack1,istack2
1221
      integer   istack1,istack2
1217
      real      lat0,lon0,lat1,lon1
1222
      real      lat0,lon0,lat1,lon1
1218
      real      length(ntim)
1223
      real      length(ntim)
1219
      integer   flag
1224
      integer   flag
1220
      real      dist
1225
      real      dist
1221
      real      xcorner(4),ycorner(4)
1226
      real      xcorner(4),ycorner(4)
1222
      integer   iparam
1227
      integer   iparam
1223
      character ch
1228
      character ch
1224
      real      varmin,varmax
1229
      real      varmin,varmax
1225
      real      lev0,lev1
1230
      real      lev0,lev1
1226
 
1231
 
1227
c     Common block for initialisation of polygon check
1232
c     Common block for initialisation of polygon check
1228
      real    tlonv(1000),vlat_c(1000),vlon_c(1000)
1233
      real    tlonv(1000),vlat_c(1000),vlon_c(1000)
1229
      real    xlat_c,xlon_c
1234
      real    xlat_c,xlon_c
1230
      integer ibndry,nv_c
1235
      integer ibndry,nv_c
1231
      common  /spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry
1236
      common  /spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry
1232
 
1237
 
1233
c     Externals
1238
c     Externals
1234
      real      sdis           ! Spherical distance
1239
      real      sdis           ! Spherical distance
1235
      external  sdis
1240
      external  sdis
1236
      integer   inregion       ! Boolean flag for regions
1241
      integer   inregion       ! Boolean flag for regions
1237
      external  inregion
1242
      external  inregion
1238
 
1243
 
1239
c     Reset the decision stack (with locical values)
1244
c     Reset the decision stack (with locical values)
1240
      nstack=0
1245
      nstack=0
1241
 
1246
 
1242
c     Loop through the complete command list
1247
c     Loop through the complete command list
1243
      i=0
1248
      i=0
1244
 100  if (i.lt.n) then  
1249
 100  if (i.lt.n) then  
1245
 
1250
 
1246
c        --- Get the command -------------------------------
1251
c        --- Get the command -------------------------------
1247
         i=i+1
1252
         i=i+1
1248
         icmd=nint(cmd(i))
1253
         icmd=nint(cmd(i))
1249
 
1254
 
1250
c        --- Handle structural commands (BEGIN, END, AND, OR)
1255
c        --- Handle structural commands (BEGIN, END, AND, OR)
1251
 
1256
 
1252
c        Handle BEGIN statement
1257
c        Handle BEGIN statement
1253
         if ( icmd.eq.-1) then
1258
         if ( icmd.eq.-1) then
1254
            nstack=0
1259
            nstack=0
1255
            goto 200
1260
            goto 200
1256
         endif
1261
         endif
1257
 
1262
 
1258
c        Handle END statement
1263
c        Handle END statement
1259
         if (icmd.eq.-2) then
1264
         if (icmd.eq.-2) then
1260
            goto 300
1265
            goto 300
1261
         endif
1266
         endif
1262
 
1267
 
1263
c        Handle AND statement
1268
c        Handle AND statement
1264
         if (icmd.eq.-3) then
1269
         if (icmd.eq.-3) then
1265
            istack1=stack(nstack)
1270
            istack1=stack(nstack)
1266
            nstack=nstack-1
1271
            nstack=nstack-1
1267
            istack2=stack(nstack)
1272
            istack2=stack(nstack)
1268
            if ((istack1.eq.1).and.(istack2.eq.1)) then
1273
            if ((istack1.eq.1).and.(istack2.eq.1)) then
1269
               stack(nstack)=1
1274
               stack(nstack)=1
1270
            else
1275
            else
1271
               stack(nstack)=0
1276
               stack(nstack)=0
1272
            endif
1277
            endif
1273
            goto 200
1278
            goto 200
1274
         endif
1279
         endif
1275
            
1280
            
1276
c        Handle OR statement
1281
c        Handle OR statement
1277
         if (icmd.eq.-4) then
1282
         if (icmd.eq.-4) then
1278
            istack1=stack(nstack)
1283
            istack1=stack(nstack)
1279
            nstack=nstack-1
1284
            nstack=nstack-1
1280
            istack2=stack(nstack)
1285
            istack2=stack(nstack)
1281
            if ((istack1.eq.1).or.(istack2.eq.1)) then
1286
            if ((istack1.eq.1).or.(istack2.eq.1)) then
1282
               stack(nstack)=1
1287
               stack(nstack)=1
1283
            else
1288
            else
1284
               stack(nstack)=0
1289
               stack(nstack)=0
1285
            endif
1290
            endif
1286
            goto 200
1291
            goto 200
1287
         endif
1292
         endif
1288
 
1293
 
1289
c        --- Get all command details (parameters, modes, times)
1294
c        --- Get all command details (parameters, modes, times)
1290
 
1295
 
1291
c        Get variable (<ivar> gets the column index in <tra>)
1296
c        Get variable (<ivar> gets the column index in <tra>)
1292
         i=i+1
1297
         i=i+1
1293
         ivar=nint(cmd(i))
1298
         ivar=nint(cmd(i))
1294
         
1299
         
1295
c        Get variable mode 
1300
c        Get variable mode 
1296
         i=i+1
1301
         i=i+1
1297
         imode=nint(cmd(i))
1302
         imode=nint(cmd(i))
1298
 
1303
 
1299
c        Get parameter values
1304
c        Get parameter values
1300
         i=i+1
1305
         i=i+1
1301
         nval=nint(cmd(i))
1306
         nval=nint(cmd(i))
1302
         do j=1,nval
1307
         do j=1,nval
1303
            i=i+1
1308
            i=i+1
1304
            param(j)=cmd(i)
1309
            param(j)=cmd(i)
1305
         enddo
1310
         enddo
1306
         
1311
         
1307
c        Get times (<time(j)> gets the row indices of <tra>)
1312
c        Get times (<time(j)> gets the row indices of <tra>)
1308
         i=i+1
1313
         i=i+1
1309
         nsel=nint(cmd(i))
1314
         nsel=nint(cmd(i))
1310
         if ( nsel .eq. -993 ) then
1315
         if ( nsel .eq. -993 ) then
1311
            nsel = 0
1316
            nsel = 0
1312
            do k=1,ntim
1317
            do k=1,ntim
1313
              if ( trigger(k).ne.0 ) then
1318
              if ( trigger(k).ne.0 ) then
1314
                nsel       = nsel + 1
1319
                nsel       = nsel + 1
1315
                time(nsel) = k
1320
                time(nsel) = k
1316
              endif
1321
              endif
1317
           enddo
1322
           enddo
1318
         else
1323
         else
1319
           do j=1,nsel
1324
           do j=1,nsel
1320
              i=i+1
1325
              i=i+1
1321
              time(j)=nint(cmd(i))
1326
              time(j)=nint(cmd(i))
1322
           enddo
1327
           enddo
1323
         endif
1328
         endif
1324
 
1329
 
1325
c        If no times are selected, exit with non-select status
1330
c        If no times are selected, exit with non-select status
1326
         if ( nsel.eq.0 ) then
1331
         if ( nsel.eq.0 ) then
1327
             stack(1) = 0
1332
             stack(1) = 0
1328
             goto 300
1333
             goto 300
1329
         endif
1334
         endif
1330
 
1335
 
1331
c        Get time mode
1336
c        Get time mode
1332
         i=i+1
1337
         i=i+1
1333
         itime=nint(cmd(i))
1338
         itime=nint(cmd(i))
1334
 
1339
 
1335
c        --- Prepare field values for analysis -----------
1340
c        --- Prepare field values for analysis -----------
1336
 
1341
 
1337
c        Implicit variable: DIST
1342
c        Implicit variable: DIST
1338
         if ( ivar.eq. -1 ) then
1343
         if ( ivar.eq. -1 ) then
1339
            length(1) = 0.
1344
            length(1) = 0.
1340
            do j=2,ntim
1345
            do j=2,ntim
1341
               lon0      = tra(j-1,2)
1346
               lon0      = tra(j-1,2)
1342
               lat0      = tra(j-1,3)
1347
               lat0      = tra(j-1,3)
1343
               lon1      = tra(j  ,2)
1348
               lon1      = tra(j  ,2)
1344
               lat1      = tra(j  ,3)
1349
               lat1      = tra(j  ,3)
1345
               length(j) = length(j-1) + sdis(lon0,lat0,lon1,lat1)
1350
               length(j) = length(j-1) + sdis(lon0,lat0,lon1,lat1)
1346
            enddo
1351
            enddo
1347
            do j=1,nsel
1352
            do j=1,nsel
1348
               var(j) = length( time(j) )
1353
               var(j) = length( time(j) )
1349
            enddo
1354
            enddo
1350
 
1355
 
1351
               
1356
               
1352
c        Implict variable: DIST0
1357
c        Implict variable: DIST0
1353
         elseif ( ivar.eq. -2 ) then
1358
         elseif ( ivar.eq. -2 ) then
1354
            do j=1,nsel
1359
            do j=1,nsel
1355
               lon0   = tra(1      ,2)
1360
               lon0   = tra(1      ,2)
1356
               lat0   = tra(1      ,3)
1361
               lat0   = tra(1      ,3)
1357
               lon1   = tra(time(j),2)
1362
               lon1   = tra(time(j),2)
1358
               lat1   = tra(time(j),3)
1363
               lat1   = tra(time(j),3)
1359
               var(j) = sdis(lon0,lat0,lon1,lat1)
1364
               var(j) = sdis(lon0,lat0,lon1,lat1)
1360
            enddo
1365
            enddo
1361
 
1366
 
1362
c        Implict variable: INPOLYGON
1367
c        Implict variable: INPOLYGON
1363
         elseif ( ivar.eq. -3 ) then
1368
         elseif ( ivar.eq. -3 ) then
1364
            do j=1,nsel
1369
            do j=1,nsel
1365
               lon1   = tra(time(j),2)
1370
               lon1   = tra(time(j),2)
1366
               lat1   = tra(time(j),3)               
1371
               lat1   = tra(time(j),3)               
1367
               call LctPtRelBndry(lat1,lon1,flag)
1372
               call LctPtRelBndry(lat1,lon1,flag)
1368
               if ( (flag.eq.1).or.(flag.eq.2) ) then
1373
               if ( (flag.eq.1).or.(flag.eq.2) ) then
1369
                  var(j) = 1.
1374
                  var(j) = 1.
1370
               else
1375
               else
1371
                  var(j) = 0.
1376
                  var(j) = 0.
1372
               endif
1377
               endif
1373
            enddo
1378
            enddo
1374
 
1379
 
1375
c        Implict variable: INBOX 
1380
c        Implict variable: INBOX 
1376
         elseif ( ivar.eq. -4 ) then
1381
         elseif ( ivar.eq. -4 ) then
1377
            do j=1,nsel
1382
            do j=1,nsel
1378
               lon1   = tra(time(j),2)
1383
               lon1   = tra(time(j),2)
1379
               lat1   = tra(time(j),3)               
1384
               lat1   = tra(time(j),3)               
1380
               if ( ( lon1.ge.param(1) ).and.       ! lonmin
1385
               if ( ( lon1.ge.param(1) ).and.       ! lonmin
1381
     >              ( lon1.le.param(2) ).and.       ! lonmax
1386
     >              ( lon1.le.param(2) ).and.       ! lonmax
1382
     >              ( lat1.ge.param(3) ).and.       ! latmin
1387
     >              ( lat1.ge.param(3) ).and.       ! latmin
1383
     >              ( lat1.le.param(4) ) )          ! latmax
1388
     >              ( lat1.le.param(4) ) )          ! latmax
1384
     >         then
1389
     >         then
1385
                  var(j) = 1
1390
                  var(j) = 1
1386
               else
1391
               else
1387
                  var(j) = 0
1392
                  var(j) = 0
1388
               endif
1393
               endif
1389
            enddo
1394
            enddo
1390
 
1395
 
1391
c        Implict variable: INCIRCLE (lonc=param(1),latc=param(2),radius=param(3))
1396
c        Implict variable: INCIRCLE (lonc=param(1),latc=param(2),radius=param(3))
1392
         elseif ( ivar.eq. -5 ) then
1397
         elseif ( ivar.eq. -5 ) then
1393
            do j=1,nsel
1398
            do j=1,nsel
1394
               lon1   = tra(time(j),2)
1399
               lon1   = tra(time(j),2)
1395
               lat1   = tra(time(j),3)               
1400
               lat1   = tra(time(j),3)               
1396
               
1401
               
1397
               dist = sdis( lon1,lat1,param(1),param(2) ) 
1402
               dist = sdis( lon1,lat1,param(1),param(2) ) 
1398
 
1403
 
1399
               if ( dist.le.param(3) ) then
1404
               if ( dist.le.param(3) ) then
1400
                  var(j) = 1
1405
                  var(j) = 1
1401
               else
1406
               else
1402
                  var(j) = 0
1407
                  var(j) = 0
1403
               endif
1408
               endif
1404
            enddo
1409
            enddo
1405
 
1410
 
1406
c        Implict variable: INREGION (xcorner=param(1..4),ycorner=param(5..8) )
1411
c        Implict variable: INREGION (xcorner=param(1..4),ycorner=param(5..8) )
1407
         elseif ( ivar.eq.-6 ) then
1412
         elseif ( ivar.eq.-6 ) then
1408
            
1413
            
1409
            do j=1,4
1414
            do j=1,4
1410
               xcorner(j) = param(j  )
1415
               xcorner(j) = param(j  )
1411
               ycorner(j) = param(j+4)
1416
               ycorner(j) = param(j+4)
1412
            enddo
1417
            enddo
1413
 
1418
 
1414
            do j=1,nsel
1419
            do j=1,nsel
1415
               lon1   = tra(time(j),2)
1420
               lon1   = tra(time(j),2)
1416
               lat1   = tra(time(j),3)  
1421
               lat1   = tra(time(j),3)  
1417
               var(j) = inregion (lon1,lat1,xcorner,ycorner)               
1422
               var(j) = inregion (lon1,lat1,xcorner,ycorner)               
1418
            enddo
1423
            enddo
1419
 
1424
 
1420
c        Implict variable: TRIGGER
1425
c        Implict variable: TRIGGER
1421
         elseif ( ivar.eq. -7 ) then
1426
         elseif ( ivar.eq. -7 ) then
1422
            do j=1,nsel
1427
            do j=1,nsel
1423
               intvar(j) = trigger( time(j) ) 
1428
               intvar(j) = trigger( time(j) ) 
1424
            enddo
1429
            enddo
1425
 
1430
 
1426
c        Implicit variable: VERT0
1431
c        Implicit variable: VERT0
1427
         elseif ( ivar.eq. -8 ) then
1432
         elseif ( ivar.eq. -8 ) then
1428
            do j=1,nsel
1433
            do j=1,nsel
1429
               lev0   = tra(1      ,4)
1434
               lev0   = tra(1      ,4)
1430
               lev1   = tra(time(j),4)
1435
               lev1   = tra(time(j),4)
1431
               var(j) = lev0 - lev1
1436
               var(j) = lev0 - lev1
1432
            enddo
1437
            enddo
1433
 
1438
 
1434
c        Explicit variable (column index <ivar>)
1439
c        Explicit variable (column index <ivar>)
1435
         else
1440
         else
1436
            do j=1,nsel
1441
            do j=1,nsel
1437
               var(j) = tra(time(j),ivar)
1442
               var(j) = tra(time(j),ivar)
1438
            enddo
1443
            enddo
1439
 
1444
 
1440
         endif
1445
         endif
1441
 
1446
 
1442
c        Take MEAN of the variable (mean of selected times)
1447
c        Take MEAN of the variable (mean of selected times)
1443
         if (imode.eq.2) then
1448
         if (imode.eq.2) then
1444
            tmp=0.
1449
            tmp=0.
1445
            do j=1,nsel
1450
            do j=1,nsel
1446
               tmp=tmp+var(j)
1451
               tmp=tmp+var(j)
1447
            enddo
1452
            enddo
1448
            var(1)=tmp/real(nsel)
1453
            var(1)=tmp/real(nsel)
1449
            nsel=1
1454
            nsel=1
1450
 
1455
 
1451
c        Take MAX of the variable (maximum of selected times)
1456
c        Take MAX of the variable (maximum of selected times)
1452
         elseif (imode.eq.3) then
1457
         elseif (imode.eq.3) then
1453
            tmp=var(1)
1458
            tmp=var(1)
1454
            do j=2,nsel
1459
            do j=2,nsel
1455
               if (var(j).gt.tmp) tmp=var(j)
1460
               if (var(j).gt.tmp) tmp=var(j)
1456
            enddo
1461
            enddo
1457
            var(1)=tmp
1462
            var(1)=tmp
1458
            nsel=1
1463
            nsel=1
1459
            
1464
            
1460
c        Take MIN of the variable (minimum of selected times)
1465
c        Take MIN of the variable (minimum of selected times)
1461
         elseif (imode.eq.4) then
1466
         elseif (imode.eq.4) then
1462
            tmp=var(1)
1467
            tmp=var(1)
1463
            do j=2,nsel
1468
            do j=2,nsel
1464
               if (var(j).lt.tmp) tmp=var(j)
1469
               if (var(j).lt.tmp) tmp=var(j)
1465
            enddo
1470
            enddo
1466
            var(1)=tmp
1471
            var(1)=tmp
1467
            nsel=1
1472
            nsel=1
1468
 
1473
 
1469
c        Take VAR of the variable (variance over all selected times)
1474
c        Take VAR of the variable (variance over all selected times)
1470
         elseif (imode.eq.5) then
1475
         elseif (imode.eq.5) then
1471
            tmp=0.
1476
            tmp=0.
1472
            do j=1,nsel
1477
            do j=1,nsel
1473
               tmp=tmp+var(j)
1478
               tmp=tmp+var(j)
1474
            enddo
1479
            enddo
1475
            mea=tmp/real(nsel)
1480
            mea=tmp/real(nsel)
1476
            do j=1,nsel
1481
            do j=1,nsel
1477
              tmp=tmp+(var(j)-mea)**2
1482
              tmp=tmp+(var(j)-mea)**2
1478
            enddo
1483
            enddo
1479
            var(1)=1./real(nsel-1)*tmp
1484
            var(1)=1./real(nsel-1)*tmp
1480
            nsel=1
1485
            nsel=1
1481
 
1486
 
1482
c        Take SUM of the variable (sum over all selected times)
1487
c        Take SUM of the variable (sum over all selected times)
1483
         elseif (imode.eq.6) then
1488
         elseif (imode.eq.6) then
1484
            tmp=0.
1489
            tmp=0.
1485
            do j=1,nsel
1490
            do j=1,nsel
1486
               tmp=tmp+var(j)
1491
               tmp=tmp+var(j)
1487
            enddo
1492
            enddo
1488
            var(1)=tmp
1493
            var(1)=tmp
1489
            nsel=1
1494
            nsel=1
1490
            
1495
            
1491
c        Take CHANGE of the variable (absolute difference between first and last time)
1496
c        Take CHANGE of the variable (absolute difference between first and last time)
1492
         elseif (imode.eq.7) then
1497
         elseif (imode.eq.7) then
1493
            var(1)=abs(var(1)-var(nsel))
1498
            var(1)=abs(var(1)-var(nsel))
1494
            nsel=1
1499
            nsel=1
1495
 
1500
 
1496
c        Take DIFF of the variable (first minus last time)
1501
c        Take DIFF of the variable (first minus last time)
1497
         elseif (imode.eq.8) then
1502
         elseif (imode.eq.8) then
1498
            var(1)=var(1)-var(nsel)
1503
            var(1)=var(1)-var(nsel)
1499
            nsel=1
1504
            nsel=1
1500
 
1505
 
1501
c        Take RANGE of the variable
1506
c        Take RANGE of the variable
1502
         elseif (imode.eq.9) then
1507
         elseif (imode.eq.9) then
1503
            varmax=var(1)
1508
            varmax=var(1)
1504
            varmin=var(1)
1509
            varmin=var(1)
1505
            do j=2,nsel
1510
            do j=2,nsel
1506
               if (var(j).gt.varmax) varmax=var(j)
1511
               if (var(j).gt.varmax) varmax=var(j)
1507
               if (var(j).lt.varmin) varmin=var(j)
1512
               if (var(j).lt.varmin) varmin=var(j)
1508
            enddo
1513
            enddo
1509
            var(1) = varmax - varmin
1514
            var(1) = varmax - varmin
1510
            nsel=1
1515
            nsel=1
1511
 
1516
 
1512
c        Take the absolute value of the variable
1517
c        Take the absolute value of the variable
1513
         elseif (imode.eq.10) then
1518
         elseif (imode.eq.10) then
1514
            do j=1,nsel
1519
            do j=1,nsel
1515
               var(j)=abs( var(j) )
1520
               var(j)=abs( var(j) )
1516
            enddo
1521
            enddo
1517
         endif
1522
         endif
1518
 
1523
 
1519
c        --- Apply the operators to the single values ---
1524
c        --- Apply the operators to the single values ---
1520
 
1525
 
1521
         do j=1,nsel
1526
         do j=1,nsel
1522
 
1527
 
1523
c           GT
1528
c           GT
1524
            if (icmd.eq.1) then
1529
            if (icmd.eq.1) then
1525
               if (var(j).gt.param(1)) then
1530
               if (var(j).gt.param(1)) then
1526
                  istrue(j)=1
1531
                  istrue(j)=1
1527
               else
1532
               else
1528
                  istrue(j)=0
1533
                  istrue(j)=0
1529
               endif
1534
               endif
1530
               
1535
               
1531
c           LT
1536
c           LT
1532
            elseif (icmd.eq.2) then
1537
            elseif (icmd.eq.2) then
1533
               if (var(j).lt.param(1)) then
1538
               if (var(j).lt.param(1)) then
1534
                  istrue(j)=1
1539
                  istrue(j)=1
1535
               else
1540
               else
1536
                  istrue(j)=0
1541
                  istrue(j)=0
1537
               endif
1542
               endif
1538
 
1543
 
1539
c           IN
1544
c           IN
1540
            elseif (icmd.eq.3) then
1545
            elseif (icmd.eq.3) then
1541
               if ( (var(j).gt.param(1)).and.
1546
               if ( (var(j).gt.param(1)).and.
1542
     >              (var(j).lt.param(2)) ) 
1547
     >              (var(j).lt.param(2)) ) 
1543
     >         then
1548
     >         then
1544
                  istrue(j)=1
1549
                  istrue(j)=1
1545
               else
1550
               else
1546
                  istrue(j)=0
1551
                  istrue(j)=0
1547
               endif
1552
               endif
1548
 
1553
 
1549
c           OUT
1554
c           OUT
1550
            elseif (icmd.eq.4) then
1555
            elseif (icmd.eq.4) then
1551
               if ( (var(j).lt.param(1)).or.
1556
               if ( (var(j).lt.param(1)).or.
1552
     >              (var(j).gt.param(2)) ) 
1557
     >              (var(j).gt.param(2)) ) 
1553
     >         then
1558
     >         then
1554
                  istrue(j)=1
1559
                  istrue(j)=1
1555
               else
1560
               else
1556
                  istrue(j)=0
1561
                  istrue(j)=0
1557
               endif
1562
               endif
1558
 
1563
 
1559
c           EQ
1564
c           EQ
1560
            elseif (icmd.eq.5) then
1565
            elseif (icmd.eq.5) then
1561
               if (abs(var(j)-param(1)).lt.eps) then
1566
               if (abs(var(j)-param(1)).lt.eps) then
1562
                  istrue(j)=1
1567
                  istrue(j)=1
1563
               else
1568
               else
1564
                  istrue(j)=0
1569
                  istrue(j)=0
1565
               endif
1570
               endif
1566
 
1571
 
1567
c           TRUE
1572
c           TRUE
1568
            elseif (icmd.eq.6) then
1573
            elseif (icmd.eq.6) then
1569
               if (abs(var(j)).lt.eps) then
1574
               if (abs(var(j)).lt.eps) then
1570
                  istrue(j)=0
1575
                  istrue(j)=0
1571
               else
1576
               else
1572
                  istrue(j)=1
1577
                  istrue(j)=1
1573
               endif
1578
               endif
1574
 
1579
 
1575
c           FALSE
1580
c           FALSE
1576
            elseif (icmd.eq.7) then
1581
            elseif (icmd.eq.7) then
1577
               if (abs(var(j)).lt.eps) then
1582
               if (abs(var(j)).lt.eps) then
1578
                  istrue(j)=1
1583
                  istrue(j)=1
1579
               else
1584
               else
1580
                  istrue(j)=0
1585
                  istrue(j)=0
1581
               endif
1586
               endif
1582
 
1587
 
1583
c           ALL
1588
c           ALL
1584
            elseif (icmd.eq.8) then
1589
            elseif (icmd.eq.8) then
1585
               istrue(j) = 1
1590
               istrue(j) = 1
1586
               do k=1,nval
1591
               do k=1,nval
1587
                  iparam = nint(param(k))-1
1592
                  iparam = nint(param(k))-1
1588
                  if (btest(intvar(j),iparam).eqv..false.) then
1593
                  if (btest(intvar(j),iparam).eqv..false.) then
1589
                     istrue(j) = 0
1594
                     istrue(j) = 0
1590
                  endif
1595
                  endif
1591
               enddo
1596
               enddo
1592
               
1597
               
1593
c           ANY
1598
c           ANY
1594
            elseif (icmd.eq.9) then
1599
            elseif (icmd.eq.9) then
1595
               istrue(j) = 0
1600
               istrue(j) = 0
1596
               do k=1,nval
1601
               do k=1,nval
1597
                  iparam = nint(param(k))-1
1602
                  iparam = nint(param(k))-1
1598
                  if (btest(intvar(j),iparam).eqv..true.) then
1603
                  if (btest(intvar(j),iparam).eqv..true.) then
1599
                     istrue(j) = 1
1604
                     istrue(j) = 1
1600
                  endif
1605
                  endif
1601
               enddo
1606
               enddo
1602
 
1607
 
1603
c           NONE
1608
c           NONE
1604
            elseif (icmd.eq.10) then
1609
            elseif (icmd.eq.10) then
1605
               istrue(j) = 1
1610
               istrue(j) = 1
1606
               do k=1,nval
1611
               do k=1,nval
1607
                  iparam = nint(param(k))-1
1612
                  iparam = nint(param(k))-1
1608
                  if (btest(intvar(j),iparam).eqv..true.) then
1613
                  if (btest(intvar(j),iparam).eqv..true.) then
1609
                     istrue(j) = 0
1614
                     istrue(j) = 0
1610
                  endif
1615
                  endif
1611
               enddo
1616
               enddo
1612
   
1617
   
1613
            endif
1618
            endif
1614
 
1619
 
1615
         enddo
1620
         enddo
1616
 
1621
 
1617
c        --- Determine the overall boolean value ----------
1622
c        --- Determine the overall boolean value ----------
1618
            
1623
            
1619
c        ALL
1624
c        ALL
1620
         if (itime.eq.1) then
1625
         if (itime.eq.1) then
1621
            decision=1
1626
            decision=1
1622
            do j=1,nsel
1627
            do j=1,nsel
1623
               if (istrue(j).eq.0) then
1628
               if (istrue(j).eq.0) then
1624
                  decision=0
1629
                  decision=0
1625
                  goto 110
1630
                  goto 110
1626
               endif
1631
               endif
1627
            enddo
1632
            enddo
1628
 110        continue
1633
 110        continue
1629
 
1634
 
1630
c        ANY
1635
c        ANY
1631
         elseif (itime.eq.2) then
1636
         elseif (itime.eq.2) then
1632
            decision=0
1637
            decision=0
1633
            do j=1,nsel
1638
            do j=1,nsel
1634
               if (istrue(j).eq.1) then
1639
               if (istrue(j).eq.1) then
1635
                  decision=1
1640
                  decision=1
1636
                  goto 120
1641
                  goto 120
1637
               endif
1642
               endif
1638
            enddo
1643
            enddo
1639
 120        continue
1644
 120        continue
1640
           
1645
           
1641
c        NONE
1646
c        NONE
1642
         elseif (itime.eq.3) then
1647
         elseif (itime.eq.3) then
1643
            decision=1
1648
            decision=1
1644
            do j=1,nsel
1649
            do j=1,nsel
1645
               if (istrue(j).eq.1) then
1650
               if (istrue(j).eq.1) then
1646
                  decision=0
1651
                  decision=0
1647
                  goto 130
1652
                  goto 130
1648
               endif
1653
               endif
1649
            enddo
1654
            enddo
1650
 130        continue
1655
 130        continue
1651
 
1656
 
1652
c        TRIGGER
1657
c        TRIGGER
1653
         elseif (itime.lt.0) then
1658
         elseif (itime.lt.0) then
1654
            decision=1
1659
            decision=1
1655
            do j=1,nsel
1660
            do j=1,nsel
1656
               if (istrue(j).eq.1) then
1661
               if (istrue(j).eq.1) then
1657
                  trigger(j) = ior( trigger(j), 2**(abs(itime)-1) )
1662
                  trigger(j) = ior( trigger(j), 2**(abs(itime)-1) )
1658
               endif
1663
               endif
1659
            enddo
1664
            enddo
1660
            
1665
            
1661
         endif
1666
         endif
1662
 
1667
 
1663
c        --- Put the new boolean value onto the stack
1668
c        --- Put the new boolean value onto the stack
1664
 
1669
 
1665
         nstack=nstack+1
1670
         nstack=nstack+1
1666
         stack(nstack)=decision
1671
         stack(nstack)=decision
1667
 
1672
 
1668
c        Exit point for loop
1673
c        Exit point for loop
1669
 200     continue
1674
 200     continue
1670
         goto 100
1675
         goto 100
1671
 
1676
 
1672
      endif
1677
      endif
1673
 
1678
 
1674
c     Return the decision (selected or non-selected)
1679
c     Return the decision (selected or non-selected)
1675
 300  continue
1680
 300  continue
1676
 
1681
 
1677
      select=stack(1)
1682
      select=stack(1)
1678
 
1683
 
1679
      end
1684
      end
1680
      
1685
      
1681
 
1686
 
1682
c     --------------------------------------------------------------------------
1687
c     --------------------------------------------------------------------------
1683
c     Split a region string and get corners of the domain
1688
c     Split a region string and get corners of the domain
1684
c     --------------------------------------------------------------------------
1689
c     --------------------------------------------------------------------------
1685
 
1690
 
1686
      subroutine regionsplit(string,iregion,xcorner,ycorner)
1691
      subroutine regionsplit(string,iregion,xcorner,ycorner)
1687
 
1692
 
1688
c     The region string comes either as <lonw,lone,lats,latn> or as <lon1,lat1,
1693
c     The region string comes either as <lonw,lone,lats,latn> or as <lon1,lat1,
1689
c     lon2,lat2,lon3,lat3,lon4,lat4>: split it into ints components and get the
1694
c     lon2,lat2,lon3,lat3,lon4,lat4>: split it into ints components and get the
1690
c     four coordinates for the region
1695
c     four coordinates for the region
1691
      
1696
      
1692
      implicit none
1697
      implicit none
1693
 
1698
 
1694
c     Declaration of subroutine parameters
1699
c     Declaration of subroutine parameters
1695
      character*80    string
1700
      character*80    string
1696
      real            xcorner(4),ycorner(4)
1701
      real            xcorner(4),ycorner(4)
1697
      integer         iregion
1702
      integer         iregion
1698
 
1703
 
1699
c     Local variables
1704
c     Local variables
1700
      integer         i,n
1705
      integer         i,n
1701
      integer         il,ir
1706
      integer         il,ir
1702
      real            subfloat (80)
1707
      real            subfloat (80)
1703
      integer         stat
1708
      integer         stat
1704
      integer         len
1709
      integer         len
1705
 
1710
 
1706
c     ------- Split the string
1711
c     ------- Split the string
1707
      i    = 1
1712
      i    = 1
1708
      n    = 0
1713
      n    = 0
1709
      stat = 0
1714
      stat = 0
1710
      il   = 1
1715
      il   = 1
1711
      len  = len_trim(string)
1716
      len  = len_trim(string)
1712
 
1717
 
1713
 100  continue
1718
 100  continue
1714
 
1719
 
1715
c     Find start of a substring
1720
c     Find start of a substring
1716
      do while ( stat.eq.0 )
1721
      do while ( stat.eq.0 )
1717
         if ( string(i:i).ne.' ' ) then
1722
         if ( string(i:i).ne.' ' ) then
1718
            stat = 1
1723
            stat = 1
1719
            il   = i
1724
            il   = i
1720
         else
1725
         else
1721
            i = i + 1
1726
            i = i + 1
1722
         endif
1727
         endif
1723
      enddo
1728
      enddo
1724
 
1729
 
1725
c     Find end of substring
1730
c     Find end of substring
1726
      do while ( stat.eq.1 )         
1731
      do while ( stat.eq.1 )         
1727
         if ( ( string(i:i).eq.' ' ) .or. ( i.eq.len ) ) then
1732
         if ( ( string(i:i).eq.' ' ) .or. ( i.eq.len ) ) then
1728
            stat = 2
1733
            stat = 2
1729
            ir   = i
1734
            ir   = i
1730
         else
1735
         else
1731
            i    = i + 1
1736
            i    = i + 1
1732
         endif
1737
         endif
1733
      enddo
1738
      enddo
1734
 
1739
 
1735
c     Convert the substring into a number
1740
c     Convert the substring into a number
1736
      if ( stat.eq.2 ) then
1741
      if ( stat.eq.2 ) then
1737
         n = n + 1
1742
         n = n + 1
1738
         read(string(il:ir),*) subfloat(n)
1743
         read(string(il:ir),*) subfloat(n)
1739
         stat = 0
1744
         stat = 0
1740
      endif
1745
      endif
1741
 
1746
 
1742
      if ( i.lt.len ) goto 100
1747
      if ( i.lt.len ) goto 100
1743
 
1748
 
1744
 
1749
 
1745
c     -------- Get the region number
1750
c     -------- Get the region number
1746
      
1751
      
1747
      iregion = nint(subfloat(1))
1752
      iregion = nint(subfloat(1))
1748
 
1753
 
1749
c     -------- Get the corners of the region
1754
c     -------- Get the corners of the region
1750
      
1755
      
1751
      if ( n.eq.5 ) then     ! lonw(2),lone(3),lats(4),latn(5)
1756
      if ( n.eq.5 ) then     ! lonw(2),lone(3),lats(4),latn(5)
1752
 
1757
 
1753
         xcorner(1) = subfloat(2)
1758
         xcorner(1) = subfloat(2)
1754
         ycorner(1) = subfloat(4)
1759
         ycorner(1) = subfloat(4)
1755
 
1760
 
1756
         xcorner(2) = subfloat(3)
1761
         xcorner(2) = subfloat(3)
1757
         ycorner(2) = subfloat(4)
1762
         ycorner(2) = subfloat(4)
1758
 
1763
 
1759
         xcorner(3) = subfloat(3)
1764
         xcorner(3) = subfloat(3)
1760
         ycorner(3) = subfloat(5)
1765
         ycorner(3) = subfloat(5)
1761
         
1766
         
1762
         xcorner(4) = subfloat(2)
1767
         xcorner(4) = subfloat(2)
1763
         ycorner(4) = subfloat(5)
1768
         ycorner(4) = subfloat(5)
1764
        
1769
        
1765
      elseif ( n.eq.9 ) then     ! lon1,lat1,lon2,lat2,lon3,lon4,lat4
1770
      elseif ( n.eq.9 ) then     ! lon1,lat1,lon2,lat2,lon3,lon4,lat4
1766
 
1771
 
1767
         xcorner(1) = subfloat(2)
1772
         xcorner(1) = subfloat(2)
1768
         ycorner(1) = subfloat(3)
1773
         ycorner(1) = subfloat(3)
1769
 
1774
 
1770
         xcorner(2) = subfloat(4)
1775
         xcorner(2) = subfloat(4)
1771
         ycorner(2) = subfloat(5)
1776
         ycorner(2) = subfloat(5)
1772
 
1777
 
1773
         xcorner(3) = subfloat(6)
1778
         xcorner(3) = subfloat(6)
1774
         ycorner(3) = subfloat(7)
1779
         ycorner(3) = subfloat(7)
1775
         
1780
         
1776
         xcorner(4) = subfloat(8)
1781
         xcorner(4) = subfloat(8)
1777
         ycorner(4) = subfloat(9)
1782
         ycorner(4) = subfloat(9)
1778
 
1783
 
1779
      else
1784
      else
1780
         
1785
         
1781
         print*,' ERROR: invalid region specification '
1786
         print*,' ERROR: invalid region specification '
1782
         print*,'     ',trim(string)
1787
         print*,'     ',trim(string)
1783
         stop
1788
         stop
1784
         
1789
         
1785
      endif
1790
      endif
1786
         
1791
         
1787
 
1792
 
1788
      end
1793
      end
1789
 
1794
 
1790
c     --------------------------------------------------------------------------
1795
c     --------------------------------------------------------------------------
1791
c     Decide whether lat/lon point is in or out of region
1796
c     Decide whether lat/lon point is in or out of region
1792
c     --------------------------------------------------------------------------
1797
c     --------------------------------------------------------------------------
1793
      
1798
      
1794
      integer function inregion (lon,lat,xcorner,ycorner)
1799
      integer function inregion (lon,lat,xcorner,ycorner)
1795
      
1800
      
1796
c     Decide whether point (lon/lat) is in the region specified by <xcorner(1..4),
1801
c     Decide whether point (lon/lat) is in the region specified by <xcorner(1..4),
1797
c     ycorner(1..4).
1802
c     ycorner(1..4).
1798
      
1803
      
1799
      implicit none
1804
      implicit none
1800
      
1805
      
1801
c     Declaration of subroutine parameters
1806
c     Declaration of subroutine parameters
1802
      real    lon,lat
1807
      real    lon,lat
1803
      real    xcorner(4),ycorner(4)
1808
      real    xcorner(4),ycorner(4)
1804
 
1809
 
1805
c     Local variables
1810
c     Local variables
1806
      integer flag
1811
      integer flag
1807
      real    xmin,xmax,ymin,ymax
1812
      real    xmin,xmax,ymin,ymax
1808
      integer i
1813
      integer i
1809
 
1814
 
1810
c     Reset the flag
1815
c     Reset the flag
1811
      flag = 0
1816
      flag = 0
1812
 
1817
 
1813
c     Set some boundaries
1818
c     Set some boundaries
1814
      xmax = xcorner(1)
1819
      xmax = xcorner(1)
1815
      xmin = xcorner(1)
1820
      xmin = xcorner(1)
1816
      ymax = ycorner(1)
1821
      ymax = ycorner(1)
1817
      ymin = ycorner(1)
1822
      ymin = ycorner(1)
1818
      do i=2,4
1823
      do i=2,4
1819
        if (xcorner(i).lt.xmin) xmin = xcorner(i)
1824
        if (xcorner(i).lt.xmin) xmin = xcorner(i)
1820
        if (xcorner(i).gt.xmax) xmax = xcorner(i)
1825
        if (xcorner(i).gt.xmax) xmax = xcorner(i)
1821
        if (ycorner(i).lt.ymin) ymin = ycorner(i)
1826
        if (ycorner(i).lt.ymin) ymin = ycorner(i)
1822
        if (ycorner(i).gt.ymax) ymax = ycorner(i)
1827
        if (ycorner(i).gt.ymax) ymax = ycorner(i)
1823
      enddo
1828
      enddo
1824
 
1829
 
1825
c     Do the tests - set flag=1 if all tests pased
1830
c     Do the tests - set flag=1 if all tests pased
1826
      if (lon.lt.xmin) goto 970
1831
      if (lon.lt.xmin) goto 970
1827
      if (lon.gt.xmax) goto 970
1832
      if (lon.gt.xmax) goto 970
1828
      if (lat.lt.ymin) goto 970
1833
      if (lat.lt.ymin) goto 970
1829
      if (lat.gt.ymax) goto 970
1834
      if (lat.gt.ymax) goto 970
1830
      
1835
      
1831
      if ((lon-xcorner(1))*(ycorner(2)-ycorner(1))-
1836
      if ((lon-xcorner(1))*(ycorner(2)-ycorner(1))-
1832
     >    (lat-ycorner(1))*(xcorner(2)-xcorner(1)).gt.0.) goto 970
1837
     >    (lat-ycorner(1))*(xcorner(2)-xcorner(1)).gt.0.) goto 970
1833
      if ((lon-xcorner(2))*(ycorner(3)-ycorner(2))-
1838
      if ((lon-xcorner(2))*(ycorner(3)-ycorner(2))-
1834
     >    (lat-ycorner(2))*(xcorner(3)-xcorner(2)).gt.0.) goto 970
1839
     >    (lat-ycorner(2))*(xcorner(3)-xcorner(2)).gt.0.) goto 970
1835
      if ((lon-xcorner(3))*(ycorner(4)-ycorner(3))-
1840
      if ((lon-xcorner(3))*(ycorner(4)-ycorner(3))-
1836
     >    (lat-ycorner(3))*(xcorner(4)-xcorner(3)).gt.0.) goto 970
1841
     >    (lat-ycorner(3))*(xcorner(4)-xcorner(3)).gt.0.) goto 970
1837
      if ((lon-xcorner(4))*(ycorner(1)-ycorner(4))-
1842
      if ((lon-xcorner(4))*(ycorner(1)-ycorner(4))-
1838
     >    (lat-ycorner(4))*(xcorner(1)-xcorner(4)).gt.0.) goto 970
1843
     >    (lat-ycorner(4))*(xcorner(1)-xcorner(4)).gt.0.) goto 970
1839
 
1844
 
1840
      flag = 1
1845
      flag = 1
1841
 
1846
 
1842
c     Return the value
1847
c     Return the value
1843
 970  continue
1848
 970  continue
1844
      
1849
      
1845
      inregion = flag
1850
      inregion = flag
1846
      
1851
      
1847
      return
1852
      return
1848
      
1853
      
1849
      end
1854
      end
1850
 
1855
 
1851
   
1856
   
1852
c     --------------------------------------------------------------------------
1857
c     --------------------------------------------------------------------------
1853
c     Spherical distance between lat/lon points                                                       
1858
c     Spherical distance between lat/lon points                                                       
1854
c     --------------------------------------------------------------------------
1859
c     --------------------------------------------------------------------------
1855
 
1860
 
1856
      real function sdis(xp,yp,xq,yq)
1861
      real function sdis(xp,yp,xq,yq)
1857
c
1862
c
1858
c     calculates spherical distance (in km) between two points given
1863
c     calculates spherical distance (in km) between two points given
1859
c     by their spherical coordinates (xp,yp) and (xq,yq), respectively.
1864
c     by their spherical coordinates (xp,yp) and (xq,yq), respectively.
1860
c
1865
c
1861
      real      re
1866
      real      re
1862
      parameter (re=6370.)
1867
      parameter (re=6370.)
1863
      real      pi180
1868
      real      pi180
1864
      parameter (pi180=3.14159/180.)
1869
      parameter (pi180=3.14159/180.)
1865
      real      xp,yp,xq,yq,arg
1870
      real      xp,yp,xq,yq,arg
1866
 
1871
 
1867
      arg=sin(pi180*yp)*sin(pi180*yq)+
1872
      arg=sin(pi180*yp)*sin(pi180*yq)+
1868
     >    cos(pi180*yp)*cos(pi180*yq)*cos(pi180*(xp-xq))
1873
     >    cos(pi180*yp)*cos(pi180*yq)*cos(pi180*(xp-xq))
1869
      if (arg.lt.-1.) arg=-1.
1874
      if (arg.lt.-1.) arg=-1.
1870
      if (arg.gt.1.) arg=1.
1875
      if (arg.gt.1.) arg=1.
1871
 
1876
 
1872
      sdis=re*acos(arg)
1877
      sdis=re*acos(arg)
1873
 
1878
 
1874
      end
1879
      end
1875
 
1880
 
1876
 
1881
 
1877
c     ****************************************************************
1882
c     ****************************************************************
1878
c     * Given some spherical polygon S and some point X known to be  *
1883
c     * Given some spherical polygon S and some point X known to be  *
1879
c     * located inside S, these routines will determine if an arbit- *
1884
c     * located inside S, these routines will determine if an arbit- *
1880
c     * -rary point P lies inside S, outside S, or on its boundary.  *
1885
c     * -rary point P lies inside S, outside S, or on its boundary.  *
1881
c     * The calling program must first call DefSPolyBndry to define  *
1886
c     * The calling program must first call DefSPolyBndry to define  *
1882
c     * the boundary of S and the point X. Any subsequent call to    *
1887
c     * the boundary of S and the point X. Any subsequent call to    *
1883
c     * subroutine LctPtRelBndry will determine if some point P lies *
1888
c     * subroutine LctPtRelBndry will determine if some point P lies *
1884
c     * inside or outside S, or on its boundary. (Usually            *
1889
c     * inside or outside S, or on its boundary. (Usually            *
1885
c     * DefSPolyBndry is called once, then LctPrRelBndry is called   *
1890
c     * DefSPolyBndry is called once, then LctPrRelBndry is called   *
1886
c     * many times).                                                 *
1891
c     * many times).                                                 *
1887
c     *                                                              * 
1892
c     *                                                              * 
1888
c     * REFERENCE:            Bevis, M. and Chatelain, J.-L. (1989)  * 
1893
c     * REFERENCE:            Bevis, M. and Chatelain, J.-L. (1989)  * 
1889
c     *                       Maflaematical Geology, vol 21.         *
1894
c     *                       Maflaematical Geology, vol 21.         *
1890
c     * VERSION 1.0                                                  *
1895
c     * VERSION 1.0                                                  *
1891
c     ****************************************************************
1896
c     ****************************************************************
1892
 
1897
 
1893
      Subroutine DefSPolyBndry(vlat,vlon,nv,xlat, xlon)
1898
      Subroutine DefSPolyBndry(vlat,vlon,nv,xlat, xlon)
1894
 
1899
 
1895
c     ****************************************************************
1900
c     ****************************************************************
1896
c     * This mmn entry point is used m define ~e spheric~ polygon S  *
1901
c     * This mmn entry point is used m define ~e spheric~ polygon S  *
1897
c     * and the point X.                                             *
1902
c     * and the point X.                                             *
1898
c     * ARGUMENTS:                                                   *
1903
c     * ARGUMENTS:                                                   *
1899
c     * vlat,vlon (sent) ... vectors containing the latitude and     * 
1904
c     * vlat,vlon (sent) ... vectors containing the latitude and     * 
1900
c     *                      longitude of each vertex of the         *
1905
c     *                      longitude of each vertex of the         *
1901
c     *                      spherical polygon S. The ith.vertex is  *
1906
c     *                      spherical polygon S. The ith.vertex is  *
1902
c     *                      located at [vlat(i),vlon(i)].           *
1907
c     *                      located at [vlat(i),vlon(i)].           *
1903
c     * nv        (sent) ... the number of vertices and sides in the *
1908
c     * nv        (sent) ... the number of vertices and sides in the *
1904
c     *                      spherical polygon S                     *
1909
c     *                      spherical polygon S                     *
1905
c     * xlat,xlon (sent) ... latitude and longitude of some point X  *
1910
c     * xlat,xlon (sent) ... latitude and longitude of some point X  *
1906
c     *                      located inside S. X must not be located *
1911
c     *                      located inside S. X must not be located *
1907
c     *                      on any great circle that includes two   *
1912
c     *                      on any great circle that includes two   *
1908
c     *                      vertices of S.                          *
1913
c     *                      vertices of S.                          *
1909
c     *                                                              *
1914
c     *                                                              *
1910
c     * UNITS AND SIGN CONVENTION:                                   *
1915
c     * UNITS AND SIGN CONVENTION:                                   *
1911
c     *  Latitudes and longitudes are specified in degrees.          *
1916
c     *  Latitudes and longitudes are specified in degrees.          *
1912
c     *  Latitudes are positive to the north and negative to the     *
1917
c     *  Latitudes are positive to the north and negative to the     *
1913
c     *  south.                                                      *
1918
c     *  south.                                                      *
1914
c     *  Longitudes are positive to the east and negative to the     *
1919
c     *  Longitudes are positive to the east and negative to the     *
1915
c     *  west.                                                       *
1920
c     *  west.                                                       *
1916
c     *                                                              * 
1921
c     *                                                              * 
1917
c     * VERTEX ENUMERATION:                                          * 
1922
c     * VERTEX ENUMERATION:                                          * 
1918
c     * The vertices of S should be numbered sequentially around the *
1923
c     * The vertices of S should be numbered sequentially around the *
1919
c     * border of the spherical polygon. Vertex 1 lies between vertex*
1924
c     * border of the spherical polygon. Vertex 1 lies between vertex*
1920
c     * nv and vertex 2. Neighbouring vertices must be seperated by  *
1925
c     * nv and vertex 2. Neighbouring vertices must be seperated by  *
1921
c     * less than 180 degrees. (In order to generate a polygon side  *
1926
c     * less than 180 degrees. (In order to generate a polygon side  *
1922
c     * whose arc length equals or exceeds 180 degrees simply        *
1927
c     * whose arc length equals or exceeds 180 degrees simply        *
1923
c     * introduce an additional (pseudo)vertex). Having chosen       *
1928
c     * introduce an additional (pseudo)vertex). Having chosen       *
1924
c     * vertex 1, the user may number the remaining vertices in      *
1929
c     * vertex 1, the user may number the remaining vertices in      *
1925
c     * either direction. However if the user wishes to use the      *
1930
c     * either direction. However if the user wishes to use the      *
1926
c     * subroutine SPA to determine the area of the polygon S (Bevis *
1931
c     * subroutine SPA to determine the area of the polygon S (Bevis *
1927
c     * & Cambareri, 1987, Math. Geol., v.19, p. 335-346) then he or *
1932
c     * & Cambareri, 1987, Math. Geol., v.19, p. 335-346) then he or *
1928
c     * she must follow the convention whereby in moving around the  *
1933
c     * she must follow the convention whereby in moving around the  *
1929
c     * polygon border in the direction of increasing vertex number  *
1934
c     * polygon border in the direction of increasing vertex number  *
1930
c     * clockwise bends occur at salient vertices. A vertex is       *
1935
c     * clockwise bends occur at salient vertices. A vertex is       *
1931
c     * salient if the interior angle is less than 180 degrees.      *
1936
c     * salient if the interior angle is less than 180 degrees.      *
1932
c     * (In the case of a convex polygon this convention implies     *
1937
c     * (In the case of a convex polygon this convention implies     *
1933
c     * that vertices are numbered in clockwise sequence).           *
1938
c     * that vertices are numbered in clockwise sequence).           *
1934
c     ****************************************************************
1939
c     ****************************************************************
1935
 
1940
 
1936
      implicit none
1941
      implicit none
1937
      
1942
      
1938
      integer mxnv,nv
1943
      integer mxnv,nv
1939
 
1944
 
1940
c     ----------------------------------------------------------------
1945
c     ----------------------------------------------------------------
1941
c     Edit next statement to increase maximum number of vertices that 
1946
c     Edit next statement to increase maximum number of vertices that 
1942
c     may be used to define the spherical polygon S               
1947
c     may be used to define the spherical polygon S               
1943
c     The value of parameter mxnv in subroutine LctPtRelBndry must match
1948
c     The value of parameter mxnv in subroutine LctPtRelBndry must match
1944
c     that of parameter mxnv in this subroutine, as assigned above.
1949
c     that of parameter mxnv in this subroutine, as assigned above.
1945
c     ----------------------------------------------------------------
1950
c     ----------------------------------------------------------------
1946
      parameter (mxnv=2000)
1951
      parameter (mxnv=2000)
1947
 
1952
 
1948
      real  vlat(nv),vlon(nv),xlat,xlon,dellon
1953
      real  vlat(nv),vlon(nv),xlat,xlon,dellon
1949
      real  tlonv(mxnv),vlat_c(mxnv),vlon_c(mxnv),xlat_c,xlon_c
1954
      real  tlonv(mxnv),vlat_c(mxnv),vlon_c(mxnv),xlat_c,xlon_c
1950
      integer i,ibndry,nv_c,ip
1955
      integer i,ibndry,nv_c,ip
1951
 
1956
 
1952
      data ibndry/0/
1957
      data ibndry/0/
1953
      
1958
      
1954
      common/spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry
1959
      common/spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry
1955
 
1960
 
1956
      if (nv.gt.mxnv) then
1961
      if (nv.gt.mxnv) then
1957
         print *,'nv exceeds maximum allowed value'
1962
         print *,'nv exceeds maximum allowed value'
1958
         print *,'adjust parameter mxnv in subroutine DefSPolyBndry'
1963
         print *,'adjust parameter mxnv in subroutine DefSPolyBndry'
1959
         stop
1964
         stop
1960
      endif
1965
      endif
1961
 
1966
 
1962
      ibndry=1                  ! boundary defined at least once (flag)
1967
      ibndry=1                  ! boundary defined at least once (flag)
1963
      nv_c=nv                   ! copy for named common
1968
      nv_c=nv                   ! copy for named common
1964
      xlat_c=xlat               ! . . . .
1969
      xlat_c=xlat               ! . . . .
1965
      xlon_c=xlon               !
1970
      xlon_c=xlon               !
1966
 
1971
 
1967
      do i=1,nv
1972
      do i=1,nv
1968
         vlat_c(i)=vlat(i)      ! "
1973
         vlat_c(i)=vlat(i)      ! "
1969
         vlon_c(i)=vlon(i)      !
1974
         vlon_c(i)=vlon(i)      !
1970
 
1975
 
1971
         call TrnsfmLon(xlat,xlon,vlat(i),vlon(i),tlonv(i))
1976
         call TrnsfmLon(xlat,xlon,vlat(i),vlon(i),tlonv(i))
1972
 
1977
 
1973
         if (i.gt.1) then
1978
         if (i.gt.1) then
1974
            ip=i-1
1979
            ip=i-1
1975
         else
1980
         else
1976
            ip=nv
1981
            ip=nv
1977
         endif
1982
         endif
1978
         
1983
         
1979
         if ((vlat(i).eq.vlat(ip)).and.(vlon(i).eq.vlon(ip))) then
1984
         if ((vlat(i).eq.vlat(ip)).and.(vlon(i).eq.vlon(ip))) then
1980
            print *,'DefSPolyBndry detects user error:'
1985
            print *,'DefSPolyBndry detects user error:'
1981
            print *,'vertices ',i,' and ',ip,' are not distinct'
1986
            print *,'vertices ',i,' and ',ip,' are not distinct'
1982
            print*,'lat ',i,ip,vlat(i),vlat(ip)
1987
            print*,'lat ',i,ip,vlat(i),vlat(ip)
1983
            print*,'lon ',i,ip,vlon(i),vlon(ip)            
1988
            print*,'lon ',i,ip,vlon(i),vlon(ip)            
1984
            stop
1989
            stop
1985
         endif
1990
         endif
1986
 
1991
 
1987
         if (tlonv(i).eq.tlonv(ip)) then
1992
         if (tlonv(i).eq.tlonv(ip)) then
1988
            print *,'DefSPolyBndry detects user error:'
1993
            print *,'DefSPolyBndry detects user error:'
1989
            print *,'vertices ',i,' & ',ip,' on same gt. circle as X'
1994
            print *,'vertices ',i,' & ',ip,' on same gt. circle as X'
1990
            stop
1995
            stop
1991
         endif
1996
         endif
1992
 
1997
 
1993
         if (vlat(i).eq.(-vlat(ip))) then
1998
         if (vlat(i).eq.(-vlat(ip))) then
1994
            dellon=vlon(i)-vlon(ip)
1999
            dellon=vlon(i)-vlon(ip)
1995
            if (dellon.gt.+180.) dellon=dellon-360.
2000
            if (dellon.gt.+180.) dellon=dellon-360.
1996
            if (dellon.lt.-180.) dellon=dellon-360.
2001
            if (dellon.lt.-180.) dellon=dellon-360.
1997
            if ((dellon.eq.+180.0).or.(dellon.eq.-180.0)) then
2002
            if ((dellon.eq.+180.0).or.(dellon.eq.-180.0)) then
1998
               print *,'DefSPolyBndry detects user error:'
2003
               print *,'DefSPolyBndry detects user error:'
1999
               print *,'vertices ',i,' and ',ip,' are antipodal'
2004
               print *,'vertices ',i,' and ',ip,' are antipodal'
2000
               stop
2005
               stop
2001
            endif
2006
            endif
2002
         endif
2007
         endif
2003
      enddo
2008
      enddo
2004
 
2009
 
2005
      return
2010
      return
2006
      
2011
      
2007
      end
2012
      end
2008
 
2013
 
2009
 
2014
 
2010
c     ****************************************************************
2015
c     ****************************************************************
2011
 
2016
 
2012
      Subroutine LctPtRelBndry(plat,plon,location)
2017
      Subroutine LctPtRelBndry(plat,plon,location)
2013
 
2018
 
2014
c     ****************************************************************
2019
c     ****************************************************************
2015
 
2020
 
2016
c     ****************************************************************
2021
c     ****************************************************************
2017
c     * This routine is used to see if some point P is located       *
2022
c     * This routine is used to see if some point P is located       *
2018
c     * inside, outside or on the boundary of the spherical polygon  *
2023
c     * inside, outside or on the boundary of the spherical polygon  *
2019
c     * S previously defined by a call to subroutine DefSPolyBndry.  *
2024
c     * S previously defined by a call to subroutine DefSPolyBndry.  *
2020
c     * There is a single restriction on point P: it must not be     *
2025
c     * There is a single restriction on point P: it must not be     *
2021
c     * antipodal to the point X defined in the call to DefSPolyBndry*
2026
c     * antipodal to the point X defined in the call to DefSPolyBndry*
2022
c     * (ie.P and X cannot be seperated by exactly 180 degrees).     *
2027
c     * (ie.P and X cannot be seperated by exactly 180 degrees).     *
2023
c     * ARGUMENTS:                                                   *  
2028
c     * ARGUMENTS:                                                   *  
2024
c     * plat,plon (sent)... the latitude and longitude of point P    *
2029
c     * plat,plon (sent)... the latitude and longitude of point P    *
2025
c     * location (returned)... specifies the location of P:          *
2030
c     * location (returned)... specifies the location of P:          *
2026
c     *                        location=0 implies P is outside of S  *
2031
c     *                        location=0 implies P is outside of S  *
2027
c     *                        location=1 implies P is inside of S   *
2032
c     *                        location=1 implies P is inside of S   *
2028
c     *                        location=2 implies P on boundary of S *
2033
c     *                        location=2 implies P on boundary of S *
2029
c     *                        location=3 implies user error (P is   *
2034
c     *                        location=3 implies user error (P is   *
2030
c     *                                     antipodal to X)          *
2035
c     *                                     antipodal to X)          *
2031
c     * UNFfS AND SIGN CONVENTION:                                   * 
2036
c     * UNFfS AND SIGN CONVENTION:                                   * 
2032
c     *  Latitudes and longitudes are specified in degrees.          *
2037
c     *  Latitudes and longitudes are specified in degrees.          *
2033
c     *  Latitudes are positive to the north and negative to the     *
2038
c     *  Latitudes are positive to the north and negative to the     *
2034
c     *  south.                                                      *    
2039
c     *  south.                                                      *    
2035
c     *  Longitudes are positive to the east and negative to the     *
2040
c     *  Longitudes are positive to the east and negative to the     *
2036
c     *  west.                                                       *
2041
c     *  west.                                                       *
2037
c     ****************************************************************
2042
c     ****************************************************************
2038
      
2043
      
2039
      implicit none
2044
      implicit none
2040
      
2045
      
2041
      integer mxnv
2046
      integer mxnv
2042
 
2047
 
2043
c     ----------------------------------------------------------------
2048
c     ----------------------------------------------------------------
2044
c     The statement below must match that in subroutine DefSPolyBndry
2049
c     The statement below must match that in subroutine DefSPolyBndry
2045
c     ----------------------------------------------------------------
2050
c     ----------------------------------------------------------------
2046
 
2051
 
2047
      parameter (mxnv=2000)
2052
      parameter (mxnv=2000)
2048
 
2053
 
2049
      real tlonv(mxnv),vlat_c(mxnv),vlon_c(mxnv),xlat_c,xlon_c
2054
      real tlonv(mxnv),vlat_c(mxnv),vlon_c(mxnv),xlat_c,xlon_c
2050
      real plat,plon,vAlat,vAlon,vBlat,vBlon,tlonA,tlonB,tlonP
2055
      real plat,plon,vAlat,vAlon,vBlat,vBlon,tlonA,tlonB,tlonP
2051
      real tlon_X,tlon_P,tlon_B,dellon
2056
      real tlon_X,tlon_P,tlon_B,dellon
2052
      integer i,ibndry,nv_c,location,icross,ibrngAB,ibrngAP,ibrngPB
2057
      integer i,ibndry,nv_c,location,icross,ibrngAB,ibrngAP,ibrngPB
2053
      integer ibrng_BX,ibrng_BP,istrike
2058
      integer ibrng_BX,ibrng_BP,istrike
2054
 
2059
 
2055
      common/spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry
2060
      common/spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry
2056
 
2061
 
2057
      if (ibndry.eq.0) then     ! user has never defined the bndry
2062
      if (ibndry.eq.0) then     ! user has never defined the bndry
2058
         print*,'Subroutine LctPtRelBndry detects user error:'
2063
         print*,'Subroutine LctPtRelBndry detects user error:'
2059
         print*,'Subroutine DefSPolyBndry must be called before'
2064
         print*,'Subroutine DefSPolyBndry must be called before'
2060
         print*,'subroutine LctPtRelBndry can be called'
2065
         print*,'subroutine LctPtRelBndry can be called'
2061
         stop
2066
         stop
2062
      endif
2067
      endif
2063
 
2068
 
2064
      if (plat.eq.(-xlat_c)) then
2069
      if (plat.eq.(-xlat_c)) then
2065
         dellon=plon-xlon_c
2070
         dellon=plon-xlon_c
2066
         if (dellon.lt.(-180.)) dellon=dellon+360.
2071
         if (dellon.lt.(-180.)) dellon=dellon+360.
2067
         if (dellon.gt.+180.) dellon=dellon-360.
2072
         if (dellon.gt.+180.) dellon=dellon-360.
2068
         if ((dellon.eq.+180.0).or.(dellon.eq.-180.)) then
2073
         if ((dellon.eq.+180.0).or.(dellon.eq.-180.)) then
2069
            print*,'Warning: LctPtRelBndry detects case P antipodal
2074
            print*,'Warning: LctPtRelBndry detects case P antipodal
2070
     >           to X'
2075
     >           to X'
2071
            print*,'location of P relative to S is undetermined'
2076
            print*,'location of P relative to S is undetermined'
2072
            location=3
2077
            location=3
2073
            return
2078
            return
2074
         endif
2079
         endif
2075
      endif 
2080
      endif 
2076
 
2081
 
2077
      location=0                ! default ( P is outside S)
2082
      location=0                ! default ( P is outside S)
2078
      icross=0                  ! initialize counter
2083
      icross=0                  ! initialize counter
2079
 
2084
 
2080
      if ((plat.eq.xlat_c).and.(plon.eq.xlon_c)) then
2085
      if ((plat.eq.xlat_c).and.(plon.eq.xlon_c)) then
2081
         location=1
2086
         location=1
2082
         return
2087
         return
2083
      endif
2088
      endif
2084
 
2089
 
2085
      
2090
      
2086
      call TrnsfmLon (xlat_c,xlon_c,plat,plon,tlonP)
2091
      call TrnsfmLon (xlat_c,xlon_c,plat,plon,tlonP)
2087
 
2092
 
2088
      do i=1,nv_c              ! start of loop over sides of S 
2093
      do i=1,nv_c              ! start of loop over sides of S 
2089
 
2094
 
2090
         vAlat=vlat_c(i)
2095
         vAlat=vlat_c(i)
2091
         vAlon=vlon_c(i)
2096
         vAlon=vlon_c(i)
2092
         tlonA=tlonv(i)
2097
         tlonA=tlonv(i)
2093
 
2098
 
2094
         if (i.lt.nv_c) then
2099
         if (i.lt.nv_c) then
2095
            vBlat=vlat_c(i+1)
2100
            vBlat=vlat_c(i+1)
2096
            vBlon=vlon_c(i+1)
2101
            vBlon=vlon_c(i+1)
2097
            tlonB=tlonv(i+1)
2102
            tlonB=tlonv(i+1)
2098
         else
2103
         else
2099
            vBlat=vlat_c(1)
2104
            vBlat=vlat_c(1)
2100
            vBlon=vlon_c(1)
2105
            vBlon=vlon_c(1)
2101
            tlonB=tlonv(1)
2106
            tlonB=tlonv(1)
2102
         endif
2107
         endif
2103
         
2108
         
2104
         istrike=0
2109
         istrike=0
2105
         
2110
         
2106
         if (tlonP.eq.tlonA) then
2111
         if (tlonP.eq.tlonA) then
2107
            istrike=1
2112
            istrike=1
2108
         else
2113
         else
2109
            call EastOrWest(tlonA,tlonB,ibrngAB)
2114
            call EastOrWest(tlonA,tlonB,ibrngAB)
2110
            call EastOrWest(tlonA,tlonP,ibrngAP)
2115
            call EastOrWest(tlonA,tlonP,ibrngAP)
2111
            call EastOrWest(tlonP,tlonB,ibrngPB)
2116
            call EastOrWest(tlonP,tlonB,ibrngPB)
2112
            
2117
            
2113
 
2118
 
2114
            if((ibrngAP.eq.ibrngAB).and.(ibrngPB.eq.ibrngAB)) istrike=1
2119
            if((ibrngAP.eq.ibrngAB).and.(ibrngPB.eq.ibrngAB)) istrike=1
2115
         endif
2120
         endif
2116
 
2121
 
2117
         
2122
         
2118
         if (istrike.eq.1) then
2123
         if (istrike.eq.1) then
2119
 
2124
 
2120
            if ((plat.eq.vAlat).and.(plon.eq.vAlon)) then
2125
            if ((plat.eq.vAlat).and.(plon.eq.vAlon)) then
2121
               location=2       ! P lies on a vertex of S
2126
               location=2       ! P lies on a vertex of S
2122
               return
2127
               return
2123
            endif
2128
            endif
2124
            call TrnsfmLon(vAlat,vAlon,xlat_c,xlon_c,tlon_X)
2129
            call TrnsfmLon(vAlat,vAlon,xlat_c,xlon_c,tlon_X)
2125
            call TrnsfmLon(vAlat,vAlon,vBlat,vBlon,tlon_B)
2130
            call TrnsfmLon(vAlat,vAlon,vBlat,vBlon,tlon_B)
2126
            call TrnsfmLon(vAlat,vAlon,plat,plon,tlon_P)
2131
            call TrnsfmLon(vAlat,vAlon,plat,plon,tlon_P)
2127
            
2132
            
2128
            if (tlon_P.eq.tlon_B) then
2133
            if (tlon_P.eq.tlon_B) then
2129
               location=2       ! P lies on side of S
2134
               location=2       ! P lies on side of S
2130
               return 
2135
               return 
2131
            else
2136
            else
2132
               call EastOrWest(tlon_B,tlon_X,ibrng_BX)
2137
               call EastOrWest(tlon_B,tlon_X,ibrng_BX)
2133
               call EastOrWest(tlon_B,tlon_P,ibrng_BP)
2138
               call EastOrWest(tlon_B,tlon_P,ibrng_BP)
2134
               if(ibrng_BX.eq.(-ibrng_BP)) icross=icross+1
2139
               if(ibrng_BX.eq.(-ibrng_BP)) icross=icross+1
2135
            endif
2140
            endif
2136
            
2141
            
2137
         endif
2142
         endif
2138
      enddo                     ! end of loop over the sides of S
2143
      enddo                     ! end of loop over the sides of S
2139
 
2144
 
2140
 
2145
 
2141
c     if the arc XP crosses the boundary S an even number of times then P
2146
c     if the arc XP crosses the boundary S an even number of times then P
2142
c     is in S
2147
c     is in S
2143
 
2148
 
2144
      if (mod(icross,2).eq.0) location=1
2149
      if (mod(icross,2).eq.0) location=1
2145
 
2150
 
2146
      return
2151
      return
2147
 
2152
 
2148
      end
2153
      end
2149
 
2154
 
2150
 
2155
 
2151
c     ****************************************************************
2156
c     ****************************************************************
2152
      
2157
      
2153
      subroutine TrnsfmLon(plat,plon,qlat,qlon,tranlon)
2158
      subroutine TrnsfmLon(plat,plon,qlat,qlon,tranlon)
2154
 
2159
 
2155
c     ****************************************************************
2160
c     ****************************************************************
2156
c     * This subroutine is required by subroutines DefSPolyBndry &   *
2161
c     * This subroutine is required by subroutines DefSPolyBndry &   *
2157
c     * LctPtRelBndry. It finds the 'longitude' of point Q in a      *
2162
c     * LctPtRelBndry. It finds the 'longitude' of point Q in a      *
2158
c     * geographic coordinate system for which point P acts as a     *
2163
c     * geographic coordinate system for which point P acts as a     *
2159
c     * 'north pole'. SENT: plat,plon,qlat,qlon, in degrees.         *
2164
c     * 'north pole'. SENT: plat,plon,qlat,qlon, in degrees.         *
2160
c     * RETURNED: tranlon, in degrees.                               *
2165
c     * RETURNED: tranlon, in degrees.                               *
2161
c     ****************************************************************
2166
c     ****************************************************************
2162
 
2167
 
2163
      implicit none
2168
      implicit none
2164
 
2169
 
2165
      real pi,dtr,plat,plon,qlat,qlon,tranlon,t,b
2170
      real pi,dtr,plat,plon,qlat,qlon,tranlon,t,b
2166
      parameter (pi=3.141592654,dtr=pi/180.0)
2171
      parameter (pi=3.141592654,dtr=pi/180.0)
2167
 
2172
 
2168
      if (plat.eq.90.) then
2173
      if (plat.eq.90.) then
2169
         tranlon=qlon
2174
         tranlon=qlon
2170
      else
2175
      else
2171
         t=sin((qlon-plon)*dtr)*cos(qlat*dtr)
2176
         t=sin((qlon-plon)*dtr)*cos(qlat*dtr)
2172
         b=sin(dtr*qlat)*cos(plat*dtr)-cos(qlat*dtr)*sin(plat*dtr)
2177
         b=sin(dtr*qlat)*cos(plat*dtr)-cos(qlat*dtr)*sin(plat*dtr)
2173
     >    *cos((qlon-plon)*dtr)
2178
     >    *cos((qlon-plon)*dtr)
2174
         tranlon=atan2(t,b)/dtr
2179
         tranlon=atan2(t,b)/dtr
2175
      endif
2180
      endif
2176
 
2181
 
2177
      return
2182
      return
2178
      end
2183
      end
2179
 
2184
 
2180
c     ****************************************************************
2185
c     ****************************************************************
2181
 
2186
 
2182
      subroutine EastOrWest(clon,dlon,ibrng)
2187
      subroutine EastOrWest(clon,dlon,ibrng)
2183
 
2188
 
2184
c     ****************************************************************
2189
c     ****************************************************************
2185
c     * This subroutine is required by subroutine LctPtRelBndry.     *
2190
c     * This subroutine is required by subroutine LctPtRelBndry.     *
2186
c     * This routine determines if in travelling the shortest path   *
2191
c     * This routine determines if in travelling the shortest path   *
2187
c     * from point C (at longitude clon) to point D (at longitude    *
2192
c     * from point C (at longitude clon) to point D (at longitude    *
2188
c     * dlon) one is heading east, west or neither.                  *
2193
c     * dlon) one is heading east, west or neither.                  *
2189
c     * SENT: clon,dlon; in degrees. RETURNED: ibrng                 *
2194
c     * SENT: clon,dlon; in degrees. RETURNED: ibrng                 *
2190
c     * (1=east,-1=west, 0=neither).                                 *
2195
c     * (1=east,-1=west, 0=neither).                                 *
2191
c     ****************************************************************
2196
c     ****************************************************************
2192
 
2197
 
2193
      implicit none
2198
      implicit none
2194
      real clon,dlon,del
2199
      real clon,dlon,del
2195
      integer ibrng
2200
      integer ibrng
2196
      del=dlon-clon
2201
      del=dlon-clon
2197
      if (del.gt.180.) del=del-360.
2202
      if (del.gt.180.) del=del-360.
2198
      if (del.lt.-180.) del=del+360.
2203
      if (del.lt.-180.) del=del+360.
2199
      if ((del.gt.0.0).and.(del.ne.180.)) then
2204
      if ((del.gt.0.0).and.(del.ne.180.)) then
2200
         ibrng=-1               ! (D is west of C)
2205
         ibrng=-1               ! (D is west of C)
2201
      elseif ((del.lt.0.0).and.(del.ne.-180.)) then
2206
      elseif ((del.lt.0.0).and.(del.ne.-180.)) then
2202
         ibrng=+1               ! (D is east of C)
2207
         ibrng=+1               ! (D is east of C)
2203
      else
2208
      else
2204
         ibrng=0                ! (D north or south of C)
2209
         ibrng=0                ! (D north or south of C)
2205
      endif
2210
      endif
2206
      return
2211
      return
2207
      end
2212
      end