Rev 3 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
SUBROUTINE special_stt (flag,cmd,tra,ntim,ncol,
> vars,times,param,nparam,outfile)
c ***************************************************************************
c * *
c * OUTPUT: flag -> 1 if trajectory is selected, 0 if not *
c * *
c * INPUT: cmd <- command string *
c * tra(ntim,ncol) <- single trajectory: indices time,column *
c * ntim <- number of times *
c * ncol <- number of columns (including time,lon,lat,p) *
c * vars(ncol) <- names of columns *
c * times(ntim) <- List of times
c * param(nparam) <- parameter values *
c * nparam <- number of parameters *
c * *
c ***************************************************************************
implicit none
c ---------------------------------------------------------------------------
c Declaration of subroutine parameters
c ---------------------------------------------------------------------------
integer flag ! Boolean flag whether trajectory is selected
character*80 cmd ! Command string
integer ntim,ncol ! Dimension of single trajectory
real tra(ntim,ncol) ! Single trajectory
character*80 vars(ncol) ! Name of columns
real times(ntim) ! List of times
integer nparam ! # parameters
real param(1000) ! List of parameters
character*80 outfile ! NAme of output file
integer i,n ! Loop indices
c ---------------------------------------------------------------------------
c Local variables for SPECIAL:WCB
c ---------------------------------------------------------------------------
integer ip,i0,i1
c ---------------------------------------------------------------------------
c Local variables for SPECIAL:STT
c ---------------------------------------------------------------------------
integer debugflag
integer tb,ta !tb and ta are the minimum residence times before and after the exchange
integer stat, ex, outputflag !Variables for I/O files
integer labelflag !Flag to handle label field
integer pvflag, thflag, zflag, pflag !Flags to signal presence of various fields
integer pvcol,thcol,labelcol,zcol,pcol !Positions of PV, TH, LABEL, z and p columns
real mean1, mean2, sd1, sd2 !Mean and standard deviations of PV and TH
real deltat !Trajectory timestep
real extime, exlon, exlat, exth, exheight, expres!Position at exchange time
character*80 namefile !Name of output file
real a,b !Normalized tropopause distance for PV and TH
real thtrop, pvtrop !Tropopause level in K and pvu
integer count1, count2
integer sttcount, p !Ancillary variables in STT do while loop
real,allocatable, dimension (:) :: tropdist ! Vector for normalized distance from tropopause
real,allocatable, dimension (:) :: exflag ! Vector for normalized distance from tropopause
integer, dimension (ntim) :: pos ! Vector to store exchange indices
c -------------------------------------------------------------------------- %)
c SPECIAL:STT:pvtrop,thtrop,tmin_b,tmin_f,outputflag %)
c --------------------------------------------------------------------------- %)
if ( cmd.eq.'STT' ) then
c Reset the flag for selection
flag = 0
c Reset the flag for debugging
debugflag = 0
c Set other flags
labelflag = 0
pvflag = 0
thflag = 0
C Set data at the exchange
extime = 0
exlon = 0
exlat = 0
exheight = 0
expres = 0
c PV and TH threshold read from command line
pvtrop = param(1)
thtrop = param(2)
c Determine number of time steps in the trajectory
c Handles backward OR forward trajectories
if ( (ntim.eq.0).or.(ntim.eq.1) ) then
print*,' ERROR: zero length trajectory in SPECIAL:STT... Stop' !If there are problems, stop computation.
stop
endif
deltat = (times(ntim)-times(1))/(ntim-1) !By default array indexing starts in Fortran at 1
C Now some checks for essential fields : label, potential vorticity, potential temperature
c Check for the presence of the LABEL field
labelcol = 1
do i = 1,ncol
if((vars(i) .eq. 'LABEL').or.(vars(i) .eq. 'label')) then
labelflag = 1
labelcol = i
if(debugflag .eq. 1) then
print*, 'Found label'
endif
endif
enddo
c Check for the presence of the variables PV and TH
pvcol = 1
thcol = 1
zcol = 1
pcol = 1 !In case th or pv are not available, tra(timestep,thcol) is always defined
do i = 1,ncol
if((vars(i) .eq. 'PV') .or. (vars(i) .eq. 'POT_VORTI')) then
pvflag = 1
pvcol = i
endif
enddo
do i = 1,ncol
if((vars(i) .eq. 'TH') .or. (vars(i) .eq. 'POT_T')) then
thflag = 1
thcol = i
endif
enddo
do i = 1,ncol
if((vars(i) .eq. 'z') .or. (vars(i) .eq. 'Z')) then
zcol = i
zflag = 1
endif
enddo
do i = 1,ncol
if((vars(i) .eq. 'p') .or. (vars(i) .eq. 'P')) then
pcol = i
pflag = 1
endif
enddo
c No PV and THETA available: not possible determining tropopause. Program stop.
if ( (thflag .eq. 0).and.(pvflag .eq. 0) ) then
print*,' ERROR: no PV and no TH in SPECIAL:STT..'
print*,' ERROR: not possible determining tropopause'
stop
endif
c Check for missing data in the trajectories
do n=1,ntim
if ((tra(n,pvcol).lt.-500.).and.(pvflag.eq.1.)) then
if(debugflag .eq. 1) then
print*,'WARNING: PV missing data',tra(n,pvcol)
print*,'Trajectory skipped'
endif
goto 600
endif
if ((tra(n,thcol) .lt.-500.).and.(thflag .eq. 1.)) then
if(debugflag .eq. 1) then
print*,'WARNING: TH missing data',tra(n,thcol)
print*,'Trajectory skipped'
endif
goto 600
endif
enddo
c Computing mean of PV and TH along a trajectory
mean1=0.
count1=0
mean2=0.
count2=0
do n=1,ntim
if ((tra(n,pvcol).gt.-100.).and.(pvflag .eq. 1)) then
count1=count1+1
mean1=mean1+tra(n,pvcol)
else
if(debugflag .eq. 1) then
print*,'WARNING: PV is missing or non-physical, mean1 = 0'
endif
mean1 = 0
endif
if ((tra(n,thcol) .gt. 1E-6) .and. (thflag .eq. 1)) then
count2=count2+1
mean2=mean2+tra(n,thcol)
else
if(debugflag .eq. 1) then
print*,'WARNING: TH is missing or non-physical, mean1 = 0'
endif
mean2 = 0
endif
enddo
c Compute average, otherwise skip problematic trajectories
if (count1.ne.0) then
mean1=mean1/count1
endif
if (count2.ne.0) then
mean2=mean2/count2
endif
if ( (count1.eq.0) .and. (count2.eq.0) )then
if(debugflag .eq. 1) then
print*, 'Trajectory with only missing data skipped'
endif
goto 600
endif
c Computing standard deviation of PV and TH along a trajectory
sd1=0.
count1=0.
sd2=0.
count2=0.
do n=1,ntim
if (tra(n,pvcol).gt.-100.) then
count1=count1+1.
sd1=sd1+(tra(n,pvcol)-mean1)**2
endif
if (tra(n,thcol).gt. 0.) then
count2=count2+1.
sd2=sd2+(tra(n,thcol)-mean2)**2
endif
enddo
sd1=sqrt(sd1/(count1-1.))
sd2=sqrt(sd2/(count2-1.))
c Allocate distance array
allocate(tropdist(1:ntim),stat=stat)
if (stat.ne.0) then
print*,'ERROR: allocating array tropdist
¬ possible in SPECIAL:STT.. '
stop
endif
c If LABEL is not available, go to section without usage of label
if(labelflag .ne. 1) goto 300
C-------------------------------------------------------------------------------------------------------------------------
c BEGINNING OF THE SECTION WITH LABEL
C-------------------------------------------------------------------------------------------------------------------------
c Check for label field
do i = 1,ntim
if((tra(i,labelcol) .ne.1) .and. (tra(i,labelcol) .ne.2)) then
if(debugflag .eq. 1) then
print*,'WARNING: unexpected label field in SPECIAL:STT.. '
endif
print*,'WARNING: unused label field in SPECIAL:STT'
goto 300
endif
end do
c Distance from the '2 PVU, 380 K' tropopause (-:trop/+:strat) : pvtrop, thtrop if PV and TH and LABEL are available
if ( (pvflag .ne. 0) .and. (thflag .ne. 0) .and.
&(labelflag .eq. 1)) then
if(debugflag .eq. 1) then
print*,'Tropopause detected with PV, TH and LABEL'
endif
do n=1,ntim
a=abs(pvtrop-abs(tra(n,pvcol)))/sd1 ! a = tropdist(PV)
b=abs(thtrop-tra(n,thcol))/sd2 ! b = tropdist(TH)
if (tra(n,labelcol) .eq. 1) then ! Troposphere (LABEL)
tropdist(n)=-min(a,b)
else
tropdist(n)=+min(a,b)
endif
enddo
endif
c If PV is not available, use only TH
if (pvflag .eq. 0) then
if(debugflag .eq. 1) then
print*,'Tropopause detected with TH only'
endif
do n=1,ntim
b=abs(thtrop-tra(n,thcol))/sd2 ! b = tropdist(TH)
if(tra(n,labelcol) .eq. 1) then ! Troposphere (TH)
tropdist(n)= -b
else
tropdist(n)= b ! Stratosphere (TH)
endif
enddo
endif
c If TH is not available, use only PV
if (thflag .eq. 0) then
if(debugflag .eq. 1) then
print*,'Tropopause detected with PV only'
endif
do n=1,ntim
a=abs(pvtrop-tra(n,pvcol))/sd2 ! a = tropdist(PV)
if( (tra(n,pvcol).lt.pvtrop) .and.
&(tra(n,labelcol) .eq. 1)) then ! Troposphere (PV)
tropdist(n)= -a
else
tropdist(n)= a ! Stratosphere (PV)
endif
enddo
endif
C Detecting STT with LABEL field
c If PV is lower than pvtrop despite the label is 2, then in next step this potential STT is not considered.
sttcount = 0
do i=2,ntim
if((tropdist(i)*tropdist(i-1) .lt. 0) .and.
&(tropdist(i-1) .gt. 0)) then
C Adding label check for STT
if((tra(i,labelcol).ne.1).and.(tra(i-1,labelcol).ne.2))then
if(debugflag .eq. 1) then
print*, 'STT label check failed:'
print*, 'moving to next STT candidate'
endif
cycle
else
sttcount = sttcount+1
pos(sttcount) = i-1
endif
endif
enddo
c If no STT is detected, move to next trajectory
if(sttcount .lt. 1 ) then
if(debugflag .eq. 1) then
print*, 'No STT detected: moving to next trajectory'
endif
goto 600
endif
c Re-connection with normal steps: label has been used
goto 350
C-------------------------------------------------------------------------------------------------------------------------
C END OF LABEL SECTION
c-------------------------------------------------------------------------------------------------------------------------
c Distance from the '2 PVU, 380 K' tropopause (-:trop/+:strat) : pvtrop, thtrop if PV and TH are available
300 continue !Here the code continues if no LABEL has been found
if ( (pvflag .ne. 0) .and. (thflag .ne. 0)) then
if(debugflag .eq. 1) then
print*,'Tropopause detected with PV and TH'
endif
do n=1,ntim
a=abs(pvtrop-abs(tra(n,pvcol)))/sd1 ! a = tropdist(PV)
b=abs(thtrop-tra(n,thcol))/sd2 ! b = tropdist(TH)
if ((tra(n,thcol).lt.thtrop).and.
&(abs(tra(n,pvcol)).lt.pvtrop)) then ! Troposphere (TH and PV) ---------WHY ABS??---------
tropdist(n)=-min(a,b)
else
if ( (abs(tra(n,pvcol)).ge.pvtrop).and.
&(tra(n,thcol).ge.thtrop) ) then ! Stratosphere (TH and PV)
tropdist(n)=+min(a,b)
endif
if ( (abs(tra(n,pvcol)).ge.pvtrop).and.
&(tra(n,thcol).lt.thtrop) ) then ! Stratosphere (PV)
tropdist(n)=a
endif
if ( (abs(tra(n,pvcol)).lt.pvtrop).and.
&(tra(n,thcol).ge.thtrop) ) then ! Stratosphere (TH)
tropdist(n)=b
endif
endif
enddo
endif
c If PV is not available, use only TH
if (pvflag .eq. 0) then
if(debugflag .eq. 1) then
print*,'Tropopause detected with TH only'
endif
do n=1,ntim
b=abs(thtrop-tra(n,thcol))/sd2 ! b = tropdist(TH)
if (tra(n,thcol).lt.thtrop) then ! Troposphere (TH)
tropdist(n)= -b
else
tropdist(n)= b ! Stratosphere (TH)
endif
enddo
endif
c If TH is not available, use only PV
if(debugflag .eq. 1) then
print*,'Tropopause detected with PV only'
endif
if (thflag .eq. 0) then
do n=1,ntim
a=abs(pvtrop-tra(n,pvcol))/sd2 ! a = tropdist(PV)
if (tra(n,pvcol).lt.pvtrop) then ! Troposphere (PV)
tropdist(n)= -a
else
tropdist(n)= a ! Stratosphere (PV)
endif
enddo
endif
c Detect the various STT occurrences and save positions in traj file in array pos
sttcount = 0
do i=2,ntim
if((tropdist(i)*tropdist(i-1) .lt. 0) .and.
& (tropdist(i-1) .gt. 0)) then
sttcount = sttcount+1
pos(sttcount) = i-1
endif
enddo
c If no STT are detected, go to next trajectory
if(sttcount .lt. 1 ) then
if(debugflag .eq. 1) then
print*, 'No STT detected: moving to next trajectory'
endif
goto 600
endif
350 continue !The same if LABEL is present or not.
c In timesteps, minimum residence time before and after the exchange
tb = nint( param(3)/deltat )
ta = nint( param(4)/deltat )
c Now a big while loop analyzing every candidate STT
do while(sttcount>0)
p = pos(sttcount)
c Check whether the trajectory is still in the troposphere after ta timesteps
if(ta .ne. 0) then
do n=1,ta
if((p+n) .le. ntim) then
if (tropdist(p)*tropdist(p+n).gt.0.) goto 500 !Try with new STT candidate
else
goto 500 !Out of range. Try with new STT candidate
endif
enddo
endif
c Check whether the trajectory had been in the stratosphere for at least tb timesteps
if(tb .ne. 0) then
do n=1,tb
if((p-n) .gt. 0) then
if (tropdist(p)*tropdist(p-n).lt.0.) goto 500 !Try with new STT candidate
else
goto 500 !Out of range. Try with new STT candidate
endif
enddo
endif
c If the loops have gone fine, the trajectory is considered, flag = 1, values at the exchange are written and the loop stops.
flag = 1
extime = tra(p,1)
exlon = tra(p,2)
exlat = tra(p,3)
if(zflag .eq. 1) then
exheight = tra(p,zcol)
endif
if(pflag .eq. 1) then
expres = tra(p,pcol)
endif
if(thflag .eq. 1) then
exth = tra(p,thcol)
endif
goto 600
500 continue
sttcount = sttcount-1
enddo ! End of do while loop
goto 600
600 continue
outputflag = param(5)
c Read the name of the file
namefile = trim(outfile)//'.stt'
if( (flag .eq. 1) .and. (outputflag .eq. 1) ) then
if ( nint( param(nparam+1) ).eq.0) then
open(15,file=namefile,status='replace',
&position='append', iostat=stat)
c ---------------------------------------------------------------
write(15,*) 'time lon lat height p th'
write(15,*) '--------------------------------------------'
write(15,*)
write(15,'(f7.2,1x,2f8.2,f8.0,9f10.3,5x,i1,4x)')
&extime,exlon,exlat,exheight,expres,exth
c ---------------------------------------------------------------
close(15)
param(nparam+1) = 1.
else
open(15,file=namefile,status='old',
&position='append', iostat=stat)
c ---------------------------------------------------------------
write(15,'(f7.2,1x,2f8.2,f8.0,9f10.3,5x,i1,4x)')
&extime,exlon,exlat,exheight,expres,exth
c ---------------------------------------------------------------
close(15)
endif
endif
c Write output if outputflag = 1
c outputflag = param(5)
c Check for correct inserted parameter
c if(debugflag .eq. 1) then
c if( (outputflag .ne. 0) .and. (outputflag .ne. 1) ) then
c print*, 'WARNING: last parameter must be either 0 or 1'
c print*, 'NO data file produced'
c endif
c endif
c if( (flag .eq. 1) .and. (outputflag .eq. 1) ) then
c Read the name of the file
c namefile = "data_exch_stt" !Maybe write in the command 'name'
c Open file (already opened before)
c
c inquire(file=namefile, exist=ex)
c if (ex) then
c open(15,file=namefile, status = 'old',
c &position='append',iostat=stat)
c if(stat .eq. -1) then !If the file is empty behave as it was non-existent
c goto 125
c endif
c Write output for trajectory making STT
c ---------------------------------------------------------------
c write(15,'(f7.2,1x,2f8.2,f6.0,9f10.3,5x,i1,4x)')
c &extime,exlon,exlat,exheight,expres,exth
c ---------------------------------------------------------------
c write(15,*) ! empty line
c
c
c else
c
c First time opening
c
c open(15,file=namefile,status='replace',
c &position='append', iostat=stat)
c
c Write title
c ---------------------------------------------------------------
c 125 write(15,"(A)") "time lon lat z p th"
c write(15,"(A)") "-------------------------------------------"
c ---------------------------------------------------------------
c write(15,*) ! empty line
c Write output for trajectory making STT
c ---------------------------------------------------------------
c write(15,'(f7.2,1x,2f8.2,f6.0,9f10.3,5x,i1,4x)')
c &extime,exlon,exlat,exheight,expres,exth
c ---------------------------------------------------------------
c write(15,*) ! empty line
c endif
c if (stat .ne. 0) then
c print *,"ERROR: Problem with output file",namefile
c stop
c endif
c close(15)
c endif
c "Closing" the STT criterion
endif
end