      program xspl
c  creates input files for anomaly interpolation from CRU 
c   monthly time series files
c  only years with all months missing are excluded
c  sets values gt defined sigma equal to missing
      parameter (xmiss=-9999)
      
      character*70 infl,mhfmt,mdfmt,splfmt,logfmt
      character name*36
      
      integer data(1701:2000,12),itot(1701:2000,12)
      integer lat1,lon1,lat2,lon2
      real sum(12),n(12),anom(12),xdata(12),var(12),sum2(12),sd(12)
      integer limit(4)
      
c      mhfmt='(i7,i5,i6,i5,a33,2i4)'
      mhfmt='(i7,i6,i7,i5,a36,i4,x,i4)'
      mdfmt='(i4,12i5)'
      splfmt='(3f8.2,12f8.1,12f8.4,,1x,i7,1x,a36,1x,i4)'
      logfmt='(3f8.2,12f8.1,12f8.4,x,i7,x,a36,x,i4)'
c
      open(99,file='log.dat',status='replace')
c
      write(*,*)'Enter start year, end year, start normal period,'
      write(*,*)' end normal period, nyears for normal'
      read(*,*)n1,n2,nor1,nor2,nyrs
      write(*,*)n1,n2,nor1,nor2,nyrs
      write(*,*) 'Enter min and max abs OK values (-999=no constraint)'
      read(*,*) minok,maxok
      write(*,*) 'Enter plus and minus sigma factors for extremes check'
      write(*,*) ' e.g. 5.0 -5.0'
      read(*,*) sigplus,sigminus
      write(*,*) 'Convert to percent anomalies (y=1 / no=0)?'
      read(*,*)iperc
c
      suspect=0.0
5     call openf(1,'Input time series file','old')
      write(*,*)'Enter missing value in time series data file'
      read(*,*)imiss
      write(*,*)imiss
      write(*,*)'Specify window (yes=1 /no=0)?'
      read(*,*)window
      if(window.eq.1)then
       write(*,*)'Enter latmin lonmin latmax lonmax'
       read(*,*)lat1,lon1,lat2,lon2
       lat1=lat1*100
       lat2=lat2*100
       lon1=lon1*100
       lon2=lon2*100
      else
       lat1=-9000
       lon1=-18000
       lat2=9000
       lon2=18000
      endif
      write(*,*)'Reading and writing time series file'
1     read(1,mhfmt,end=99)iwmo,lat,lon,ielv,name,iy1,iy2
      icount=icount+1
      if(500*(icount/500).eq.icount)write(*,*)icount,match,ival
      ncount=0
      do iy=iy1,iy2
        read(1,mdfmt)iyear,(data(iy,im),im=1,12)
        if(iy.ge.nor1.and.iy.le.nor2)ncount=ncount+1
      enddo
      if(lat.lt.lat1.or.lon.lt.lon1.or.lat.gt.lat2.or.lon.gt.lon2.or.
     &    ncount.lt.nyrs)goto 1
      match=match+1
      do im=1,12
       sum(im)=0
       sum2(im)=0
       n(im)=0
      enddo

      do iy=iy1,iy2
       do im=1,12
        if(iy.ge.nor1.and.iy.le.nor2.and.data(iy,im).gt.imiss)then
         sum(im)=sum(im)+real(data(iy,im))/10.0
	 sum2(im)=sum2(im)+(real(data(iy,im))/10.0)**2
         n(im)=n(im)+1
        endif
       enddo
      enddo
      do iy=iy1,iy2
       ipres=0 ; seqstatus=0.0
       do 55 im=1,12
        if(iy.eq.iy1.and.n(im).gt.0)then
	 sum(im)=sum(im)/n(im)
	 sum2(im)=sum2(im)/n(im)
	 diff=sum2(im)-sum(im)**2
	 if(diff.lt.0)diff=0.0
	 sd(im)=sqrt(diff)
        endif
        if(iy.ge.n1.and.iy.le.n2.and.data(iy,im).gt.imiss.and.
     &  	n(im).ge.nyrs)then
         valuestatus=0
         condmin=1 ; condmax=1
         if(minok.eq.-999.or.data(iy,im).ge.minok)condmin=0
         if(maxok.eq.-999.or.data(iy,im).le.maxok)condmax=0
         if(condmin.eq.0.and.condmax.eq.0)then
           anom(im)=real(data(iy,im))/10.0-sum(im)
	   var(im)=1/n(im)
           ipres=1
	   sdt=sdtest(n1,n2,iy,im,data,imiss,nyrs)
           condneg=1 ; condpos=1
           if(anom(im).lt.sigminus*sdt.and.sdt.gt.0)condneg=0
           if(anom(im).gt.sigplus*sdt.and.sdt.gt.0)condpos=0
           if(condneg.eq.0.or.condpos.eq.0)then
             if((anom(im)/sdt).gt.sigplus+1.or.anom(im)/sdt.lt.
     &			sigminus-1)then
               valuestatus=2 
               seqstatus=(seqstatus*2.0)+1.0
               if(seqstatus.gt.2)valuestatus=3
             else
               seqstatus=(seqstatus*2.0)+1.0
               if(seqstatus.gt.2)valuestatus=3
             endif             
           endif
         else
           valuestatus=3
           seqstatus=(seqstatus*2.0)+1.0
         endif
         if(seqstatus.gt.0)seqstatus=seqstatus-0.5
         if(seqstatus.lt.0)seqstatus=0.0
