c
      program mtmcohere
c
c     (c) Michael Mann
c
c     MTM code of J. Park adapted to perform significance of spectral
c     peaks relative to "robust red noise" background as described
c     by Mann and Lees (1996) and to calculate MTM spectral coherence
c     of two series with jacknife uncertainties and automatic determination
c     of confidence levels.
c
      integer maxwin,maxdof,nlim,nmed
      parameter (maxwin=8,maxdof=2*maxwin,nlim=32768)
      parameter (nmed=2000)
      parameter (big=1.0e+36,small=1.0e-12,tol=1e-4)
      real rho,rho0
      real FUNC
      real*8 avar,el
      real val(nmed)
      real tm
      real rmean(nlim),specmed(nlim)
      real harmonic(nlim),background(nlim),psd(nlim)
      real rednoise(nlim),rednoise0(nlim)
      real dat(nlim,2)
      real base(nlim)
      real amp(nlim),phase(nlim),amphigh(nlim),amplow(nlim)
      real coh(maxwin)
      real takeep(nlim/2,maxwin,2),taikeep(nlim/2,maxwin,2)
      integer iharm(nlim)
      real ftest(6),fcoh(6),fcoh0(6),fconf(6)
      real adum
      character*1 k0,k1,k2,k3,k4,chan*8,ista*4
      character*80 ifmt,name,title
      complex zed
      common/npiprol/anpi
      common/data/a(50000)
      common/work/b(32800)
      common/work2/fspec(16400)
      COMMON /BLK1/white,specmed,fny,ddf,f0
      COMMON /BLK2/ilog,nfreq
c     program is limited to 8 windows
c     program is limited to 16400 frequency-ftest estimation pairs
c     #pts in padded series must be < 32768 '
      common/pltopt/key,k1,k2,k3,k4,nbin,npad,nst,npts,nmin,nmax,t(3),
     $     fmin,fmax,nf
      common/taperz/ta(16400,8),tai(16400,8),dcf(16400,8),amu(16400,8)
      common/staple/tad(32800),tad1(32800)
      common/stap2/tas(32800,16)
      common/idiot/qcyc,rfrq,ftfrq,fr(3),k0
      common/udhedz/iy,id,ih,im,iss,ktime(5),dt,ista,chan,nscan,commen
      dimension dum(35)
      dimension reim(2),el(10)
      equivalence (zed,reim),(iy,dum)
      pi=3.14159265358979
      radian=180./pi
      tiny = 1e-6
      iflag=1
c
6666  write (6,*) 'options: (quit=0)'
      write (6,*) '(1) MTM spectrum of a time series'
      write (6,*) '(2) MTM time-domain signal reconstruction'
      write (6,*) '(3) MTM spectral coherence of two time series'
      read (5,*) ioption
      ioption = ioption-1
      if (ioption.eq.1) then
         write (6,*) 'sorry--that section is still in progress'
         write (6,*) 'check back soon for updated version!'
         goto 6666
      else
       if (ioption.lt.0) goto 8888
      endif
c
c
c     read in data file/s
c
c     first 3 lines contain
c        1. title
c        2. #samples, sample interval
c        3. fortran format statement
c
101   format(80a)
c
      if (ioption.lt.2) then
c
        nrep = 1
        write (6,*) 'input file name : '
        read (5,101) name
        open(7,file=name,form='formatted')
        rewind(7)
        read(7,101) title
        read(7,*) nscan,dt
        read(7,101) ifmt
        read(7,ifmt)(dat(i,nrep),i=1,nscan)
        close(7)
        open (unit=44,file='data.out',status='unknown')
        do i=1,nscan
           write (44,*) i,dat(i,1)
        end do
        close (unit=44)
c
      else
        nrep = 2
        do irep = 1,nrep
          write (6,*) 'input file name for series #',
     $      irep,':'
          read (5,101) name
          open(7,file=name,form='formatted')
          rewind(7)
          read(7,101) title
          read(7,*) nscan1,dt1
          read(7,101) ifmt
          read(7,ifmt) (dat(i,irep),i=1,nscan1)
          close(7)
          if (irep.eq.1) then
             nscan=nscan1
             dt = dt1
          else
             if (abs(dt1-dt).gt.tol) then
                write (6,*) 'sampling rates not equal'
                write (6,*) 'cannot compute coherences...'
                goto 6666
             else
              if (nscan1.ne.nscan) then
                write (6,*) 'lengths not equal'
                write (6,*) 'series1: ',nscan,' samples'
                write (6,*) 'series2: ',nscan1,' samples'
                write (6,*) 'taking shorter of the two:'
                nscan = min(nscan,nscan1)
                write (6,*) 'using first ',nscan,' data points...'
              endif
             endif
          endif
        end do
      endif
