c   program to  merge single  event files to one file from
c   standard data base or a base an d a file. Two events are merged together
c   if they are less than maxdif seconds apart 
c
c   jens havskov, jan 88
C   uppdates:
c   mar 8 by j.h   : also merge distant events
c   jan 19   j.h.  : adaption new data base, file name length
c
c   aug 6    c.l.  : new merge routine implemented
c   feb 17, 92 r.a.: fixed for SUN
c   feb 18,    r.a.: fixed for time difference at new month
c   jul 93    version 3.0
c   aug 23         : filenames to 80
c   nov 24, 1994   : opening files changed
c   dec 94         : ********* version 5.0 ********************
c   jan 11         : new find ev in
c   feb 7 99 jh    : ---------Version 7.0 ---------------------
c                    fix year, start and end times
c   sep 23   jh    : put in confirm overrride, error if dir name had a '-'
c                    put in time routines
c   nov 6,00       : bug: seconds were not used
c   feb 2001       : merge from data base and a file
c   mar 23 2004 jh : also write out events used for merging if from a file

        implicit none	
C
C    Seisan library inserts and routines...
C    ======================================
C
       include 'libsei.inc'                ! File operations.
       include 'seidim.inc'                ! Dimentions
C
       external sei open,                  ! Open file routine.
     &          sei close,                 ! Close file routine.
     &          sei code                   ! Error encoder.
C
C    ============= end of list ==========
C
       character*80	data1(max_data),data2(max_data)	
c event data
       character*1	exp		
c exp indicator
       character*1      type1,type2,type
c event type
       character*1      answer		
c answer
       integer		nrecord		
c number of recors for event
       integer		nhead		 
c  number of header lines
       integer		nrecord2	
       character*1      confirm     ! y: confirm delete, n, do not confirm
c  number of recors for event
       integer		nhead2		
c   number of header lines
       integer		nstat, nphas
c number of stations
       character*14     start_time,end_time 
c start and end time of select
       character*40	base_name	
c data base name if not rea (blank)
       character*80	evfile1,evfile2, text	
c event file name
       character*10     key		
c select key
       integer		status,new_month,fstart,event_no 
c see subroutine find...
       integer nass,ndel,nmer 		
c counters for events, records etc.
       integer		maxdif		
c maximum difference in secs b. ev.
       integer		year1,month1,day1,hr1,min1,sec1
       integer		year2,month2,day2,hr2,min2,sec2
       real sec11,sec22
       double precision t1,t2,diff
c time in day-hr-min-sec
       integer		choice		
c choice for merging, see below
       integer		first		
c indicate first time read 1: first
       integer 		i,id		
c print unit
       integer          printu
c logical for existing file or not
       logical          b_old
c returned code                                   
       integer          code
c read unit #1 
       integer          readu1
c read unit #2
       integer          readu2
       integer          npos       ! position of flag
       logical          afile      ! true if file comparison used
       character*80     infile     ! file name
       logical          merged     ! true if event used for merge
c function
       real seirealnum


c
c print version
c
      include 'version.inc'
      out_version_date='July 23, 2001'
      if (version_new) out_version_date=version_date
      call print_ver

c
c   open output file
c
      call sei open(unknown$,              ! Open a unknown status file. 
     &              ' ',                   ! Prompt file name (n/a).
     &              'associ.out',       ! File name
     &              printu,                ! Print unit
     &              b_old,                 ! Already exists? (n/a).
     &              code)                  ! Returned condition.
c
c   input base name and time interval
c
       write(6,*)' Base name, return for default'
       read(5,'(a40)') base_name
       write(6,*)' Start time'
       read(5,'(a14)') start_time
       write(6,*)' End time, return for end of month'
       read(5,'(a14)') end_time
c
 3     continue
c
c Give time difference between events to be associated
c
13     write(*,*) 
     * ' Give maximum time difference between two events to associcate'
       write(6,*) ' default is 150 s (return):'
       read(5,'(a)') text
       maxdif= sei real num (text,code)
       if (maxdif .eq. 0 ) maxdif=150		 
