c last modified 2008-05-06 c add TMAXmean and TMINmean output in qc function c in TN10p subroutine, add an 1e-5 term on all c thresholds, to eliminate computational error. ( 3.5 may store like c 3.5000001 or 3.49999999 in thresholds ) c changed TN10p subroutine, set missing value for monthly output the c same level as R, eg. >10 days missing in a month, then set this month c missing. c last modified 2008-06-15 c changed percentile funcion to calculate multi-level percentiles in a single c routine, also changed threshold. MODULE COMM IMPLICIT NONE SAVE character(20) :: STNID integer(4) :: STDSPAN, BASESYEAR, BASEEYEAR, PRCPNN, & SYEAR, EYEAR, TOT, YRS, BYRS, WINSIZE, SS c parameter(MAXYEAR=500) real :: LATITUDE, PRCP(500*365), TMAX(500*365), & TMIN(500*365), MISSING integer(4) :: YMD(500*365,3), MNASTAT(500,12,3),YNASTAT(500,3), & MON(12),MONLEAP(12) data MON/31,28,31,30,31,30,31,31,30,31,30,31/ data MONLEAP/31,29,31,30,31,30,31,31,30,31,30,31/ data WINSIZE/5/ END MODULE COMM C Main program start use COMM character(80) :: ifile character(80) :: header integer(4) :: stnnum MISSING=-99.9 SS=int(WINSIZE/2) stnnum=1 open (1, file="para.txt") open (2, file="infilename.txt") read (1, '(a80)') header 77 read (1, '(a20,f10.2,3i6,i10)',end=100) STNID, LATITUDE, & STDSPAN, BASESYEAR, BASEEYEAR, PRCPNN c print*,'##3##',STDSPAN,BASESYEAR,BASEEYEAR,PRCPNN read (2, '(a80)', end=100) ifile if(trim(ifile).eq." ") then print*, "Read in data filename ERROR happen in:" print*, "infilename.txt, line:", stnnum stop endif open (6, file=trim(ifile)//"_log") BYRS=BASEEYEAR-BASESYEAR+1 call qc(ifile) call FD(ifile) ! FD, SU, ID, TR call GSL(ifile) ! GSL call TXX(ifile) ! TXx, TXn, TNx, TNn, DTR call Rnnmm(ifile) ! R10mm, R20mm, Rnnmm, SDII call RX5day(ifile)! Rx1day, Rx5day call CDD(ifile) ! CDD, CWD call R95p(ifile) ! R95p, R99p, PRCPTOT call TX10p(ifile) ! TX10p, TN10p, TX90p, TN90p stnnum=stnnum+1 goto 77 100 close(2) close(1) stnnum=stnnum-1 write(6,*) "Total ",stnnum,"stations be calculated" end integer function leapyear(iyear) integer iyear if(mod(iyear,400).eq.0) then leapyear=1 else if(mod(iyear,100).eq.0) then leapyear=0 else if(mod(iyear,4).eq.0) then leapyear=1 else leapyear=0 endif endif endif end subroutine percentile(x, length, nl, per, oout) use COMM integer length,nl real x(length), per(nl) real xtos(length),bb,cc,oout(nl) integer nn logical ismiss,nomiss do i=1,nl if(per(i).gt.1.or.per(i).lt.0) then print*,nl,i,per(i) print *, "Function percentile return error: parameter perc" stop endif enddo nn=0 do i=1, length if(nomiss(x(i)))then nn=nn+1 xtos(nn)=x(i) endif enddo if(nn.eq.0) then oout=MISSING else call sort(nn,xtos) do i=1,nl bb=nn*per(i)+per(i)/3.+1/3. cc=real(int(bb)) if(int(cc).ge.nn) then oout(i)=xtos(nn) else oout(i)=xtos(int(cc))+(bb-cc)* & (xtos(int(cc)+1)-xtos(int(cc))) endif enddo endif end c---Sorts an array arr(1:n) into ascending numerical order using the Quicksort c algorithm. n is inpu; arr is replace on output by its sorted rearrangement. c Parameters: M is the size of subarrays sorted by straight insertion c and NSTACK is the required auxiliary. SUBROUTINE sort(n,arr) INTEGER n,M,NSTACK REAL arr(n) PARAMETER (M=7,NSTACK=50) INTEGER i,ir,j,jstack,k,l,istack(NSTACK) REAL a,temp jstack=0 l=1 ir=n 1 if(ir-l.lt.M)then do 12 j=l+1,ir a=arr(j) do 11 i=j-1,1,-1 if(arr(i).le.a)goto 2 arr(i+1)=arr(i) 11 continue i=0 2 arr(i+1)=a 12 continue if(jstack.eq.0)return ir=istack(jstack) l=istack(jstack-1) jstack=jstack-2 else k=(l+ir)/2 temp=arr(k) arr(k)=arr(l+1) arr(l+1)=temp if(arr(l+1).gt.arr(ir))then temp=arr(l+1) arr(l+1)=arr(ir) arr(ir)=temp endif if(arr(l).gt.arr(ir))then temp=arr(l) arr(l)=arr(ir) arr(ir)=temp endif if(arr(l+1).gt.arr(l))then temp=arr(l+1) arr(l+1)=arr(l) arr(l)=temp endif i=l+1 j=ir a=arr(l) 3 continue i=i+1 if(arr(i).lt.a)goto 3 4 continue j=j-1 if(arr(j).gt.a)goto 4 if(j.lt.i)goto 5 temp=arr(i) arr(i)=arr(j) arr(j)=temp goto 3 5 arr(l)=arr(j) arr(j)=a jstack=jstack+2 if(jstack.gt.NSTACK)pause 'NSTACK too small in sort' if(ir-i+1.ge.j-l)then istack(jstack)=ir istack(jstack-1)=i ir=j-1 else istack(jstack)=j-1 istack(jstack-1)=l l=i endif endif goto 1 END C (C) Copr. 1986-92 Numerical Recipes Software ,. subroutine qc(ifile) use COMM character*80 ifile character*80 omissf, title(3), otmpfile integer ios, rno, tmpymd(365*500,3), i, ith real tmpdata(365*500,3),stddata(365,500,3),stdval(365,3),m1(365,3) integer kth,month,k,trno,ymiss(3),mmiss(3),stdcnt(3), & missout(500,13,3),tmpcnt logical ismiss,nomiss data title/"PRCPMISS","TMAXMISS","TMINMISS"/ omissf=trim(ifile)//"_NASTAT" C print*, BASESYEAR, BASEEYEAR open(10, file=ifile, STATUS="OLD", IOSTAT=ios) c print *, ifile, ios if(ios.ne.0) then write(6,*) "ERROR during opening file: ", trim(ifile) write(6,*) "Program STOP!!" stop endif otmpfile=trim(ifile)//"_prcpQC" open(81, file=otmpfile) write(81,*) "PRCP Quality Control Log File:" otmpfile=trim(ifile)//"_tempQC" open(82, file=otmpfile) write(82,*) "TMAX and TMIN Quality Control Log File:" rno=1 88 read(10,*,end=110) (tmpymd(rno,j),j=1,3), & (tmpdata(rno,j),j=1,3) rno=rno+1 goto 88 110 rno=rno-1 close(10) SYEAR=tmpymd(1,1) EYEAR=tmpymd(rno,1) YRS=EYEAR-SYEAR+1 TOT=0 do i=SYEAR,EYEAR do month=1,12 if(leapyear(i)==1) then kth=MONLEAP(month) else kth=MON(month) endif do k=1,kth TOT=TOT+1 YMD(tot,1)=i YMD(tot,2)=month YMD(tot,3)=k enddo enddo enddo j=1 do i=1, TOT 111 if(YMD(i,1)*10000+YMD(i,2)*100+YMD(i,3).eq. & tmpymd(j,1)*10000+tmpymd(j,2)*100+tmpymd(j,3)) then PRCP(i)=tmpdata(j,1) TMAX(i)=tmpdata(j,2) TMIN(i)=tmpdata(j,3) j=j+1 elseif(YMD(i,1)*10000+YMD(i,2)*100+YMD(i,3).lt. & tmpymd(j,1)*10000+tmpymd(j,2)*100+tmpymd(j,3)) then PRCP(i)=MISSING TMAX(i)=MISSING TMIN(i)=MISSING elseif(YMD(i,1)*10000+YMD(i,2)*100+YMD(i,3).gt. & tmpymd(rno,1)*10000+tmpymd(rno,2)*100+tmpymd(rno,3)) then PRCP(i)=MISSING TMAX(i)=MISSING TMIN(i)=MISSING else j=j+1 goto 111 endif enddo trno=0 MNASTAT=0 YNASTAT=0 do i=SYEAR,EYEAR ymiss=0 stdcnt=0 do month=1,12 mmiss=0 if(leapyear(i)==1) then kth=MONLEAP(month) else kth=MON(month) endif do k=1,kth trno=trno+1 if(TMAX(trno).le.MISSING) TMAX(trno)=MISSING if(TMIN(trno).le.MISSING) TMIN(trno)=MISSING if(PRCP(trno).le.MISSING) PRCP(trno)=MISSING if(TMAX(trno).lt.TMIN(trno).and.nomiss(TMAX(trno)) & .and.nomiss(TMIN(trno))) then TMAX(trno)=MISSING TMIN(trno)=MISSING write(82, *) i*10000+month*100+k, "TMAX