c
      write (6,*) 'read in: '
      write (6,*) nrep,' time series of length ',nscan
      write (6,*) float(int(100*nscan*dt+0.5))/100.0, ' years long...'
      write (6,*) 'sampling rate ',dt
c
c
c     determine MTM parameters
c
c     default settings
c
      npi = 2
      anpi=float(npi)
      nwin=3
      imode = 0
      nmode = 1
      iseg = 0
      iformat = 0
      iref = 1
      jsmoo = 0
      iaverage = 0
      irecon = 0
      imoderecon = 0
      ioutput = 0
      itype = 0
      nbeg=1
      nend = nscan
      n1 = nbeg
      n2 = nend
      npts = n2-n1+1
      neval = nscan
      nmove = nscan
      ninterv = nmove
      fsmooth = 0.0
      nsmooth = 0
      inoise = 1
      ismooth = 1
      ilog = 1
      tm0 = 0.0
c
444   write (6,*) 'present settings'
      write (6,*) '1) use',nwin, ' x ',npi,' pi tapers'
      write (6,*) '2) data interval (',nbeg,' to ',nend,' )'
      if (itype.eq.0) then
        write (6,*) '3) fixed window analysis'
      else
         write (6,*) '3) evolutive analysis'
         write (6,*) '    --',nmove,' time unit moving window'
         write (6,*) '    --',ninterv,' time unit step'
      endif
      if (ioption.gt.1) goto 555
c
      if (inoise.eq.0) then
         write (6,*) '4) white noise assumption'
      else
        if (inoise.eq.1) then
           write (6,*) '4) red noise assumption'
        else
           if (inoise.eq.2) then
              write (6,*) '4) median-estimated "local white" noise'
           endif
        endif
      endif
555   write (6,*) 'item to change (0=continue)'
      read (5,*) icont
      if (icont.eq.1) then
       goto 1111
      else
       if (icont.eq.2) then
         goto 2222
       else
         if (icont.eq.3) then
          goto 3333
         else
            if (icont.eq.4) then
               goto 4444
            else
              goto 9999
            endif
         endif
       endif
      endif
c
c     anpi = desired time/frequency bandwith "p" (ie, "p pi tapers")
c     nwin = number of tapers used (maximum is 2p-1)
c
1111  write (6,*) 'time-frequency bandwidth product "p"'
      read (5,*) npinew
      if (npinew.gt.maxwin) then
         write (6,*) 'sorry--exceeds maximum bandwidth'
      else
         write (6,*) 'number of tapers'
         read (5,*) nwinnew
         if (nwinnew.gt.2*npinew-1) then
           write (6,*) 'sorry--cannot exceed 2*p-1'
         else
           npi = npinew
           anpi = float(npi)
           nwin=nwinnew
         endif
      endif
      goto 444
c
2222  write (6,*) 'beginning time index'
      read (5,*) nbeg
      write (6,*) 'ending time index'
      read (5,*) nend
      nmove = nend-nbeg+1
      neval = nend-nbeg+1
      n1 = nbeg
      n2 = nend
      goto 444
c
3333  write (6,*) 'choose'
      write (6,*) '(0) fixed window'
      write (6,*) '(1) evolutive analysis'
      read (5,*) itype
      if (itype.eq.1) then
         write (6,*) 'window width (in time units)'
         read (5,*) nmove
         write (6,*) 'interval between evaluations (in time units)'
         read (5,*) ninterv
         write (6,*) 'initial time (year,month, etc)'
         read (5,*) tm0
      endif
      goto 444
c
c
4444  write (6,*) 'choose'
      write (6,*) '(0) white noise background assumption'
      write (6,*) '(1) red noise background assumption'
      write (6,*) '(2) median estimated "local white" assumption'
      read (5,*) inoise
      if (inoise.eq.0) then
         rho = 0.0
         rho0 = rho
      else
        fsmooth = 0.0
        nsmooth = 0
c
        demn = 0.0
        do i=n1,n2
         demn=demn+a(i)
        end do
        demn = demn/float(npts)