c
c  associate from a file or from same base
c
c
       write(6,*)' Associate from a file        :  Enter file name'
       write(6,*)' Associate from same data base:  Enter          '
       read(5,'(a)') infile
       afile=.false.
       if(infile.ne.' ') afile=.true. ! associate from infile'
c
c   open file if associate from file
c
       if(afile) then
 344      continue
          open(3,file=infile,status='old',err=345)
          goto 346
 345      continue
          write(6,*)' Error opening file, enter file name'
          read(5,'(a)') infile
          goto 344
 346      continue
        endif

       if(.not.afile) then
       write(6,*)
     *' check events which can be associated                    (1)'
       write(6,*)
     *' associate and merge events, do NOT delete merged events (2)'      
       write(6,*)
     *' associate and merge events, delete merged events        (3)'
       read(5,*) choice
       if(choice.ne.1.and.choice.ne.2.and.choice.ne.3) then
c
c check choice
c
          write(6,*) 'wrong choice, try again'
          goto 3
       endif
       endif
       if(afile) then
 33    continue
       write(6,*)
     *' check events which can be associated                    (1)'
       write(6,*)
     *' associate and merge events                              (2)'
       read(5,*) choice
       if(choice.ne.1.and.choice.ne.2) then
c
c check choice
c
          write(6,*) 'Wrong choice, try again'
          goto 33
       endif
       endif
c
c always use next event
c
       confirm='n'
       if(choice.gt.1) then
          write(6,*)' Confirm merge (y/n)'
          read(5,'(a)') confirm
       endif

       key='          '
c
c  reset counters
c
       nass=0
       nmer=0
       ndel=0
       first=1
c
c
c----------------------------------------------------------------
c   merge from same base
c----------------------------------------------------------------
c
       if(.not.afile) then


 4     continue
c
c   read first event or first event after a merge
c
       CALL findevin
     * (base_name,start_time,end_time,key,0,
     * event_no,evfile1,fstart,new_month,status)
       if(first.eq.1) then		
c  check if first time around
          new_month=0			
c lower new month flag
          first=0                       
c  lower first flag
       endif

c  return if eof or other erorrs

       if(status.ne.0) go to 99
c
c indicate that no comparisom possible
c
       t1=-1				

       write(6,208) event_no,evfile1(1:50),int(t1)
       goto 6
c
c  read and write loop until pair found
c
 5     continue
c
c   shift to next event, save previous
c
       evfile1=evfile2
       key='          '		
c always use next event
 6     continue			
c start here the first time
       CALL findevin	
c get name of next event
     * (base_name,start_time,end_time,key,0,
     * event_no,evfile2,fstart,new_month,status)

c return if eof or other erorrs

       if(status.ne.0) goto 99
c
c   compare times
c
       call time_evname(evfile1,year1,month1,day1,hr1,min1,sec1,type1)
       call time_evname(evfile2,year2,month2,day2,hr2,min2,sec2,type2)
       sec11=sec1
       sec22=sec2
       call TIMSEC (YEAR1,month1,DAY1,HR1,MIN1,SEC11,t1)
       call TIMSEC (YEAR2,month2,DAY2,HR2,MIN2,SEC22,t2)
       write(6,208) event_no,evfile2(1:55),int(t2-t1)
 208   format(1x,'#',i4,1x,a55,' Diff=',i8,' s')
c
c   check types before comparing times
c
C       if(type1.eq.'D'.or.type2.eq.'D') go to 5	
c do not merge distant events
       if(dabs(t2-t1).lt.maxdif) then
c
c   count events associated 
c
          nass=nass+1
          if(choice.eq.1) then	
c only show which events are associated
             write(printu,217,iostat=code)
     *       evfile2(fstart:fstart+18),evfile1(fstart:fstart+18)
             call sei code(stop$,          ! Force stop on error.
     &                     code,           ! Fortran i/o condition.
     &                     printu,         ! Unit with condition.
     &                     b_old)          ! Flag (n/a).