c
	 if(valuestatus.eq.3)then
	  write(99,'(i4,i3,i8,1x,a36)')iy,im,iwmo,name
	  iqy1=iy-10 ; if(iqy1.lt.iy1)iqy1=iy1
	  iqy2=iy+10 ; if(iqy2.gt.iy2)iqy2=iy2
	  do iqy=iqy1,iqy2
	    write(99,'(i4,12i5)')iqy,(data(iqy,iqm),iqm=1,12)
	  enddo
	  write(*,*)'Enter the first mon,yr & last mon,yr to reject:'
	  write(*,*)'  the earliest useful yr is the present=', iy
	  read(*,*)irejmon0,irejyr0,irejmon1,irejyr1
	  do irejyr=irejyr0,irejyr1
	    do irejmon=1,12
	      if(irejyr.eq.irejyr0.and.irejmon.lt.irejmon0)then
	      else if(irejyr.eq.irejyr1.and.irejmon.gt.irejmon1)then
	      else
	        data(irejyr,irejmon)=imiss
	        if(irejyr.eq.iy)then
	          anom(irejmon)=xmiss ; var(irejmon)=-9 ; ipres=0
	        endif
	      endif
	    enddo
	  enddo
	 else if(valuestatus.gt.0)then
	  suspect=suspect+1
	  anom(im)=xmiss
	  var(im)=-9    
	  ipres=0
	 endif
        else
	 anom(im)=xmiss
	 var(im)=-9    
        endif
55     enddo
       if(iperc.eq.1.and.ipres.eq.1)then
	do im=1,12
	 if(sum(im).eq.0)anom(im)=xmiss
	 if(anom(im).ne.xmiss)anom(im)=100*anom(im)/sum(im)
	 if(anom(im).gt.500)anom(im)=500
        enddo
       endif
c 			@@@@ added by TDM to avoid untraceable format errors in write to iy
       do im=1,12
         if(var(im).ne.-9)then
           if(var(im).lt.nyrs)var(im)=1.0/real(nyrs-1)
           if(var(im).gt.nyrs)var(im)=1.0/real(nyrs+1)
         endif
       enddo
c       write(99,'(i7)')iwmo
c       if(iwmo.eq.-965333)write(*,*)real(lat)/100,real(lon)/100,
c     &                   real(ielv)/1000,(anom(im),im=1,12),
c     &			 (var(im),im=1,12),iwmo,name,iy
c       if(ipres.eq.1)write(99,logfmt)real(lat)/100,real(lon)/100,
c     &                   real(ielv)/1000,(anom(im),im=1,12),
c     &			 (var(im),im=1,12),iwmo,name,iy
       if(ipres.eq.1)write(iy,splfmt)real(lat)/100,real(lon)/100,
     &                   real(ielv)/1000,(anom(im),im=1,12),
     &                   (var(im),im=1,12),iwmo,name,iy
c       if(ipres.eq.1)write(99,'(a7)')'written'
      enddo
      write(98,'(i7,a36,12f5.1)')iwmo,name,(sd(im),im=1,12)
      goto 1
99    close(1)
      write(*,*) 'Extract from another time series file (y=1 / n=0)?'
      read(*,*) repeat
      if(repeat.eq.1)goto 5
      if(suspect.gt.0)then
       write(*,*)suspects,' suspect values were found'
       write(*,*)'      see fort.99'
      endif
c
      close(99)
c
      end
      
      subroutine openf(iunit,prompt,oldnew)

      character*(*) prompt,oldnew
      character fname*80,yes*1
      logical fexist
      
1     write(*,*)prompt
      write(*,*)'or enter ''XX'' to quit'
      read(*,'(a80)')fname
      if(fname(1:2).eq.'XX')stop
      write(*,*)fname
      write(*,*)
      do i=1,75
       if(fname(i:i+5).eq.'     ')goto 5
      enddo
5     continue
      inquire(file=fname,exist=fexist)
      if(oldnew.eq.'new')then 
       if(fexist)then 
        write(*,*)'File already exists - open it anyway (y/n)'
        read(*,'(a1)')yes
        write(*,*)
        if(yes.eq.'y')then
	 open(iunit,file=fname,status='old')
        else
         goto 1
        endif
       else
        open(iunit,file=fname,status='new')
       endif
      endif
      if(oldnew.eq.'old')then 
       if(.not.fexist)then 
        write(*,*)'File does not exist - open it anyway (y/n)'
        read(*,'(a1)')yes
        write(*,*)
        if(yes.eq.'y')then
	 open(iunit,file=fname,status='new')
        else
         goto 1
        endif
       else
        open(iunit,file=fname,status='old')
       endif
      endif
      if(oldnew.eq.'unknown')open(iunit,file=fname,status='unknown')
      end

      function sdtest(n1,n2,iy,im,data,imiss,nyrs)
      integer data(1701:2000,12)
      sum=0.0
      sum2=0.0
      n=0
      do jy=n1,n2
       if(jy.ne.iy.and.data(jy,im).ne.imiss)then
	sum=sum+0.1*real(data(jy,im))
	sum2=sum2+(0.1*real(data(jy,im)))**2
	n=n+1
       endif
      enddo
      if(n.gt.nyrs)then
       sum=sum/n
       sum2=sum2/n
       diff=sum2-sum**2
       if(diff.lt.0)diff=0.0
       sdtest=sqrt(diff)
      else
       sdtest=imiss
      endif
      return
      end