c
c       determine raw AR(1) coefficient 
c
        var = 0.0
        do i=n1,n2
         a(i)=dat(i,1)
         rmean(i)=a(i)-demn 
         var = var + rmean(i)**2
        end do
        var = var/float(npts)
        sd = sqrt(var)
        write (6,*) 'series mean: ',demn
        write (6,*) 'series standard deviation: ',sd
        c1 = 0.0
        icount = 0
        do i=2,n2
         icount = icount + 1
         c1 = c1 + rmean(i-1)*rmean(i)
        end do
        c1 = c1/float(icount)
        rho = c1/var
        write (6,*) 'rho (raw series): ',rho
        rho0 = rho
        if (inoise.eq.1) then
         write (6,*) 'robust noise background option'
         write (6,*) '(0) no'
         write (6,*) '(1) yes'
         read (5,*) ismooth
        else
          ismooth = 1
        endif
      endif
      goto 444
c
c
c
9999  npts = nmove
c
c     determine chi-square values for confidence level
c     determination of spectrum
c
      open (unit=21,file='/big2/MTM-COHERE/chisquare.dat',
     $ status='old')
         do i=2,maxdof
            idofs = 2*nwin
            if (i.eq.idofs) then
               read (21,*) idum,conf50,conf90,conf95,conf99
            else
               read (21,*) 
            endif
         end do
      close (unit=21)
c
      ick1 = 0
      ick2 = 1
      ick3 = 1
      jper = 3
      bfact = conf95
      fconf(1)=50.0
      fconf(2)=90.0
      fconf(3)=95.0
      fconf(4)=99.0
      fconf(5)=99.5
      fconf(6)=99.9
      if (nwin.eq.1) ick3 = 0
c
c     read in f-test data
c
      if (ick3.eq.1) then
       iper = 3
       open (unit=17,file='/big2/MTM-COHERE/ftest.dat',
     $    status='unknown')
       do i=2,14,2
         if (i.eq.2*nwin-2) then
            read (17,*) idum,ftest(1),ftest(2),ftest(3),ftest(4),
     $            ftest(5),ftest(6)
         else
            read (17,*)
         endif
       end do
       close (unit=17)
      endif
      thresh = ftest(iper)   
c
      if (ioption.eq.2) then
       do i=1,6
          fcoh(i)=0.0
          fcoh0(i)=0.0
       end do
       if (nwin.eq.1) then
          write (6,*) 'warning: '
          write (6,*) 'confidence intervals are indeterminate'
          write (6,*) 'for the case K=1...'
       endif
c
c      read in coherence signficance levels for non-secular
c
       open (unit=17,file='/big2/MTM-COHERE/fcoher.dat',
     $ status='unknown')
       do i=2,14,2
         if (i.eq.2*nwin-2) then
            read (17,*) idum,fcoh(1),fcoh(2),fcoh(3),fcoh(4),
     $            fcoh(5),fcoh(6)
         else
            read (17,*)
         endif
       end do
       close (unit=17)
c
c      read in coherence signficance levels for secular band
c
c      note we are comparing 1 and nwin-2 dof since dft
c      is real at zero frequency, and the mean counts as
c      one dof (which we have removed)
c
       open (unit=17,file='/big2/MTM-COHERE/fcoher-sec.dat',
     $    status='unknown')
       do i=0,6
         if (i.eq.nwin-2) then
            read (17,*) idum,fcoh0(1),fcoh0(2),fcoh0(3),fcoh0(4),
     $            fcoh0(5),fcoh0(6)
         else
            read (17,*)
         endif
       end do
       close (unit=17)
       bfact = fcoh(jper)
       bfact0 = fcoh0(jper)
c
      endif
c
      if(iflag.eq.0) go to 60
      key=0
      k2='n'
      k1='y'
      nbin=2
      inorm = 0
      k4='y'
      k3='y'
      qcyc=0.
      k0='n'