C
             write(6,217)
     *       evfile2(fstart:fstart+18),evfile1(fstart:fstart+18)
 217         format(1x,'   ***** ',a,' is associated with ',a,' *****')
          else
c
c merge associated events
c
c  question merge
c
            write(6,207) event_no,
     *      evfile2(fstart:fstart+10),evfile1(fstart:fstart+10)
 207        format(1x,'    **** merge #',i3,2x,a,' with ',a,' y/n ****')
            if(confirm.eq.'N'.or.confirm.eq.'n') then
               answer='y'
            else
               read(5,'(a1)') answer
            endif
            if(answer.eq.'y'.or.answer.eq.'Y') then
               call sei open(old$,                  ! Open a existing file.
     &                       ' ',                   ! Prompt file name (n/a).
     &                       evfile1,               ! File name
     &                       readu1,                ! Read unit #1
     &                       b_old,                 ! Already exists? (n/a).
     &                       code)                  ! Returned condition.
               call sei open(old$,                  ! Open a existing file.
     &                       ' ',                   ! Prompt file name (n/a).
     &                       evfile2,               ! File name
     &                       readu2,                ! Read unit #2
     &                       b_old,                 ! Already exists? (n/a).
     &                       code)                  ! Returned condition.
c
c   read two input files
c
               call indata
     *         (readu1,nstat,nphas,nhead,nrecord,type,exp,data1,id)
               call indata
     *         (readu2,nstat,nphas,nhead2,nrecord2,type,exp,data2,id)

              
c
c   merge events
c
               call merge_f(data1,data2,nhead,nhead2,nrecord,nrecord2)

               rewind( readu1, iostat=code )
               call sei code(stop$,             ! Stop program on error.
     &                       code,              ! Fortran i/o condition.
     &                       readu1,            ! Unit with condition.
     &                       b_old)             ! Flag (n/a).
C
               write(readu1,'(a80)',iostat=code)
     &                         (data1(i),i=1,nrecord)   
               call sei code(stop$,             ! Stop program on error.
     &                       code,              ! Fortran i/o condition.
     &                       readu1,            ! Unit with condition.
     &                       b_old)             ! Flag (n/a).
C
c write event
c
c   close and delete file 2 if choice is 3
c
               nmer=nmer+1		
c count merged events
               if(choice.eq.3) then
                  call sei close (delete$+warn$,readu2,code)
                  if (code .eq. e_ok$) write(6,*)
     *                '    **** event',event_no,' deleted ****'
                  ndel=ndel+1		
c count deleted events
               else
                  call sei close (close$,readu2,code)
               endif
               call sei close (close$,readu1,code)
               go to 4	  
c go and read one extra event before continuing
            endif
         endif
       endif
      
       goto 5 ! next event

      endif

c
c-----------------------------------------------------------------
c  merge from file and base
c----------------------------------------------------------------
c-
c
      if(afile) then

        open(4,file='associ_rest.out',status='unknown')
        open(8,file='associ_merg.out',status='unknown')
c
c   initialize by read one event from each source
c                                                
c
c   read event of data base
c
       CALL findevin
     * (base_name,start_time,end_time,key,0,
     * event_no,evfile1,fstart,new_month,status)
       if(first.eq.1) then		
c  check if first time around
          new_month=0			
c lower new month flag
          first=0                       
c  lower first flag
       endif
c
c  return if eof or other erorrs
c
       if(status.ne.0) go to 99
c
c   read first event from file
c
       merged=.false.                ! flag to indicate event not tmerged
       call indata
     * (3,nstat,nphas,nhead2,nrecord2,type,exp,data2,id)
       if(nrecord2.eq.0) goto 99     ! end of file