c
c  find the rayleigh freq
      rfrq=1./(npts*dt)
      if(npts.gt.32768) type *,'too large - cut it down'
      npad=npts-1
      ij=0
 1001 npad=npad/2
      ij=ij+1
      if(npad.ne.0) go to 1001
      npad=2**ij
      write (6,*) ,npad
      fmin=0.
      f0 = fmin
      fmax=.5/dt
      nst=0
      hstart=nst*dt
      thrs=npts*dt
   60 ddf=1.0/(npad*dt)
      eps=.1*ddf
      nn1=(fmin+eps)/ddf
      fmin=nn1*ddf
      f0 = fmin
      nn2=((fmax+eps)/ddf) 
      fmax=nn2*ddf
      nf=nn2-nn1+1
      nfreq = nf
      write (6,*) ' number of freqs = ',nf
      nmin=nn1*2+1
      nmax=nn2*2+2
      t(1)=fmin
      t(2)=ddf
      t(3)=ddf
      ftfrq=ddf
      lwt=2
      
   50 write (6,*) ' 1) freq spacing(can be decreased by padding): ',ddf
      write (6,*) ' 2) min and max freq for analysis: ',fmin,fmax
      if (ioption.eq.2) then
           write (6,*) ' 3) filter spectral coherence at ',fconf(jper),
     $          ' significance level'
      else
      write (6,*) ' 3) spectrum type:'
      if (ick1.eq.1) then
        write (6,*) '  * high resolution MTM spectrum'
      else
        write (6,*) '  * adaptive MTM spectrum'
      endif
        write (6,*) '  * filter spectrum at ',fconf(jper),
     $        ' signficance level'
      if (ick3.eq.1) then
        write (6,*) '  * harmonic peak detection/reshaping'
        write (6,*) '  * ',fconf(iper),
     $      '% sig. level for harm. peak detection'
      else
        write (6,*) '  * no harmonic peak detection/reshaping'
      endif
      write (6,*) ' 4) units - amp spectrum per unit time '
      endif
666   write (6,*) 'which number do you want to change (0=continue) '
      read (5,*) ijk
      if(ijk.eq.0) goto 9876
c
c     set iflag if user selects 1 or 2 
c     iflag=1 causes eigentapers to be reinterpolated
c
      go to (1,2,3,4), ijk
c
    1 write (6,*) 'current padded length',npad
      write (6,*) 'pad by how many powers of two? '
      read (5,*) ij
      ip=2**(iabs(ij))
      nd=npad*ip
      if(ij.lt.0) nd=npad/ip
      if(nd.gt.32768) then
        type *,'too many - max padded length=32768'
        go to 1
      endif
      npad=nd
      write (6,*) ' padded fft length = ',npad
      go to 60
c
    4 write (6,*) '(0) no normalization'
      write (6,*) '(1) normalization = dft*npts'
      write (6,*) '(2) normalization = dft/dt'
      read (5,*) inorm
      go to 50
c
    2 write (6,*) 'freq units are in cycles per time unit'
      write (6,*) 'enter fmin and fmax '
      read (5,*) fmin,fmax
      go to 60
c
    3 if (ioption.eq.2) then
c
        write (6,*) 'significance level (%) for filtering'
        write (6,*) '(0) 50%'
        write (6,*) '(1) 90%'
        write (6,*) '(2) 95%'
        write (6,*) '(3) 99%'
        write (6,*) '(4) 99.5%'
        write (6,*) '(5) 99.9%'
        read (5,*) jper
        jper = jper+1
        bfact = fcoh(jper)
        bfact0 = fcoh0(jper)
c
      else
c
      write (6,*) 'choose:'
      write (6,*) '(0) high-resolution MTM spectrum'
      write (6,*) '(1) adaptive MTM spectrum'
      read (5,*) ick2
      if ((ick2.gt.1).or.(ick2.lt.0)) then
         write (6,*) 'illegal entry'
         goto 4
      endif
      ick1 =  1-ick2
        write (6,*) 'significance level (%) for filtering'
        write (6,*) '(0) 50%'
        write (6,*) '(1) 90%'
        write (6,*) '(2) 95%'
        write (6,*) '(3) 99%'
        write (6,*) '(4) 99.5%'
        write (6,*) '(5) 99.9%'
        read (5,*) jper
        jper = jper+1
        bfact = conf50
        if (jper.eq.2) bfact = conf90
        if (jper.eq.3) bfact = conf95
        if (jper.gt.3) bfact = conf99
      write (6,*) 'F-test for harmonic lines (0=no,1=yes)'
      read (5,*) ick3
      if (ick3.eq.1) then
       if (nwin.eq.1) then
           write (6,*) 'sorry--F test is indeterminate for K=1'
           goto 60
       else
        write (6,*) 'significance level (%) for harmonic peak detection'
        write (6,*) '(0) 50%'
        write (6,*) '(1) 90%'
        write (6,*) '(2) 95%'
        write (6,*) '(3) 99%'
        write (6,*) '(4) 99.5%'
        write (6,*) '(5) 99.9%'
        read (5,*) iper
        iper = iper+1
        thresh = ftest(iper)
       endif
      endif
c
      endif
      goto 50
c
c     we're happy with the settings. Continue...
c
9876  ddf = 1.0/(dt*npad)
      fny = 0.5/dt
      if(nf.ge.16400) then
        write (6,*) 'too many DFT points'
        go to 444
      endif
c
      afact = conf50
      if (iper.eq.2) afact = conf90
      if (iper.eq.3) afact = conf95
      if (iper.gt.3) afact = conf99
c
      bndwdth = 2.0*anpi*rfrq  
      halfwdth = bndwdth/2.0
      nbnd = bndwdth/ddf
      timefreq = 2.0*anpi
      write (6,*) 'Rayleigh frequency: ',rfrq
      write (6,*) 'time-frequency bandwidth: ',timefreq,' N'
      write (6,*) 'spectral bandwidth: ',bndwdth
      write (6,*) 'Nyquist frequency: ',fny
      fsugg = fny/5.0
      if (fsugg.lt.bndwdth) fsugg=bndwdth
      if ((inoise.gt.0).and.(ioption.eq.0)) then
828      write (6,*) 'smoothing width (cycles/yr):'
         write (6,*) 'suggested value = ',fsugg
         read (5,*) fsmooth
         if ((fsmooth.gt.fny).or.(fsmooth.lt.bndwdth)) then
          write (6,*) 'spectral bdwdth < width < Nyquist freq!'
           write (6,*) 'your frequency width is out of bounds'
           goto 828
         endif
         nsmooth = fsmooth/ddf
         if (inoise.eq.1) then
          write (6,*)
          write (6,*) 'fit red noise to smoothed'
          write (6,*) '(0) spectrum'
          write (6,*) '(1) log spectrum'
          read (5,*) ilog
         endif
      endif
c
c  if we have not changed anything, we need not recalculate the windowed
c  spectra (e.g. if we wish to re-interpolate spectra)
c  get slepian windows - unless we can skip this step
c
      if(iflag.eq.1) then
        call taper2(npts,nwin,el)
      endif
c
c     refresh iflag
c
      iflag=0
c
c
c    normalization: mult by dt if we wish absolute spectral estimate
c    e.g. analysis of time-limited signal
c    divide by npts if we wish amplitude spectrum per unit time
c    or divide by sqrt(npts)  if we are adhering to conventions of 
c    inverse theory paper (since tapers self-dotted = n)
c
      if(inorm.eq.2) then  !  amp spec (time limited)
        anrm=1/dt
      elseif(inorm.eq.1) then  ! amp spect per unit time
        anrm=float(npts)
      else
        anrm=1.
      endif
c
c
c     begin the analysis....
c
c     create output files
c
      open (unit=31,file='coher-amp.out',status='unknown')
      open (unit=32,file='coher-phase.out',status='unknown')
      open (unit=33,file='coher-sig.out',status='unknown')
      open (unit=21,file='spec-harm.out',status='unknown')
      open (unit=22,file='spec-robst.out',status='unknown')
      open (unit=23,file='spec-raw.out',status='unknown')
      open (unit=24,file='spec-med.out',status='unknown')
c
      open (unit=29,file='spec-inf-evol.out',status='unknown')
c
c     loop in time (if non-evolutive, reduces to a single window)
c
      write (6,*) 'nmove ',nmove
      write (6,*) 'ninterv ',ninterv
      niter = (neval-nmove)/ninterv + 1
      write (6,*) 'beginining 1st of ',niter, ' iteration/s...'
      amax = -99999
c
c     begin moving time window loop
c
      do it = 1,niter
c
c
      n1 = 1+(it-1)*ninterv
      n2 = n1+npts-1
      ncent = (n1+n2-1)/2
      tm = ncent*dt
c
      write (6,*) 'interval: ',n1,' to ',n2,' time: ',tm
c
c     demean series in local window -- loop over two series
c     if spectral coherence option
c
      do k=1,nrep
c
      demn=0.
      do i=n1,n2
         a(i)=dat(i,k)
         demn=demn+a(i)
      end do
      demn=demn/(npts)