c
c   compare times
c
       call time_evname(evfile1,year1,month1,day1,hr1,min1,sec1,type1)
       read(data2(1),'(1x,i4,1x,2i2,1x,2i2,f5.1)')
     * year2,month2,day2,hr2,min2,sec22
       sec11=sec1
       call TIMSEC (YEAR1,month1,DAY1,HR1,MIN1,SEC11,t1)
       call TIMSEC (YEAR2,month2,DAY2,HR2,MIN2,SEC22,t2)
       diff=t2-t1
       write(printu,'(a,2x,f12.1)') evfile1(fstart:fstart+19), diff
c
c   merge if difference small enough
c
       if(dabs(diff).le.maxdif) then
         merged=.true.                    ! event merged, do not write out
         npos=2222
         goto 5555   ! merge point
       endif
 2222  continue

c
c  loop for reading in base and file
c

  250  continue
c
c   advance in file until file time has passed data base time
c   check if any events to be merged
c
       do while(t2.le.t1)
c
c   if previous event was not used for merge, write out event in
c   file for not merged events, else write in file for events
c   which were used for merging. note, the actual merged events are written 
c   out in a different file
c
          if(.not.merged) then
              write(4,'(a)') (data2(i),i=1,nrecord2)
              ndel=ndel+1
          else
              write(8,'(a)') (data2(i),i=1,nrecord2)
          endif
c
          call indata
     *    (3,nstat,nphas,nhead2,nrecord2,type,exp,data2,id)
          if(nrecord2.eq.0) goto 99
          merged=.false.                              ! reset merge flag
c          write(6,*)'advance indata'
          read(data2(1),'(1x,i4,1x,2i2,1x,2i2,f5.1)')
     *    year2,month2,day2,hr2,min2,sec22
          call TIMSEC (YEAR2,month2,DAY2,HR2,MIN2,SEC22,t2)
          diff=t2-t1
          write(printu,'(a,2x,f12.1)') evfile1(fstart:fstart+19), diff
          if(dabs(diff).lt.maxdif) then
             merged=.true.       ! event used for merge
c             ndata=ndata+1
             npos=3333
             goto 5555
          endif
 3333     continue
c           if(ndata.gt.0) call data_back(3,ndata)
c           ndata=0
        enddo             
c
c   advance data base one event
c
       CALL findevin
     * (base_name,start_time,end_time,key,0,
     * event_no,evfile1,fstart,new_month,status)
c
c  return if eof or other erorrs
c
       if(status.ne.0) go to 99
       call time_evname(evfile1,year1,month1,day1,hr1,min1,sec1,type1)
       sec11=sec1
       call TIMSEC(YEAR1,month1,DAY1,HR1,MIN1,SEC11,t1)
       diff=t2-t1
       write(printu,'(a,2x,f12.1)') evfile1(fstart:fstart+19), diff
       if(dabs(diff).lt.maxdif) then
          merged=.true.                   ! INDECATE EVENT MERGED
          npos=4444
          goto 5555
       endif
 4444  continue
c
c   back up to check file
c
       goto 250




 5555  continue

c
c   count events associated 
c
          nass=nass+1

          if(choice.eq.1) then
c
c only show which events are associated
c
             write(6,217)
     *       evfile1(fstart:fstart+18),data2(1)(1:20)
             write(printu,217)
     *       evfile1(fstart:fstart+18),data2(1)(1:20)

          else
c
c merge associated events
c

c
c  question merge
c
            write(6,207) event_no,
     *      evfile1(fstart:fstart+10),data2(1)(1:20)
c
            write(printu,207) event_no,
     *      evfile1(fstart:fstart+10),data2(1)(1:20)

            if(confirm.eq.'N'.or.confirm.eq.'n') then
               answer='y'
            else
               read(5,'(a1)') answer
            endif
            if(answer.eq.'y'.or.answer.eq.'Y') then
               call sei open(old$,                  ! Open a existing file.
     &                       ' ',                   ! Prompt file name (n/a).
     &                       evfile1,               ! File name
     &                       readu1,                ! Read unit #1
     &                       b_old,                 ! Already exists? (n/a).
     &                       code)                  ! Returned condition.