c
      do iwin=1,nwin
        do i=n1,n2
          b(i-n1+1)=(a(i)-demn)*tas(i+1-n1,iwin) 
        end do
        j=npts+1
        do i=j,npad
          b(i)=0.
        end do
        call realft(b,npad/2,1)
        b(npad-1)=b(2)
        b(npad)=0.
        b(2)=0.
        sum=0.
        j=0
        do i=nmin,nmax,2
          j=j+1
          ta(j,iwin)=b(i)/anrm
          tai(j,iwin)=b(i+1)/anrm
          takeep(j,iwin,k)=ta(j,iwin)
          taikeep(j,iwin,k)=tai(j,iwin)
          sumi=(b(i)*b(i)+b(i+1)*b(i+1))
          sum=sum+sumi
        end do
        avamp=sqrt(sum/nf)/anrm
      end do
c
c
      end do
      if (ioption.eq.2) then
c
c     calculate the spectral coherence and jacknife uncertainties
c
       do i=1,nf-1
        abr=0.
        abi=0.
        aa=0.
        bb=0.
        cmean = 0.
        do k=1,nwin
          coh(k)=0.
          aa=aa+takeep(i,k,1)*takeep(i,k,1)
     $      +taikeep(i,k,1)*taikeep(i,k,1)
          bb=bb+takeep(i,k,2)*takeep(i,k,2)
     $      +taikeep(i,k,2)*taikeep(i,k,2)
          abr=abr+takeep(i,k,1)*takeep(i,k,2)
     $      +taikeep(i,k,1)*taikeep(i,k,2)
          abi=abi+takeep(i,k,1)*taikeep(i,k,2)
     $      -taikeep(i,k,1)*takeep(i,k,2)
          abr2=0.
          abi2=0.
          aa2=0.
          bb2=0.
          do j=1,nwin
             if (j.ne.k) then
               aa2=aa2+takeep(i,j,1)*takeep(i,j,1)
     $           +taikeep(i,j,1)*taikeep(i,j,1)
               bb2=bb2+takeep(i,j,2)*takeep(i,j,2)
     $           +taikeep(i,j,2)*taikeep(i,j,2)
               abr2=abr2+takeep(i,j,1)*takeep(i,j,2)
     $           +taikeep(i,j,1)*taikeep(i,j,2)
               abi2=abi2+takeep(i,j,1)*taikeep(i,j,2)
     $           -taikeep(i,j,1)*takeep(i,j,2)
             endif
          enddo
          coh(k)=(abr2*abr2+abi2*abi2)/(aa2*bb2)
          cmean = cmean + coh(k)
        end do
        cmean = cmean/float(nwin)
        var = 0.
        do k=1,nwin
         var = var + (coh(k)-cmean)**2
        end do
        unc = sqrt(var/float(nwin))
        amp(i)=(abr*abr+abi*abi)/(aa*bb)
        phase(i)=180.*atan2(abi,abr)/pi
        amphigh(i)=amp(i)+unc
        amplow(i)=amp(i)-unc
        ff = (i-1)*ddf+fmin
        if (itype.eq.0) then
           write (31,854) ff,amp(i),amplow(i),amphigh(i)
           write (32,855) ff,phase(i)
           if (ff.ge.halfwdth) then
            write (33,856) ff,amp(i),fcoh(1),fcoh(2),fcoh(3),fcoh(4)
           else
            write (33,856) ff,amp(i),fcoh0(1),fcoh0(2),fcoh0(3),
     $                        fcoh0(4)
           endif
        else
           write (31,954) tm,ff,amp(i)
           write (32,955) tm,ff,phase(i)
           if (ff.ge.halfwdth) then
             if (amp(i).gt.bfact) then
              write (33,955) tm,ff,amp(i),phase(i)
             else
              write (33,955) tm,ff,0.0,-200.0
             endif
           else
             if (amp(i).gt.bfact0) then
              write (33,955) tm,ff,amp(i),phase(i)
             else
              write (33,955) tm,ff,0.0,-200.0
             endif
           endif
        endif
       end do
       goto 777
      endif
c
c     high-resolution mtm spectrum
c
      if(ick1.eq.1) then
        call hires(ta,tai,el,nwin,nf-1,amu)
c
c       normalized psd, disallow small negative values
c
        do i=1,nf-1
          amu(i,1)=abs(amu(i,1))**2
        end do
      endif
c
c     adaptively weighted mtm spectrum 
c
      if(ick2.eq.1) then
        avar=0.d0
        do i=n1,n2
          avar=avar+(a(i)-demn)*(a(i)-demn)
        end do
c
c       avar is a factor that scales the bias factor 
c       in adaptive weighting
c       scheme. it will depend on the transform normalization thusly:
c
        if (inorm.eq.1) then ! amp spect per unit time
          avar=avar/(npts*npts)
        elseif(inorm.eq.2) then  ! absolute amp spect
          avar=avar*dt*dt
        endif
        call adwait(ta,tai,dcf,el,nwin,nf-1,amu,amu(1,2),avar)
c
c       normalized psd, disallow small negative values
c
        do i=1,nf-1
          amu(i,1)=abs(amu(i,1))
        end do
      endif
c
c
      do i=1,nf-1
         psd(i)=amu(i,1)
      end do
c
      if (it.eq.1) then
c
c     determine white noise level
c     and  determine median smoothed spectrum
c      (if moving window, based on first window)
c
      white0 = 0.0
      do i=1,nf-1
         white0 = white0+psd(i)
      end do
      white0 = white0/float(nf-1)
      rho = rho0
      white = white0
      endif
c
c
c     estimate spectrum amplitude
c
      do i=1,nf-1
         psd(i)=psd(i)+white0*small
      end do
c
      if (it.eq.1) then
       do i=1,nf-1
         red = white0*(1.0-rho0**2)/
     $      (1.0-2.0*rho0*cos(arg)+rho0**2)
         if ((red.gt.amax).and.(it.eq.1)) amax = red
       end do
c
       white = 0.0
       do j=1,nf-1
         if1 = j-nsmooth/2
         if2 = j+nsmooth/2
         if (if1.lt.1) if1=1
         if (if2.gt.nf-1) if2=nf-1
         nblk = if2-if1+1
         do i=1,nblk
            val(i)=psd(if1+i-1)
         end do
c
c        sort spectrum in this block
c         
         kmid = (nblk+1)/2
         do kk1=1,nblk
            do kk2=kk1+1,nblk
               if (val(kk2).lt.val(kk1)) then
                  adum = val(kk2)
                  val(kk2)=val(kk1)
                  val(kk1)=adum
               endif
            end do
         end do
         specmed(j)=val(kmid)
         white = white + specmed(j)
       end do
       white = white/float(nf-1)
c
c      now determine best fit red noise spectrum of the form
c
c         rednoise = white*(1.0-rho**2)/
c     $      (1.0-2.0*rho*cos(arg)+rho**2)
c
c      to the median-smoother.
c
c      we take "white" as estimated above from median smoothed
c      spectrum, and do a global search of the interval [0,1)
c      to find the optimal rho as determined by minimum MSE
c
       if (ismooth.eq.1) then
        amin = big
        do rho1=0.0,0.999,0.001
         amiss = FUNC(rho1)
         if (amiss.lt.amin) then
            rho=rho1
            amin = amiss
         endif
        end do
       endif
c
c     amax is just a scaling factor to insure a standard
c     magnitude scale of the output spectrum
c
      amax = amax/100.0
c
      tau = 1e+16
      tau0 = 1e+16
      if (rho.gt.0.0) tau = -dt/log(rho)
      if (rho0.gt.0.0) tau0 = -dt/log(rho0)
      write (29,657) n1,n2,white,rho,tau
      write (6,*) n1,n2,white,rho,tau
c
      endif
c
      do i=1,nf-1
         ff = (i-1)*ddf+fmin
         freq_norm = ff/fny
         arg = freq_norm*pi
         rednoise0(i) = white0*(1.0-rho0**2)/
     $      (1.0-2.0*rho0*cos(arg)+rho0**2)
         rednoise(i) = white*(1.0-rho**2)/
     $      (1.0-2.0*rho*cos(arg)+rho**2)
         if (inoise.ne.2) then
             base(i) = rednoise(i)
         else
             base(i) = specmed(i)
         endif
c
         if (itype.eq.0) then
c
         write (22,654) ff,psd(i)/amax,base(i)/amax,
     $         base(i)*conf90/amax,
     $         base(i)*conf95/amax,base(i)*conf99/amax
         write (23,654) ff,psd(i)/amax,rednoise0(i)/amax,
     $         rednoise0(i)*conf90/amax,
     $         rednoise0(i)*conf95/amax,
     $         rednoise0(i)*conf99/amax
         write (24,655) ff,psd(i)/amax,specmed(i)/amax
c
         else
c
         if (psd(i).gt.bfact*base(i)) then
           write (22,754) tm+tm0,ff,log(psd(i)/amax)
         else
           write (22,754) tm+tm0,ff,0.0
         endif
         write (23,754) tm+tm0,ff,log(psd(i)/amax)
c
         endif
      end do
c
      if (ick3.eq.1) then
c
        call regre(ta,tai,nf-1,nwin,amu)