c
c   read data base file
c
               call indata
     *         (readu1,nstat,nphas,nhead,nrecord,type,exp,data1,id)
           
c
c   merge events
c
               call merge_f(data1,data2,nhead,nhead2,nrecord,nrecord2)

               rewind( readu1, iostat=code )
               call sei code(stop$,             ! Stop program on error.
     &                       code,              ! Fortran i/o condition.
     &                       readu1,            ! Unit with condition.
     &                       b_old)             ! Flag (n/a).
C
               write(readu1,'(a80)',iostat=code)
     &                         (data1(i),i=1,nrecord)   
               call sei code(stop$,             ! Stop program on error.
     &                       code,              ! Fortran i/o condition.
     &                       readu1,            ! Unit with condition.
     &                       b_old)             ! Flag (n/a).
               
               call sei close (close$,readu1,code)
             endif
c
c   count merged events
c
             nmer=nmer+1
          endif
c
c  back to where merge was initiated from
c
         if(npos.eq.2222) goto 2222
         if(npos.eq.3333) goto 3333
         if(npos.eq.4444) goto 4444

       endif
c-------------------------------------------------------------------



 99    continue
       if(afile) then
c
c   if merge from file, write out rest of events from file not used
c
          if(.not.merged) then
             write(4,'(a)') (data2(i),i=1,nrecord2)
             ndel=ndel+1
          endif
 90       continue
          call indata
     *    (3,nstat,nphas,nhead2,nrecord2,type,exp,data2,id)
          if(nrecord2.eq.0) goto 199     ! end of file
          write(4,'(a)')(data2(i),i=1,nrecord2)
          ndel=ndel+1
          goto 90
 199      continue
       endif
 
c
c  print out statistics
c

      write(6,*)
      write(6,*)
      if(.not.afile) write(6,201) nass,nmer,ndel
      if(afile) then
        write(6,*) ' Number of associated events from file',nass
        write(6,*) ' Number of merged events              ',nmer
        write(6,*) ' Number of remaining events in file   ',ndel
        write(6,*)
      endif
        

      write(printu,*,iostat=code)
      call sei code( stop$, code, printu, b_old)
C
      write(printu,*,iostat=code)
      call sei code( stop$, code, printu, b_old)
C
      write(printu,201,iostat=code) nass, nmer, ndel
      call sei code( stop$, code, printu, b_old)
C

 201  format(' Total number of associated events',i7,
     *     /,' Total number of merged events    ',i7
     *     /,' Total number of deleted events   ',i7)
c
      write(6,*)' Output of statistics id associ.out'
      if(afile) then
        write(6,*)
     *' Events in file not used for merge: associ_rest.out'
        write(6,*)
     *' Events in file used for merge: associ_merg.out'
      endif
      stop
      end
     

      subroutine time_evname(evname,year,month,day,hr,min,sec,type)
c
c  finds date and event type from seisan data base evname.
c  Possible disk or directory names are of no importance.
c
      implicit none
      integer year,month,day,hr,min,sec
      character*80 evname	
c event file name inc possibly disk name
      character*1  type		
c event type
      integer i
      call get_fstart(evname,i)
      i=i+2
c     i = index(evname,'-')                
c find first '-' in name
      read(evname(i-2:i-1),'(i2)') day
      read(evname(i+1:i+2),'(i2)') hr
      read(evname(i+3:i+4),'(i2)') min
      read(evname(i+6:i+7),'(i2)') sec
      read(evname(i+8:i+8),'(a1)') type
      read(evname(i+11:i+14),'(i4)') year
      read(evname(i+15:i+16),'(i2)') month
         
c
      return
      end
c -----------------------------------------------------


      subroutine data_back(unit,ndata)
c
c   backspace one or several events, not tested
c
      implicit none

      integer ndata,unit,k
      character*80 text
      k=0

  10  continue
      backspace(unit)
      backspace(unit)
      read(unit,'(a)') text
      if(text.eq.' ') k=k+1
      if(k.eq.ndata) return
      goto 10

      return
      end
         