c
c       do a poor mans reshaping -detect harmonic peaks and then
c       interpolate the continuous spectrum across the effected
c       bandwidth  -only reshape if harmonic peak is greater than
c       the significance level in terms of overall power that was
c       indicated for the F-test harmonic detection procedure
c
c
        do i=1,nf-1
           background(i)=psd(i)
           harmonic(i)=background(i)
           iharm(i)=0
           if ((amu(i,3).gt.thresh).
     $         and.(psd(i).gt.afact*base(i))) iharm(i)=1
        end do
        do i=1,nf-1
           if (iharm(i).eq.1) then
c
c           determine frequency points at boarder of the bandwidth
c
            ipre = i-nbnd/2-1
            iaft = i+nbnd/2+1
            if (ipre.lt.1) ipre=1
            if (iaft.gt.nf-1) iaft=nf-1 
c
            ave = 0.0
            do j=ipre+1,iaft-1
              background(j)=0.5*(psd(ipre)+psd(iaft))
              harmonic(j)=psd(i)
            end do
           endif
        end do
        do i=1,nf-1
           ff = float(i-1)*ddf+fmin
           if (itype.eq.0) then
           write (21,656) ff,harmonic(i)/amax,background(i)/amax,
     $        amu(i,3),ftest(1),ftest(2),ftest(3),ftest(4)
           else
            alarge = max(afact,bfact)
            if (harmonic(i).gt.alarge*base(i)) then
              write (21,756) tm,ff,log(harmonic(i)/amax),
     $           amu(i,3)
            else
              write (21,756) tm,ff,0.0,amu(i,3)
            endif
           endif
        end do
      endif
c
c     finished with evolutive loop
c
777   end do
c
      open (unit=27,file='spec-inf.out',status='unknown')
      if (itype.eq.1) write (27,*) 'final window:'
      write (27,*) 'smoothing:'
      write (27,*) '# points: ',nsmooth
      write (27,*) '   bndwdth: ',fsmooth
      write (27,*) '   log(yes=1) ',ilog
      write (27,*) 'normalization option: ',inorm
      write (27,*) 'anrm: ',anrm
      write (27,*) 'normalizing factor for output: ',amax
      write (27,*) 'raw determination:'
      write (27,*) '    white noise variance: ',white0
      write (27,*) '    rho: ',rho0
      write (27,*) '    tau: ',tau0
      write (27,*) 'robust determination:'
      write (27,*) '    white noise variance: ',white
      write (27,*) '    rho: ',rho
      write (27,*) '    tau: ',tau
c
      close (unit=21)
      close (unit=22)
      close (unit=23)
      close (unit=24)
      close (unit=27)
      close (unit=29)
      close (unit=31)
      close (unit=32)
      close (unit=33)
      goto 6666
c
8888  continue
c
654   format (f7.4,1x,5f12.6)
655   format (f7.4,1x,2f12.6)
656   format (f7.4,1x,3f12.6,4f6.2)
657   format (2i5,6f9.3)
c
754   format (2f9.4,1x,1f12.6)
756   format (2f9.4,1x,2f12.6)
c
854   format (f7.4,1x,3f12.6)
855   format (f7.4,1x,1f12.6)
856   format (f7.4,1x,5f6.3)
c
954   format (2f9.4,1x,1f12.6)
955   format (2f9.4,1x,2f12.6)
956   format (2f9.4,1x,5f6.3)
      stop
      end
c
      real function FUNC(rho)
c
      parameter (nlim=32768)
      COMMON /BLK1/white,specmed(nlim),fny,ddf,f0
      COMMON /BLK2/ilog,nfreq
      real rho
      real pie,dff,freq_norm,ff,arg,small,rednoise,val1,val2
      pie = 3.1415926
      small = 1e-12
      dff = 0.0
      do j=1,nfreq-1
         ff = (j-1)*ddf+f0
         freq_norm = ff/fny
         arg = freq_norm*pie
         rednoise = white*(1.0-rho**2)/
     $      (1.0-2.0*rho*cos(arg)+rho**2)
         if (ilog.eq.0) then
           dff = dff + (specmed(j)-rednoise)**2
         else
           val1 = abs(specmed(j))
           val2 = abs(rednoise)
           if (val1.lt.small) val1=small
           if (val2.lt.small) val2=small
           dff = dff + 
     $     (log(val1)-log(val2))**2
         endif
      end do
      FUNC = dff
      return
      end
