[KLOE] [Offline Doc] [TRK Files]

Track Reconstruction Library

v_merge.kloe


      subroutine v_merge
C-----------------------------------------------------------------------
C-
C-   Created   12-Jun-1996   Alexander Andryakov
C-   
C-   Purpose: Goes through all t.c. found by 1-view p.r. and chooses the pairs
C-            to be merged in one 3-d t.c.
C-
C-   Output :
C-           numb_3d_cand - number of 3-d t.c. built 
C----------------------------------------------------------------------
$$IMPLICIT
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$INC:ERLEVL.INC'
$$INCLUDE 'K$ITRK:CDTCUT.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DHRE.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
c
      INTEGER BLOCAT,BNUMB
      LOGICAL intersect_in_layer_phi
c
      INTEGER cycle,status,ind,
     &        inddat_dprs_1,itr1,inddat_dprs_2,itr2,view_n1,view_n2,
     &        checked_tc_list(N_TRK_MAX),itr_tried,
     &        merging_order(FPL_LNG_MAX),list_length 
      REAL    first_pass_list(FPL_LNG_MAX,3),curvature1,curvature2
c
c
c   Some preparations
c     Take the value of	LAYER_GAP and COMBINING_GAP (wire/phi gap) 
c     equal to corresponding cuts used in DTPTRN (one view pattern recognition)
c
      LAYER_GAP     = LDTXTR * 2
      COMBINING_GAP = DTXPN3 + 0.01
c
c     Locate DHRE bank
c
      status = blocat(IW,'DHRE',1,ind,inddat_dhre)  
      if (status .ne. YESUCC) return   !  DHRE bank has not been located
      dhre_e_size = IW(inddat_dhre + DHRNCO)
      inddat_dhre = inddat_dhre + IW(inddat_dhre + DHRHDS)
c
c   FIRST loop over all t.c. Only t.c. from different stereo views and the
c     same sign of curvatures are merged in accordance with ordered
c     first_pass_list. If some t.c. becomes 3d one it leaves this loop
c     and will be treated in the SECOND loop. (It's very important in
c     multitrack regime) Start with the first t.c. in DPRS chain (take
c     it as current)
c     Build the ordered first_pass_list.
c
      call make_1st_pass_list(first_pass_list,list_length,
     &                        merging_order)
c
c     Go through the list
c
      if(list_length.lt.1) return
      call vzero(checked_tc_list,N_TRK_MAX)
      n_itr1_checked = 0
      n_itr2_checked = 0
      cycle=1
      do while(cycle .le. list_length .and.
     &         n_itr1_checked .lt. first_itr2 - 1 .and.
     &         n_itr2_checked .lt. last_itr2-first_itr2+1)

c
c     Get the t.c. attributes
c
        itr1=int(first_pass_list(merging_order(cycle),2))
        itr2=int(first_pass_list(merging_order(cycle),3))
        inddat_dprs_1 = inddat_dprs_array(itr1)
        inddat_dprs_2 = inddat_dprs_array(itr2)
c
c     Check if neither of t.c. has already become 3d one
c
        view_n1 = iw(inddat_dprs_1+DPRPOK)
        view_n2 = iw(inddat_dprs_2+DPRPOK)
        if(view_n1 .ne. 3 .and. view_n2 .ne. 3) then 
c
c     Try to merge them
c
          if(inddat_dprs_1 .gt. 0 .and. inddat_dprs_2 .gt. 0) then 
            call merge_2_tc(itr1,inddat_dprs_1,itr2,inddat_dprs_2)
          
c
c      Save for "curretnt" t.c. its partner t.c. number. It's done with the
c      aim not to try to merge this pair in the SECOND loop
c
            if(itr1 .le. N_TRK_MAX) checked_tc_list(itr1)=itr2
          endif
        endif
c
c     Take the next pair of t.c.
c
        cycle = cycle+1
      enddo
c
c   SECOND loop over all t.c. Only t.c. from different stereo views with the
c   same sign and closest values of curvatures and NOT tried in the FIRST loop
c   are about to be merged 
c     Locate the first t.c. in DPRS chain 
c
      status=BLOCAT(iw,'DPRS',-1,ind,inddat_dprs_1)
c
c     Get the track candidate number
c
      status=BNUMB(IW,ind,itr1)
      if (status.ne.YESUCC) then
         call ERLOGR('v_merge',ERSEVR,0,status,
     &              'track number cannot be retrieved!?')
        return
      endif
c
c     Go through all t.c.. (Loop over "current" t.c.)
c
      do while(itr1 .lt. last_itr2)
        if(inddat_dprs_array(itr1) .gt. 0) then
c
c     DPRS bank of the "current" t.c. exists. Check all the rest t.c.
c     for merging with it.
c
          inddat_dprs_1=inddat_dprs_array(itr1)
c
c     Get curvature and view number of the "current" t.c.
c
          curvature1= rw(inddat_dprs_1+DPRCUR)
          view_n1   = iw(inddat_dprs_1+DPRPOK)
c
c     Get the number of t.c. already tried to be merged with the "current"
c     one in the FIRST loop
c
          if(itr1.le.N_TRK_MAX) then
            itr_tried=checked_tc_list(itr1)
          else
            itr_tried=-1
          endif
c
c     Go throuhg all t.c. starting from the next to the "current" one and 
c     check them one by one if they have appropriate sign of curvature and
c     view number (The last means that we will try to merge here only t.c. 
c     from different views 1,2,3. 3 means 3-d t.c.)
c     Loop over "second" t.c..
c
          itr2=itr1+1
          do while(itr2 .le. last_itr2 .and.
     &             inddat_dprs_1 .gt. 0)
            if(inddat_dprs_array(itr2) .gt. 0) then
c
c     DPRS bank of "second" t.c. exists. Check it on merging
c
              inddat_dprs_2=inddat_dprs_array(itr2)
c
c      Get curvature and view number of "second" t.c.
c
              curvature2= rw(inddat_dprs_2+DPRCUR)
              view_n2   = iw(inddat_dprs_2+DPRPOK)
c
c     Check if this pair of t.c. has not been already tried in the FIRST loop.
c     This pair should not be attempted only if NEITHER of both t.c. has
c     become 3d t.c. during the FIRST loop
c     
              if(itr2 .ne. itr_tried .or.
     &             view_n1 .eq. 3 .or. view_n2 .eq. 3) then
c
c      Check whether these two t.c. are from different views 
c                         and 
c            whether their curvatures are of the same sign
c                         and 
c            whether they occupy intersecting regions in layer-phi space
c     and make an attempt to merge this pair of t.c..
c
c
                if(curvature1 * curvature2 .gt. 0. .and.
     &               view_n1 .ne. view_n2 .and.
     &               intersect_in_layer_phi(inddat_dprs_1,inddat_dprs_2)
     &            ) then
                  call merge_2_tc(itr1,inddat_dprs_1,itr2
     &                            ,inddat_dprs_2)
c
c     Update curvature and view number of the "current" t.c.
c
                  inddat_dprs_1=inddat_dprs_array(itr1)
                  if(inddat_dprs_1 .gt. 0) then
                    curvature1= rw(inddat_dprs_1+DPRCUR)
                    view_n1   = iw(inddat_dprs_1+DPRPOK)
                  endif
                endif
              endif
            endif
c
c     Take next "second" t.c. and continue the loop over "second" t.c.
c
            itr2 = itr2 + 1
          enddo
c
c     All the t.c. next to the "current" one have been checked/merged
c     with it. Take next "current" t.c. and continue the loop over
c     "current" t.c.  
c
        endif
        itr1 = itr1 + 1
      enddo
      return
      end
C===========================================================================
      integer function adjust_layer_directions(
     &           nhits1,inddat_dprs_1,
     &           hitn_1_c_f,hitn_1_c_l,layer_1,layer_dir_1,
     &           nhits2,inddat_dprs_2,
     &           hitn_2_c_f,hitn_2_c_l,layer_2,layer_dir_2)
$$IMPLICIT
      integer 
     &           nhits1,inddat_dprs_1,
     &           hitn_1_c_f,hitn_1_c_l,layer_1,layer_dir_1,
     &           nhits2,inddat_dprs_2,
     &           hitn_2_c_f,hitn_2_c_l,layer_2,layer_dir_2
C-----------------------------------------------------------------------
C-
C-   Created   11-Jun-1996   Alexander Andryakov
C-   
C-   Purpose: Finds the pieces of t.c. with the same layer direction of
C-            movement.
C-            It's supposed that at least one t.c. changes its direction
C-
C-   Input :  
C-           nhits1        \ total number of hits of both t.c.
C-           nhits2        / 
C-           inddat_dprs_1 \ pointer to the beginning of the hit list in
C-           inddat_dprs_2 / DPRS banks of 1st and 2nd t.c. respectevly
C-           hitn_1_c_f    \ DHRE numbers of the 1st and the last hits in the 
C-           hitn_1_c_l    / "current" cluster of the 1st t.c.
C-           hitn_2_c_f    \ same as hitn_1_c_f,hitn_1_c_l but for 2nd t.c.
C-           hitn_2_c_l    /
C-           layer_1   	   \ layer number of clusters of both t.c.
C-           layer_2       /
C-           layer_dir_1   \ layer direction of both t.c.
C-           layer_dir_2   /
C-   Output :
C-           hitn_1_c_f   \                                                   
C-           hitn_1_c_l    | These values define layer cluster.
C-           hitn_2_c_f    | ONLY for one of 2 t.c. they will describe
C-           hitn_2_c_l    | new "current" cluster
C-           layer_1   	   |                                                 
C-           layer_2      / 
C-   Return :
C-           <0 - adjustment failed
C-           >0 -  ---//---  succeeded
C----------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DHRE.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
c
      INTEGER get_layer_cluster
      INTEGER inddat_dprs,hitn_c_f,hitn_c_l,hitn_n_f,hitn_n_l,
     &        layer_dir,nhits,layer,
     &        layer_n
      LOGICAL first
c
      adjust_layer_directions = -1
      if(iw(inddat_dprs_1 - DPRCEN + DPRLRG) .lt. 0 .and.
     &   iw(inddat_dprs_2 - DPRCEN + DPRLRG) .lt. 0) then
c
c  Both t.c. change their direction
c  For a moment we are only looking into the longest t.c. and are using only
c  one layer direction matching and ignore another matching
c
      else if(iw(inddat_dprs_1 - DPRCEN + DPRLRG) .lt. 0) then
        if(nhits1 .ge. nhits2) then
          first=.TRUE.
          inddat_dprs = inddat_dprs_1
          hitn_n_f    = hitn_1_c_l+1 
          hitn_c_f    = hitn_1_c_f 
          layer       = layer_1    
          layer_dir   = layer_dir_1    
          nhits       = nhits1
        else
          first=.FALSE.
          inddat_dprs = inddat_dprs_2
          hitn_n_f    = hitn_2_c_l+1 
          hitn_c_f    = hitn_2_c_f 
          layer       = layer_2
          layer_dir   = layer_dir_2
          nhits       = nhits2
        endif
c	   
c  Only 1st t.c. changes its direction. 
c  Find the beginning of its piece of other direction
c
        first=.TRUE.
        inddat_dprs = inddat_dprs_1
        hitn_n_f    = hitn_1_c_l+1 
        hitn_c_f    = hitn_1_c_f 
        layer       = layer_1
        layer_dir   = layer_dir_1    
        nhits       = nhits1
      else if(iw(inddat_dprs_2 - DPRCEN + DPRLRG) .lt. 0) then
c
c  Only 2nd t.c. changes its direction
c  Find the beginning of its piece of other direction
c
        first=.FALSE.
        inddat_dprs = inddat_dprs_2
        hitn_n_f    = hitn_2_c_l+1 
        hitn_c_f    = hitn_2_c_f 
        layer       = layer_2
        layer_dir   = layer_dir_2
        nhits       = nhits2
      endif
c
c  Loop over wires/clusters to find the piece of another direction
c      
      do while (hitn_n_f .le. nhits)
c
c  Take next cluster and check new layer direction between this ckuster and
c  previous one 
c
        hitn_n_l = get_layer_cluster(nhits,hitn_n_f,
     &                 inddat_dprs,layer_n)
        if((layer_n-layer)*layer_dir .lt. 0) then
          adjust_layer_directions = 1
          go to 111
        endif
        hitn_c_f = hitn_n_f
        hitn_c_l = hitn_n_l
        layer    = layer_n
        hitn_n_f = hitn_c_l + 1
      enddo
  111 if(first) then
        hitn_1_c_f    = hitn_c_f   
        hitn_1_c_l    = hitn_c_l   
        layer_1       = layer
      else
        hitn_2_c_f    = hitn_c_f   
        hitn_2_c_l    = hitn_c_l   
        layer_2       = layer
      endif
      return
      end
C===========================================================================
      logical function check_azim_gap(
     &        hit1, inddat_dprs1, hit2, inddat_dprs2)
$$IMPLICIT
      integer hit1, inddat_dprs1, hit2, inddat_dprs2
C----------------------------------------------------------------------
C-
C-   Created   23-May-1996   Alexander Andryakov
C-
C-   Input :  
C-           hit1         -  hit number in DPRS bank of the 1st t.c.
C-           hit2         -  hit number in DPRS bank of the 2nd t.c.
C-           inddat_dprs1 -  pointer to the beginning of the data block of DPRS
C-                           bank of the 1st t.c.
C-           inddat_dprs2 -  the same as inddat_dprs1 but for the 2nd t.c.
C-   Return :
C-           result of azimuthal gap check (azimuthal gap is equivalent to the
C-           gap measured in number of wires)
C----------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DHRE.INC'
$$INCLUDE 'K$ITRK:CTIDRI.INC'
$$INCLUDE 'K$ITRK:CDTCUT.INC'
$$INCLUDE 'K$ITRK:CDTHIT.INC'
$$INCLUDE 'K$ITRK:CCONST.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
c
      INTEGER dhre_w_n1,dhre_w_n2,dhre_pos,layer1,layer2
      REAL    tan_stereo,azim_1,azim_2,azim_gap,phi1,phi2
c
      dhre_w_n1 = iw(inddat_dprs1 + DPRLWI*(hit1-1)+DPRIWI) 
      dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n1-1)
      layer1 = iw(dhre_pos + DHRSLR)
      phi1 = TIDDP(layer1) * (iw(dhre_pos + DHRWNR)-1)
      dhre_w_n2 = iw(inddat_dprs2 + DPRLWI*(hit2-1)+DPRIWI) 
      dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n2-1)
      layer2 = iw(dhre_pos + DHRSLR)
      phi2 = TIDDP(layer2) * (iw(dhre_pos + DHRWNR)-1)
      if(mod(abs(layer1-layer2),2) .ne. 0) then
c
c   The hits belong to layers of DIFFERENT views
c
        tan_stereo=TIDST(layer1)/TIDSC(layer1)
        azim_1=atan(tan_stereo/sqrt((TIDRA(layer1)/ZMAX)**2-
     &              tan_stereo**2))
        tan_stereo=TIDST(layer2)/TIDSC(layer2)
        azim_2=atan(tan_stereo/sqrt((TIDRA(layer2)/ZMAX)**2-
     &              tan_stereo**2))
        azim_gap=abs(azim_1-azim_2)
      else
c
c   The hits belong to layers of the SAME view. Take the biggest azimuthal gap
c   from one view pattern recognition.
c
       azim_gap=max(TIDDP(layer1),TIDDP(layer2)) * DTXPN1
      endif
      if(abs(phi1-phi2).gt.azim_gap
     &  .and.
     &  pi2-abs(phi1-phi2).gt.azim_gap) then
        check_azim_gap=.FALSE.
      else
        check_azim_gap=.TRUE.
      endif
      return
      end
C===========================================================================
      integer function combine_clusters(
     &        hitn_1_f,hitn_1_l,inddat_dprs_1,nhits1,
     &        hitn_2_f,hitn_2_l,inddat_dprs_2,nhits2,
     &        combine_buffer)
$$IMPLICIT
      integer
     &        hitn_1_f,hitn_1_l,inddat_dprs_1,nhits1,
     &        hitn_2_f,hitn_2_l,inddat_dprs_2,nhits2,
     &        combine_buffer(1)
C----------------------------------------------------------------------
C-
C-   Created   30-May-1996   Alexander Andryakov
C-
C-   Input :  
C-           inddat_dprs_1 \ pointer to the beginning of the data block of DPRS
C-           inddat_dprs_2 / banks of 1st and 2nd t.c. respectevly
C-           hitn_1_f      \ DHRE numbers of the 1st and the last hits in the 
C-           hitn_1_l      / cluster of the 1st t.c.
C-           hitn_2_f      \ same as above but for 2nd t.c.
C-           hitn_2_l      /
C-   Output :
C-           combine_buffer -  temporary buffer with mixture of wires from
C-                             both t.c.
C-   Return :
C-           <0 - combining failed
C-           >0 - total number of wires saved into temporary buffer
C-
C-   **** Very important note ***
C-    It's supposed that both t.c. moves in the same azimuth direction
C-    However the check of this is done
C----------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$ITRK:CTIDRI.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DHRE.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
c
      INTEGER get_layer_cluster
      LOGICAL check_azim_gap
c
      INTEGER cycle1,cycle2, n_w, dhre_w_n, dhre_pos,layer,
     &        layer_1,hitn_1_n_f,hitn_1_n_l,
     &        layer_2,hitn_2_n_f,hitn_2_n_l 
      REAL    phi_1_c, phi_1_l, phi_2_c, phi_2_l,
     &        phi_dir_1, phi_dir_2, phi_dir, azimthal_gap
c
      REAL A,B,PROX
      PROX(B,A)=B + 6.2831853 * ANINT(0.15915494*(A-B))
c
c
c   Azimuth of 1st wire of 1st t.c. and delta phi of  the layer
c
      dhre_w_n = iw(inddat_dprs_1 + DPRLWI*(hitn_1_f-1)+DPRIWI) 
      dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n-1)
      layer = iw(dhre_pos + DHRSLR)
      phi_1_c = TIDDP(layer) * (iw(dhre_pos + DHRWNR)-1)
      azimthal_gap=COMBINING_GAP*TIDDP(layer)
c
c   Azimuth of last wire of 1st t.c.
c
      dhre_w_n = iw(inddat_dprs_1 + DPRLWI*(hitn_1_l-1)+DPRIWI) 
      dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n-1)
      phi_1_l = TIDDP(layer) * (iw(dhre_pos + DHRWNR)-1)
      phi_dir_1 = sign(1.,phi_1_l-PROX(phi_1_c,phi_1_l))
c
c   Azimuth of 1st wire of 2nd t.c.
c
      dhre_w_n = iw(inddat_dprs_2 + DPRLWI*(hitn_2_f-1)+DPRIWI) 
      dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n-1)
      phi_2_c = TIDDP(layer) * (iw(dhre_pos + DHRWNR)-1)
c
c   Azimuth of last wire of 2nd t.c.
c
      dhre_w_n = iw(inddat_dprs_2 + DPRLWI*(hitn_2_l-1)+DPRIWI) 
      dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n-1)
      phi_2_l = TIDDP(layer) * (iw(dhre_pos + DHRWNR)-1)
      phi_dir_2 = sign(1.,phi_2_l-PROX(phi_2_c,phi_2_l))
c
c   Before performing combining procedure, one should check that this
c   procedure will not destroy already existing t.c. It means that one should
c   check azimuthal connection between the last wire of "current" cluster of
c   one t.c. and the first wire of "next" cluster of other t.c. One can
c   restrict oneself by checking only one such connection with the smallest
c   layer gap.
c   Take the "next" clusters of both t.c.
c
      layer_1=0
      hitn_1_n_f = hitn_1_l+1
      if(hitn_1_n_f.le.nhits1)
     &    hitn_1_n_l = get_layer_cluster(
     &            nhits1,hitn_1_n_f,
     &            inddat_dprs_1,layer_1)
      layer_2=0
      hitn_2_n_f = hitn_2_l+1
      if(hitn_2_n_f.le.nhits2)
     &    hitn_2_n_l = get_layer_cluster(
     &            nhits2,hitn_2_n_f,
     &            inddat_dprs_2,layer_2)
c
c   1st t.c. is 3d one and has "next" layer cluster.
c   Check azimuth gap between hitn_2_l and hitn_1_n_f
c
      if(layer_1 .gt. 0 .and. mod(layer_1-layer,2) .ne. 0) then
        if(.not. check_azim_gap(
     &      hitn_1_n_f, inddat_dprs_1, hitn_2_l, inddat_dprs_2)) then
c
c   Azimuthal gap is to large. Combining will damage 3d t.c.
c
          combine_clusters = -1
          go to 111
        endif
      else if(layer_2 .gt. 0 .and. mod(layer_2-layer,2) .ne. 0) then
c
c   2nd t.c. is 3d one and has "next" layer cluster.
c   Check azimuth gap between hitn_1_l and hitn_2_n_f
c
        if(.not. check_azim_gap(
     &      hitn_1_l, inddat_dprs_1, hitn_2_n_f, inddat_dprs_2)) then
c
c   Azimuthal gap is to large. Combining will damage 3d t.c.
c
          combine_clusters = -1
          go to 111
        endif
      endif
c
c   Now when we are sure that combining will not damage possible 3d t.c.
c   let's start combining with checking azimuthal direction of movement and
c   azimuthal overlap of combining clusters
c   If at least one of the clusters has only 1 wire we do not need the
c   following checks of movement directions coincidence, but only overlaping 
c
      if (hitn_1_l-hitn_1_f .gt. 0 .and.
     &    hitn_2_l-hitn_2_f .gt. 0) then
c
c   Check the movement direction
c
        if(phi_dir_1 .ne. phi_dir_2) then
c
c   Different azimuth direction. 
c   Exit combining with unsuccessful return code
c
          combine_clusters = -1
          go to 111
        endif
        phi_dir = phi_dir_1
      else if (hitn_1_l-hitn_1_f .eq. 0 .and.
     &         hitn_2_l-hitn_2_f .eq. 0) then
c
c   Both t.c. has just single wires. Take azimuth direction of the movement
c   from previous step. 
c   
        if(phi_dir_cur_1 .ne. 0) then
          phi_dir = phi_dir_cur_1
        else if(phi_dir_cur_2 .ne. 0) then
          phi_dir = phi_dir_cur_2
        endif
      else
c
c   Only one t.c. has a single wire, but another has more than one. Define
c   azimuth direction for this other t.c.
c
        if (hitn_1_l-hitn_1_f .gt. 0) then
           phi_dir = phi_dir_1
        else
           phi_dir = phi_dir_2
        endif
      endif
c
c   Azimuth direction has been defined. 
c   Check now if t.c.'s overlap in azimuth
c
      if(phi_dir*(phi_1_c-PROX(phi_2_l,phi_1_c)) .gt. azimthal_gap
     &   .or.
     &   phi_dir*(phi_2_c-PROX(phi_1_l,phi_2_c)) .gt. azimthal_gap)
     &   then
c
c   No overlaping in azimuth.
c   Exit combining with unsuccessful return code
c
        combine_clusters = -1
        go to 111
      endif
c
c   The same direction in azimuth & overlaping
c   Proceed with combining, which at that point consists in putting ALL the
c   wires of layer clusters of both t.c. into combining buffer in RIGHT ODER
c
      cycle1 = hitn_1_f
      cycle2 = hitn_2_f
      n_w = 0
      do while (cycle1.le.hitn_1_l.and.cycle2.le.hitn_2_l.and.
     &          n_w.lt.10000)
c
c   We always start/continue at this point with current wires of both t.c.
c
         dhre_w_n = iw(inddat_dprs_1 + DPRLWI*(cycle1-1)+DPRIWI) 
         dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n-1)
         phi_1_c = TIDDP(layer) * (iw(dhre_pos + DHRWNR)-1)
         dhre_w_n = iw(inddat_dprs_2 + DPRLWI*(cycle2-1)+DPRIWI) 
         dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n-1)
         phi_2_c = TIDDP(layer) * (iw(dhre_pos + DHRWNR)-1)
c
c   Now, which wire should we save into buffer and which t.c. should we take
c   next wire from to proceed.
c
         if(phi_dir*(phi_1_c-PROX(phi_2_c,phi_1_c)) .lt. 0) then
c
c   phi_1_c < phi_2_c in a sence that it's before along the trajectory
c   Save current wire and take next one from 1st t.c. 
c
           n_w = n_w + 1
           combine_buffer(n_w)=
     &      iw(inddat_dprs_1 + DPRLWI*(cycle1-1)+DPRIWI)
           cycle1 = cycle1 + 1
         else
c
c   phi_2_c < phi_1_c 
c   Save current wire and take next one from 2nd t.c. 
c
           n_w = n_w + 1
           combine_buffer(n_w)=
     &      iw(inddat_dprs_2 + DPRLWI*(cycle2-1)+DPRIWI)
           cycle2 = cycle2 + 1
         endif
      enddo
c
c   The main loop is finished. There only two possibilites:
c       1. the buffer is full - nothing to do
c       2. one of t.c. clusters is over - 
c                 saved the rest of another, starting from its current wire
c                 but only in case if combining succeeded (n_w>0)      
c
      if(n_w.eq.0) then
        combine_clusters = -1
        go to 111
      endif
      if(n_w.lt.10000) then
        if(cycle1.le.hitn_1_l) then
c
c   2nd t.c. is over, save the rest of 1nd one
c
c********************************************** debugging only   
          if(cycle2.le.hitn_2_l) then  
            write (6,'(''  after combinning ..... cycle1,cycle2,n_w:'',
     &                3i10)') cycle1,cycle2,n_w
            stop
          endif
c********************************************** debugging only   

          do while (cycle1.le.hitn_1_l)
             n_w = n_w + 1
             combine_buffer(n_w)=
     &        iw(inddat_dprs_1 + DPRLWI*(cycle1-1)+DPRIWI)
             cycle1 = cycle1 + 1
          enddo
        else if(cycle2.le.hitn_2_l) then
c
c   1st t.c. is over, save the rest of 2nd one
c
c********************************************** debugging only   
          if(cycle1.le.hitn_1_l) then  
            write (6,'(''  after combinning ..... cycle1,cycle2,n_w:'',
     &                3i10)') cycle1,cycle2,n_w
            stop
          endif
c********************************************** debugging only   

          do while (cycle2.le.hitn_2_l)
             n_w = n_w + 1
             combine_buffer(n_w)=
     &        iw(inddat_dprs_2 + DPRLWI*(cycle2-1)+DPRIWI)
             cycle2 = cycle2 + 1
          enddo
        endif
      endif
      combine_clusters = n_w
  111 return 
      end
C===========================================================================
      integer function get_layer_cluster (
     &        nhits, cur_hit_n, inddat_dprs,
     &        cluster_layer)
$$IMPLICIT
      integer nhits, cur_hit_n, inddat_dprs,
     &        cluster_layer
C----------------------------------------------------------------------
C-
C-   Created   22-May-1996   Alexander Andryakov
C-
C-   Input :  
C-           nhits       -  total number of hits of the t.c.
C-           cur_hit_n   -  number of current hit of the t.c.
C-           inddat_dprs -  pointer to the beginning of the data block of DPRS
C-                          bank of the t.c.
C-   Output:
C-           cluster_layer  - layer number of the cluster
C-   Return :
C-           number in DPRS of the last wire of found cluster
C----------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DHRE.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
c
      INTEGER cycle,layer_c,dhre_w_n,dhre_pos,cluster_lenght
c
      dhre_w_n = iw(inddat_dprs + DPRLWI*(cur_hit_n-1)+DPRIWI)
      dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n-1)
      cluster_layer = iw(dhre_pos  + DHRSLR)
      cluster_lenght=1
      cycle = cur_hit_n
      do while (cycle .lt. nhits)
         cycle = cycle +1       
         dhre_w_n = iw(inddat_dprs + DPRLWI*(cycle-1)+DPRIWI)
         dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n-1)
         layer_c = iw(dhre_pos + DHRSLR)
         if(layer_c .ne. cluster_layer) go to 111
         cluster_lenght=cluster_lenght+1
      enddo
  111 get_layer_cluster=cur_hit_n+cluster_lenght-1
      return
      end
C===========================================================================
      integer function get_layer_supercluster (
     &        nhits, cur_hit_n, inddat_dprs,bound_layer,layer_dir,
     &        cluster_layer,same_layer_f)
$$IMPLICIT
      integer nhits, cur_hit_n, inddat_dprs,bound_layer,layer_dir,
     &        cluster_layer
      logical same_layer_f
C----------------------------------------------------------------------
C-
C-   Created   22-May-1996   Alexander Andryakov
C-
C-   Input :  
C-           nhits       - total number of hits of the t.c.
C-           cur_hit_n   - number of current hit of the t.c.
C-           inddat_dprs - pointer to the beginning of the data block of DPRS
C-                         bank of the t.c.
C-           bound_layer - layer number of the "next" cluster of other t.c.
C-           layer_dir   - layer direction of movement the t.c. piece 
C-   Output:
C-           cluster_layer  - layer number of the last cluster
C-           same_layer_f   - logical flag if the supercluster ends in the
C-                            bound_layer
C-   Return :
C-           number in DPRS of the last wire of found supercluster
C-           <0 if no supercluster extension has been found
C----------------------------------------------------------------------
c
      INTEGER get_layer_cluster
      INTEGER next,int_last,int_layer
c
      same_layer_f=.FALSE.
      get_layer_supercluster=-1
      next=cur_hit_n+1
      do while (next .le. nhits)
         int_last = get_layer_cluster(
     &              nhits,next,
     &              inddat_dprs,int_layer)
         if(bound_layer. eq. int_layer) then
            same_layer_f=.TRUE.
            get_layer_supercluster=next-1
            go to 111
         else if(layer_dir*(bound_layer - int_layer) .gt. 0) then
            cluster_layer = int_layer
            get_layer_supercluster=int_last
            next=int_last+1
         else 
            go to 111
         endif
      enddo
  111 return
      end
C===========================================================================
      integer function insert_inbetween(
     &        layer_1_c,layer_1_n,layer_2_c,
     &        inddat_dprs_1,nhits1,inddat_dprs_2,nhits2,
     &        hitn_1_c_f,hitn_1_c_l,hitn_1_n_f,hitn_1_n_l,
     &        hitn_2_c_f,hitn_2_c_l,
     &        num_w_saved,same_layer_f)
$$IMPLICIT
      integer
     &        layer_1_c,layer_1_n,layer_2_c,
     &        inddat_dprs_1,nhits1,inddat_dprs_2,nhits2,
     &        hitn_1_c_f,hitn_1_c_l,hitn_1_n_f,hitn_1_n_l,
     &        hitn_2_c_f,hitn_2_c_l,num_w_saved
      logical same_layer_f
C-----------------------------------------------------------------------
C-
C-   Created   29-May-1996   Alexander Andryakov
C-   
C-   Purpose: Inserts the layer cluster (or supercluster) of 2nd
C-            t.c. inbetween to clusters of 1st t.c. 
C-   *** Very important note : the numbering of t.c. is internal only
C-
C-   Input :  
C-           layer_1_c     - layer number of "current" cluster of 1st t.c.
C-           layer_1_n     - layer number of "next" cluster of 1st t.c.
C-           layer_2_c     - layer number of "current" cluster of 2nd t.c.
C-           inddat_dprs_1 \ pointer to the beginning of the hit list of DPRS
C-           inddat_dprs_2 / banks of 1st and 2nd t.c. respectevly
C-           nhits1        - total number of hits of the 1st t.c.
C-           nhits2        - total number of hits of the 2nd t.c.
C-           hitn_1_c_f    \ DHRE numbers of the 1st and the last hits in the 
C-           hitn_1_c_l    / "current" cluster of the 1st t.c.
C-           hitn_1_n_f    \ the same as above but for the "next" cluster
C-           hitn_1_n_l    /
C-           hitn_2_c_f    \ same as hitn_1_c_f,hitn_1_c_l but for 2nd t.c.
C-           hitn_2_c_l    /
C-           num_w_saved - total number of wires already saved into temporary
C-                         buffer of new merged t.c.
C-   Output :
C-           layer_2_c     - layer number of last hit of 2nd t.c. supercluster
C-           hitn_2_c_l    - last hit number of 2nd t.c. supercluster
C-           num_w_saved  - total number of wires saved into temporary buffer 
C-                          after the insertion
C-           same_layer_f - logical flag (TRUE if the last clusters are in the
C-                          same layer
C-   Return :
C-           -1 insertion failed
C-            0 insertion has been done as required
C-            1 special case of successful insertion, when the last cluster of 
C-              2nd t.c. supercluster and the "next" cluster of 1st t.c. are
C-              in the SAME LAYER
C----------------------------------------------------------------------
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
c
      INTEGER get_layer_cluster,get_layer_supercluster,
     &        combine_clusters,save_clust2buf
      LOGICAL check_azim_gap
c
      INTEGER int_first,interim_last,int_layer,
     &        hitn_for_comb_l,l_f_comb,
     &        n_comb_wires,combine_buffer(BUFF_LENGTH),cycle
c
      same_layer_f=.FALSE.
      interim_last=-1
c
c     First check what are the layer gaps between the current clusters of
c     different t.c. (1st connection)
c     
      if(abs(layer_1_c - layer_2_c) .le. LAYER_GAP) then
c
c     Layer gap of the first connection (1st cluster of 1st t.c. and
c     cluster of 2nd t.c.) is ok.
c     Check now azimuthal distance between last wire of 1st t.c. cluster
c     and first wire of 2nd t.c. cluster Azimuthal gap is not constant
c     and depends on the layer numbers. 
c
        if(check_azim_gap(hitn_1_c_l,inddat_dprs_1,
     &                    hitn_2_c_f,inddat_dprs_2)) then
c
c     Azimutal gap is ok. The 1st connection is established.
c     Now try establish 2nd connection, one between the last wire of the
c     cluster of the 2nd t.c. and the first wire of the 2nd cluster of
c     the 1st t.c.
c     First extend the current cluster of 2nd t.c. to supercluster
c
          if(hitn_2_c_l+1.le.nhits2) then
            int_first = hitn_2_c_l+1
            int_layer = layer_2_c
            interim_last = get_layer_supercluster(
     &                  nhits2,hitn_2_c_l,
     &                  inddat_dprs_2,layer_1_n,
     &                  layer_1_n-layer_1_c,
     &                  int_layer,same_layer_f)
          endif
c
c     Check if the last cluster of 2nd t.c. supercluster is in the same
c     layer with the "next" cluster of 1st t.c.
c
          if(same_layer_f) then
c
c     Combine the hits of the same layer clusters. If they are combined
c     successfully the insertion of the of the whole supercluster 
c     should be done.
c     Remember that if same_layer_f=.TRUE. the get_layer_supercluster function
c     returns results for supercluster WITHOUT this last cluster.
c     So first get this cluster.
c
            hitn_for_comb_l = get_layer_cluster(
     &              nhits2,interim_last+1,
     &              inddat_dprs_2,l_f_comb)
c
c     Then perform combining
c
            n_comb_wires=combine_clusters(
     &             hitn_1_n_f,hitn_1_n_l,inddat_dprs_1,nhits1,
     &             interim_last+1,hitn_for_comb_l,inddat_dprs_2,nhits2,
     &             combine_buffer)
            if(n_comb_wires.gt.0) then
c
c     The clusters of the same layer have been succsessfully combined.
c     Save  current clusters of 1st t.c., the whole supercluster of 2nd
c     t.c. and and the second cluster of 1st t.c.
c          1.Save current clusters of 1st into temporary buffer
c
              num_w_saved=save_clust2buf(
     &                    inddat_dprs_1,hitn_1_c_f,hitn_1_c_l,
     &                    num_w_saved)
c              
c          2.Save the whole supercluster of 2nd up to the last "same" layer
c            cluster 
c
              num_w_saved=save_clust2buf(
     &                    inddat_dprs_2,hitn_2_c_f,interim_last,
     &                    num_w_saved)

c              
c          3.Save combined cluster into temporary buffer
c
              cycle=1
              do while(cycle.le.n_comb_wires .and.
     &                 num_w_saved .lt. BUFF_LENGTH)
                 num_w_saved = num_w_saved +1
                 merge_buff(num_w_saved) = combine_buffer(cycle)
                 cycle = cycle + 1
              enddo
c
c          4.Set successful return code for and exit
c
              insert_inbetween=0
            else
c     Combining failed. Second connection is NOT established.
c     Set unsuccessful return code and exit
c  (
c     It's probably to firm logic, but it's used here as the first approach.
c     It can be loosened in the following way: if the above is not satisfied,
c     one can instead try to connect the previous cluster from supercluster
c     with the next cluster of partner t.c.. If the last is possible then the
c     whole supercluster will be inserted inbetween two clusters and the last
c     cluster of supercluster (that from "the same layer") will be dropped.
c  )
c
              insert_inbetween=-1
            endif
c
c     Redefine the upper boundary of supercluster of 2nd t.c.
c
            if(interim_last.gt.0) then
              hitn_2_c_l = hitn_for_comb_l
              layer_2_c = l_f_comb
            endif
*            go to 111
          else
c
c     The supercluster is in between the two clusters. 
c     Redefine the upper boundary of the current cluster of 2nd t.c. to that
c     of supercluster
c 
            if(interim_last.gt.0) then
              hitn_2_c_l = interim_last
              layer_2_c = int_layer
            endif
c
c     Check the second connection. Start with check of layer gap
c
            if(abs(layer_2_c - layer_1_n) .le. LAYER_GAP) then
c
c     Layer gap of the 2nd connection is ok.
c     Check now azimuthal gap
c
              if(check_azim_gap(hitn_2_c_l,inddat_dprs_2,
     &                          hitn_1_n_f,inddat_dprs_1)) then
c
c     Azimutal gap is ok. The 2nd connection is established.
c       1.Save current clusters of 1st & 2nd t.c. into temporary buffer
c
                num_w_saved=save_clust2buf(
     &                      inddat_dprs_1,hitn_1_c_f,hitn_1_c_l,
     &                      num_w_saved)
                num_w_saved=save_clust2buf(
     &                      inddat_dprs_2,hitn_2_c_f,hitn_2_c_l,
     &                      num_w_saved)
c
c       2.Set successful return code and exit
c
                insert_inbetween=0
*                go to 111
              else
c
c     Azimutal gap is too large. The 2nd connection is NOT established.
c     Set unsuccessful return code and exit
c
                insert_inbetween=-1
*                go to 111
              endif
            else
c
c     Layer gap is to large. The 2nd connection is NOT established.
c     Set unsuccessful return code and exit
c
              insert_inbetween=-1
*              go to 111
            endif
          endif
        else
c
c     Azimutal gap is to large. The 1st connection is NOT established.
c     Set unsuccessful return code and exit
c
          insert_inbetween=-1
*          go to 111
        endif
      else
c
c     Layer gap is to large. The 1st connection is NOT established.
c     Set unsuccessful return code and exit
c
        insert_inbetween=-1
*        go to 111
      endif
 111  return
      end
C===========================================================================
      logical function intersect_in_layer_phi(
     &        inddat_dprs1, inddat_dprs2)
$$IMPLICIT
      integer inddat_dprs1, inddat_dprs2
C----------------------------------------------------------------------
C-
C-   Created   24-Jun-1996   Alexander Andryakov
C-
C-   Input :  
C-           inddat_dprs1 -  pointer to the beginning of the data block of DPRS
C-                           bank of the 1st t.c.
C-           inddat_dprs2 -  the same as inddat_dprs1 but for the 2nd t.c.
C-   Return :
C-           result of check whether the regions of these 2 t.c. intersect  
C----------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$ITRK:CTIDRI.INC'
$$INCLUDE 'K$ITRK:CCONST.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
c
      INTEGER layer1_min,layer1_max,layer2_min,layer2_max,ltemp,
     &        layer_base, layer_baseu
      REAL    phi1_first,phi1_last,phi2_first,phi2_last,
     &        tan_stereo,azim_1,azim_2,azim_gap
c
      REAL A,B,PROX
      PROX(B,A)=B + PI2 * ANINT(0.15915494*(A-B))
c
      intersect_in_layer_phi = .FALSE.
c
c   Get layer boundaries of 1st t.c. region
c
      ltemp = mod(abs(iw(inddat_dprs1+DPRLRG)),10000)
      layer1_max = ltemp/100
      layer1_min = mod(ltemp,100)
c
c   Get layer boundaries of 2nd t.c. region
c
      ltemp=mod(abs(iw(inddat_dprs2+DPRLRG)),10000)
      layer2_max=ltemp/100
      layer2_min=mod(ltemp,100)
c
c   Check region "intersection" in layer dimension
c
      if(layer1_min-layer2_max .le. LAYER_GAP .and.
     &   layer2_min-layer1_max .le. LAYER_GAP) then
c
c     T.c. regions "intersect" in layer dimension
c     Check if they "intersect" in azimuth dimension
c       Get azimuthal boundaries of t.c.
c
        phi1_first = rw(inddat_dprs1+DPRPHF)
        phi1_last  = rw(inddat_dprs1+DPRPHL)
        phi2_first = rw(inddat_dprs2+DPRPHF)
        phi2_last  = rw(inddat_dprs2+DPRPHL)
        if(phi1_last .lt. -100. .or. phi2_last .lt. -100.) then
c
c     One of 2 t.c. occupy 2pi in azimuthal space
c
          intersect_in_layer_phi = .TRUE.
        else
c     
c       Calculate max allowed azimuthal gap
c         Get minimal value of upper layer boundaries of t.c.
c     
          layer_base = min (layer1_max,layer2_max)
c
c         Calculate max allowed azimuthal gap between layers:
c         layer_base and layer_base+LAYER_GAP (if layer_base equal to NLAYER
c         take layer_base-LAYER_GAP)
c
          if(layer_base .lt. NLAYER) then
            layer_baseu = layer_base + 1
          else
            layer_baseu = layer_base - 1
          endif
          tan_stereo=TIDST(layer_base)/TIDSC(layer_base)
          azim_1=atan(tan_stereo/sqrt((TIDRA(layer_base)/ZMAX)**2-
     &           tan_stereo**2))
          tan_stereo=TIDST(layer_baseu)/TIDSC(layer_baseu)
          azim_2=atan(tan_stereo/sqrt((TIDRA(layer_baseu)/ZMAX)**2-
     &           tan_stereo**2))
          azim_gap=abs(azim_1-azim_2)
c
c     Now check azimuthal "intersection"
c
          intersect_in_layer_phi =
     &         phi1_first - phi2_last       .le. azim_gap .or.
     &         phi1_first - phi2_last - PI2 .le. azim_gap
     &                           .or.
     &         phi2_first - phi1_last       .le. azim_gap .or.
     &         phi2_first - phi1_last - PI2 .le. azim_gap
        endif
      endif
      return
      end
C===========================================================================
      subroutine make_1st_pass_list(first_pass_list,list_length
     &                              ,merging_order) 
$$IMPLICIT
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
      real       first_pass_list(FPL_LNG_MAX,3)
      integer    list_length,merging_order(FPL_LNG_MAX)
C---------------------------------------------------------------------------
C-
C-   Created    7-Oct-1996   Alexander Andryakov
C-   
C     -   Purpose: Goes through all t.c. found by 1-view p.r. and 
C         bulds the merging order list of t.c. pairs for the 1st 
C         merging loop 
C-
C-   Output :
C-           first_pass_list - t.c. pairs list in the oreder of merging
C-                             (i,1) - "difference" order parameter      
C-                             (i,2) - itr of 1st view t.c.
C-                             (i,3) - itr of 2nd view t.c.
C-           list_length     - number of t.c. combinations in the list
C-           merging_order   - array of pointers to first_pass_list elements 
C-                             after ordering with SORTZV routine of CERNLIB
C---------------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$INC:ERLEVL.INC'
$$INCLUDE 'K$ITRK:CDTCUT.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DHRE.INC'
c
      LOGICAL intersect_in_layer_phi
c
      INTEGER inddat_dprs_1,itr1,inddat_dprs_2,itr2,view_n1,view_n2
      REAL    difference,curvature1,curvature2,qual1,qual2
c
c   LOOP over all t.c. Only t.c. from different stereo views and the
c     same sign of curvatures are discussed. 
c
      call vzero(first_pass_list,3*FPL_LNG_MAX)
      call vzero(merging_order,FPL_LNG_MAX)
      list_length=0
      itr1=1
      do while(itr1 .lt. first_itr2 .and. 
     &         inddat_dprs_array(itr1) .gt. 0 .and.
     &         list_length .lt. FPL_LNG_MAX) 
         inddat_dprs_1=inddat_dprs_array(itr1)
c
c      Get curvature and view number of current t.c.
c
         curvature1= rw(inddat_dprs_1+DPRCUR)
************************************************* debug only ***** beg
         view_n1   = iw(inddat_dprs_1+DPRPOK)
         if(view_n1 .ne. 1) then
           write (6,'('' view_n1 = '',i10)') view_n1
           stop
         endif
************************************************* debug only ***** end
         qual1 = rw(inddat_dprs_1+DPRQUA)
c
c     Locate now all other t.c. of another view, check them one by one
c     if they have appropriate sign of curvature and view number and see
c     difference in curvatures 
c 
         itr2 = first_itr2
         do while(itr2 .le. last_itr2 .and. 
     &            inddat_dprs_array(itr2) .gt. 0 .and.
     &            list_length .lt. FPL_LNG_MAX) 
           inddat_dprs_2=inddat_dprs_array(itr2)
c
c      Get curvature and view number of next t.c.
c
           curvature2= rw(inddat_dprs_2+DPRCUR)
************************************************* debug only ***** beg
           view_n2   = iw(inddat_dprs_2+DPRPOK)
           if(view_n2 .ne. 2) then
             write (6,'('' view_n2 = '',i10)') view_n2
             stop
           endif
************************************************* debug only ***** end
c
c      Check whether these two t.c. are from different views 
c                         and 
c            whether their curvatures are of the same sign
c                         and 
c            whether they occupy intersecting regions in layer-phi space
c
           if(curvature1 * curvature2 .gt. 0. .and.
     &        intersect_in_layer_phi(inddat_dprs_1,inddat_dprs_2)) then
c
c     Build what serves as measure of how these t.c. are unlike to each
c     other
c
             qual2 = rw(inddat_dprs_2+DPRQUA)
c             difference = abs(curvature1-curvature2) +
c     &                    abs(qual1 - qual2)
             difference = 2.*abs(curvature1-curvature2)/
     &                       abs(curvature1+curvature2) +
     &                    2.*abs(qual1 - qual2)/abs(qual1 + qual2)
c
c     Put these pair of t.c. with their "difference" value into list
c
             list_length = list_length + 1
             first_pass_list(list_length,1) = difference
             first_pass_list(list_length,2) = float(itr1)
             first_pass_list(list_length,3) = float(itr2)
           endif
c
c     Take next t.c. in the second stereo view
c
           itr2 = itr2 + 1
         enddo
c
c     Take next t.c. in the first stereo view
c
         itr1 = itr1 + 1
       enddo
c
c     Sort list in ascending order of "difference" value
c
       call SORTZV(first_pass_list(1,1),merging_order,list_length,1,0,0)
       return
       end
C===========================================================================
      subroutine merge_1_into_2(
     &            itr1,nhits1,inddat_dprs_1,
     &            hitn_1_c_f,hitn_1_c_l,layer_1_c,
     &            itr2,nhits2,inddat_dprs_2,
     &            hitn_2_c_f,hitn_2_c_l,layer_2_c,
     &            hitn_2_n_f,hitn_2_n_l,layer_2_n)
$$IMPLICIT
      integer 
     &            itr1,nhits1,inddat_dprs_1,
     &            hitn_1_c_f,hitn_1_c_l,layer_1_c,
     &            itr2,nhits2,inddat_dprs_2,
     &            hitn_2_c_f,hitn_2_c_l,layer_2_c,
     &            hitn_2_n_f,hitn_2_n_l,layer_2_n
C-----------------------------------------------------------------------
C-
C-   Created   31-May-1996   Alexander Andryakov
C-   
C-   Purpose: Merge 1st t.c. into 2nd one.  
C-            1st t.c. is always a single layer t.c.
C-   Input :  
C-           itr1          \ DPRS bank nubmers of both t.c.
C-           itr2          / 
C-           layer_1_c     - layer number of "current" cluster of 1st t.c.
C-           layer_2_c     - layer number of "current" cluster of 2nd t.c.
C-           layer_2_n     - layer number of "next" cluster of 2nd t.c.
C-           inddat_dprs_1 \ pointer to the beginning of the hit list of DPRS
C-           inddat_dprs_2 / banks of 1st and 2nd t.c. respectevly
C-           nhits1        \ total number of hits of 
C-           nhits2        / both t.c.
C-           hitn_1_c_f    \ DHRE numbers of the 1st and the last hits in the 
C-           hitn_1_c_l    / "current" cluster of the 1st t.c.
C-           hitn_2_c_f    \ same as hitn_1_c_f,hitn_1_c_l but for 2nd t.c.
C-           hitn_2_c_l    /
C-           hitn_2_n_f    \ the same as above but for the "next" cluster
C-           hitn_2_n_l    /
C----------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DHRE.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
C
      INTEGER get_layer_cluster,combine_clusters,
     &        insert_inbetween,modify_DPRS_DHRE
c
      INTEGER 
     &        num_w_saved,insert_status,layer_dir_2,
     &        n_comb_wires,combine_buffer(BUFF_LENGTH),cycle
      LOGICAL same_layer_f
c
      layer_dir_2 = layer_2_n - layer_2_c
      num_w_saved=0
c
c   Check if 1st t.c. should be really merged into the second one.
c
      if(layer_dir_2*(layer_2_c-layer_1_c) .lt. 0) then
c
c   1st t.c. is AFTER "current" cluster of 2nd t.c.
c
c   Loop over wires/clusters of 2nd t.c. (hit lists merging) to find two
c   cluster between which 1st t.c. should be inserted
c
        do while (hitn_2_c_f .le. nhits2)
c
c   Check if the 1st t.c. is BEFORE "next" cluster of 2nd t.c.
c
          if(layer_dir_2*(layer_2_n-layer_1_c) .ge. 0) then
c
c     Layer condition is satisfied. 1st t.c. is in between 2
c     adjacent clusters of 2nd t.c. Try to insert it between them.
c
            insert_status = insert_inbetween( 
     &                    layer_2_c,layer_2_n,layer_1_c,
     &                    inddat_dprs_2,nhits2,inddat_dprs_1,nhits1,
     &                    hitn_2_c_f,hitn_2_c_l,hitn_2_n_f,hitn_2_n_l,
     &                    hitn_1_c_f,hitn_1_c_l,
     &                    num_w_saved,same_layer_f)

            if(insert_status.lt.0) then
c
c     Insertion failed. Only if 2nd t.c. changes its movement direction it
c     can have another pair of adjacent clusters sutisfying the above criteria
c
              if(iw(inddat_dprs_2-DPRCEN+DPRLRG) .gt. 0) go to 111
            else
c
c     Insertion scceeded. Enlarge DPRS of the 2nd t.c., modify it and exit
c
              if(same_layer_f) then
c
c     "next" cluster of 2nd t.c. has been saved to merging buffer
c
                call modify_DPRS_DHRE(
     &               itr2,nhits2,inddat_dprs_2,hitn_2_c_f-1,
     &               itr2,nhits2,inddat_dprs_2,hitn_2_n_l+1,
     &               num_w_saved,itr1,nhits1,inddat_dprs_1)
              else
c
c     "next" cluster of 2nd t.c. has NOT been saved to merging buffer
c
                call modify_DPRS_DHRE(
     &               itr2,nhits2,inddat_dprs_2,hitn_2_c_f-1,
     &               itr2,nhits2,inddat_dprs_2,hitn_2_n_f,
     &               num_w_saved,itr1,nhits1,inddat_dprs_1)
              endif
              go to 111
            endif
          else
c
c     Layer condition is not satisfied. Go to next cluster of 2nd t.c.
c     Which means
c        1. redefine "next" cluster of the 2nd t.c. as "current" one
c        2. take new cluster of the 2nd t.c. as "next"
c        3. continue main loop
c
            hitn_2_c_f =  hitn_2_n_f                   
            hitn_2_c_l =  hitn_2_n_l                   
            layer_2_c = layer_2_n
            hitn_2_n_f = hitn_2_c_l+1    
            if(hitn_2_n_f.le.nhits2) then
               hitn_2_n_l = get_layer_cluster(
     &                  nhits2,hitn_2_n_f,
     &                  inddat_dprs_2,layer_2_n)
            endif                     
          endif
        enddo
      else if(layer_dir_2*(layer_2_c-layer_1_c) .eq. 0) then
c
c   Both t.c. have clusters in the same layer. Combine this clusters in one
c
        n_comb_wires=combine_clusters(
     &                hitn_1_c_f,hitn_1_c_l,inddat_dprs_1,nhits1,
     &                hitn_2_c_f,hitn_2_c_l,inddat_dprs_2,nhits2,
     &                combine_buffer)
        if(n_comb_wires.gt.0) then
c
c   Combining succeeded. 
c   Save combined cluster into merging buffer
c
          cycle=1
          do while(cycle.le.n_comb_wires)
             merge_buff(cycle) = combine_buffer(cycle)
             cycle = cycle + 1
          enddo
c              
c   Enlarge DPRS of the 2nd t.c., modify it and exit
c
                call modify_DPRS_DHRE(
     &               itr2,nhits2,inddat_dprs_2,0,
     &               itr2,nhits2,inddat_dprs_2,hitn_2_n_f,
     &               num_w_saved,itr1,nhits1,inddat_dprs_1)
          go to 111
        else
c
c     Combining failed. Only if 2nd t.c. changes its movement direction it
c     can have another pair of adjacent clusters sutisfying the above criteria
c
          if(iw(inddat_dprs_2-DPRCEN+DPRLRG) .gt. 0) go to 111
        endif
c      else
c
c   1st t.c. is BEFORE "current" cluster of 2nd t.c., but within LAYER_GAP
c   (otherwise this routine is never called). Check azimuth direction and gap
c   and either merge these t.c. or leave this routine.
c   It's not an overlaping of t.c., so at best we can have only one connection
c   and only one z-measurement. It's not sufficient to  start track fit and in
c   this sence the merged t.c. will not be really 3-d.
c   For a moment such t.c. are net merged
c
      endif
  111 return
      end
C===========================================================================
      subroutine merge_2_tc(
     &           itr1,inddat_dprs_1i,itr2,inddat_dprs_2i)
$$IMPLICIT
      integer itr1,inddat_dprs_1i,itr2,inddat_dprs_2i
C-----------------------------------------------------------------------
C-
C-   Created   20-May-1996   Alexander Andryakov
C-   
C-   Purpose: Merge 2 t.c.
C-
C-   Input :  
C-           itr1           \ DPRS bank numbers of both t.c.
C-           itr2           /
C-           inddat_dprs_1i \ pointer to the beginning of the data block of 
C-           inddat_dprs_2i / DPRS banks of 1st and 2nd t.c. respectevly
C-   Output :
C----------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DHRE.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
c
      INTEGER get_layer_cluster,save_clust2buf,combine_clusters,
     &        insert_inbetween, modify_DPRS_DHRE
      LOGICAL check_azim_gap
c
      INTEGER 
     &        nhits1,nhits2,view_n1,view_n2,
     &        inddat_dprs_1,inddat_dprs_2,
     &        hitn_1_c_f,hitn_1_c_l,hitn_1_n_f,hitn_1_n_l,
     &        hitn_2_c_f,hitn_2_c_l,hitn_2_n_f,hitn_2_n_l,
     &        layer_1_c,layer_1_n,layer_2_c,layer_2_n,
     &        num_w_saved,insert_status,layer_dir_1,layer_dir_2,
     &        work_l,
     &        itr_save,nhits_save,inddat_dprs_save,hitn_save_l,
     &        itr_rest,nhits_rest,inddat_dprs_rest,hitn_rest_f,
     &        itr_drop,nhits_drop,inddat_dprs_drop,
     &        n_comb_wires,combine_buffer(BUFF_LENGTH),cycle
      LOGICAL same_layer_f
c
c   Some preparations
c
      nhits1 = iw(inddat_dprs_1i+DPRPOS) + iw(inddat_dprs_1i+DPRNEG)
      nhits2 = iw(inddat_dprs_2i+DPRPOS) + iw(inddat_dprs_2i+DPRNEG)
      view_n1= iw(inddat_dprs_1i+DPRPOK)
      view_n2= iw(inddat_dprs_2i+DPRPOK)
      inddat_dprs_1 = inddat_dprs_1i + DPRCEN
      inddat_dprs_2 = inddat_dprs_2i + DPRCEN
      if(view_n1 .eq. 3) then
        itr_rest = itr1
        nhits_rest = nhits1
        inddat_dprs_rest = inddat_dprs_1
      else if(view_n2 .eq. 3) then
        itr_rest = itr2
        nhits_rest = nhits2
        inddat_dprs_rest = inddat_dprs_2
      endif
      if(nhits1 .ge. nhits2) then
         itr_save=itr1
         nhits_save=nhits1
         inddat_dprs_save=inddat_dprs_1
         itr_drop=itr2
         nhits_drop=nhits2
         inddat_dprs_drop=inddat_dprs_2
      else
         itr_save=itr2
         nhits_save=nhits2
         inddat_dprs_save=inddat_dprs_2
         itr_drop=itr1
         nhits_drop=nhits1
         inddat_dprs_drop=inddat_dprs_1
      endif
      hitn_save_l=0
      num_w_saved=0
      n_comb_wires=0
      insert_status=-10
c
c   Get two 1st clusters of both t.c. and define layer direction of movement
c
      hitn_1_c_f = 1     
      hitn_1_c_l = get_layer_cluster(nhits1,hitn_1_c_f,
     &               inddat_dprs_1,layer_1_c)
      hitn_2_c_f = 1     
      hitn_2_c_l = get_layer_cluster(nhits2,hitn_2_c_f,
     &               inddat_dprs_2,layer_2_c)
      hitn_1_n_f = hitn_1_c_l+ 1     
      if(hitn_1_n_f .le. nhits1) then
        hitn_1_n_l = get_layer_cluster(nhits1,hitn_1_n_f,
     &                 inddat_dprs_1,layer_1_n)
        layer_dir_1 = layer_1_n - layer_1_c
      else
        layer_dir_1 = 0
      endif
      hitn_2_n_f = hitn_2_c_l + 1     
      if(hitn_2_n_f .le. nhits2) then
        hitn_2_n_l = get_layer_cluster(nhits2,hitn_2_n_f,
     &                 inddat_dprs_2,layer_2_n)
        layer_dir_2 = layer_2_n - layer_2_c
      else
        layer_dir_2 = 0
      endif
c
c   Check if both t.c. have the same layer direction (or at least their pieces)
c
      if(layer_dir_2*layer_dir_1 .lt. 0) then
c
c   Layer directions at the beginning of t.c. are different
c   Check if one or both t.c. change layer direction of movement
c
        if(iw(inddat_dprs_1i+DPRLRG) .gt. 0 .and.
     &     iw(inddat_dprs_2i+DPRLRG) .gt. 0) then
c
c   Neither of 2 t.c. changes layer direction. T.c. cannot be merged.
c 
          go to 112
        else
c
c   At least one of t.c. changes direction. So there is a hope that its piece
c   of other direction can be merge with other t.c.
c
          call adjust_layer_directions(
     &            nhits1,inddat_dprs_1,
     &            hitn_1_c_f,hitn_1_c_l,layer_1_c,layer_dir_1,
     &            nhits2,inddat_dprs_2,
     &            hitn_2_c_f,hitn_2_c_l,layer_2_c,layer_dir_2)
        endif
      else if(layer_dir_2*layer_dir_1 .eq. 0) then
c
c   At least one t.c. is 1 layer t.c.. 
c   We do not need to go through the main merging loop. Simplear merging will
c   be performed.
c   Find which one and merge it into another
c
        if(layer_dir_1 .eq. 0 .and. layer_dir_2 .eq. 0) then
c
c      Both t.c. are single layer t.c.
c      If it's not a turning region of the track, these t.c. will not produce
c      a really 3-d t.c., since there can be only one connection between
c      layers of different stereo views and therefore only 1 z-measurement.
c      So it's pointless to merge them, apart from the cases when there are
c      many single layer t.c. of one track and merging all of them can produce
c      really 3-d t.c. I think it's very rear case and probably it should be
c      done during one view merging (or one view t.c. extension)
c      Second case when an attempt to merge 2 single layer t.c. should be done
c      is the case of turning region. In this case one of t.c. can have a
c      big azinuth gap and represent two pieces of track. So second
c      t.c. should be inserted between two, let's say azimuth, clusters of
c      first one. 
c      I do not realize this for a moment, before check how important it is
c
          go to 112
        else if(layer_dir_1 .eq. 0) then
c
c      1st t.c. is a single layer t.c.
c      Check if it can be merged into 2nd t.c.
c
          if(layer_dir_2*(layer_2_c-layer_1_c) .le. LAYER_GAP)
c
c      1st t.c. is before the begining of 2nd t.c. but within layer gap.
c      Try to merge
c
     &       call merge_1_into_2(
     &            itr1,nhits1,inddat_dprs_1,
     &            hitn_1_c_f,hitn_1_c_l,layer_1_c,
     &            itr2,nhits2,inddat_dprs_2,
     &            hitn_2_c_f,hitn_2_c_l,layer_2_c,
     &            hitn_2_n_f,hitn_2_n_l,layer_2_n)
c
c      Then no matter what is the result exit
c
          go to 112
        else if(layer_dir_2 .eq. 0) then
c
c      2nd t.c. is a single layer t.c.
c      Check if it can be merged into 2nd t.c.
c
          if(layer_dir_1*(layer_1_c-layer_2_c) .le. LAYER_GAP)
c
c      2nd t.c. is before the begining of 1st t.c. but within layer gap.
c      Try to merge
c
     &       call merge_1_into_2(
     &            itr2,nhits2,inddat_dprs_2,
     &            hitn_2_c_f,hitn_2_c_l,layer_2_c,
     &            itr1,nhits1,inddat_dprs_1,
     &            hitn_1_c_f,hitn_1_c_l,layer_1_c,
     &            hitn_1_n_f,hitn_1_n_l,layer_1_n)
c
c      Then no matter what is the result exit
c
          go to 112
        endif
      endif
c
c  2. Loop over wires/clusters of 1st & 2nd t.c. (hit lists merging)
c
      do while (hitn_1_c_f .le. nhits1 .and. 
     &          hitn_2_c_f .le. nhits2)
c
c  The t.c. with > 1 layer are used in this loop
c  It's also supposed that they are positioned at beginning of pieces of the
c  same layer direction
c
c  Find which of the 2 clusters of 2 t.c. has smallest R (biggest layer #)  
c
        if(layer_dir_1*(layer_1_c-layer_2_c) .lt. 0) then
c
c     "Current" cluster of 1st t.c. is inner than that of 2nd t.c.
c     Take next layer cluster of 1st t.c. and check if current cluster
c     of 2nd t.c. is in between.
c
          hitn_1_n_f = hitn_1_c_l+1    
          if(hitn_1_n_f.le.nhits1) then
            hitn_1_n_l = get_layer_cluster(nhits1,hitn_1_n_f,
     &                    inddat_dprs_1,layer_1_n)
            layer_dir_1=layer_1_n-layer_1_c
          else
c
c     One layer cluster remains in 1st t.c. We have almost done the job.
c     Check what happens with previous clusters
c
            if(insert_status .eq. 0) then
c
c     Insertion/Combining of most previous clusters succeeded.
c     Merging is in progress. Check layer and azimuth gaps between two current
c     clusters
c 
              if(abs(layer_1_c - layer_2_c) .le. LAYER_GAP) then
c
c     Layer gap between "current" clusters is ok
c     Check now azimuthal distance between last wire of 1st t.c. cluster
c     and first wire of 2nd t.c. cluster Azimuthal gap is not constant
c     and depends on the layer numbers. 
c
                if(check_azim_gap(hitn_1_c_l,inddat_dprs_1,
     &                            hitn_2_c_f,inddat_dprs_2)) then
c
c     Azimutal gap is ok. Connection is established.
c     We should save into merging buffer "current" cluster of 1st t.c and copy
c     into modified DPRS the rest of 2nd t.c. starting with hitn_2_c_f
c
                  num_w_saved=save_clust2buf(
     &                        inddat_dprs_1,hitn_1_c_f,hitn_1_c_l,
     &                        num_w_saved)
                  hitn_rest_f = hitn_2_c_f
                  itr_rest = itr2
                  nhits_rest = nhits2
                  inddat_dprs_rest = inddat_dprs_2
                else
c
c     Azimutal gap requirement is NOT satisfied.
c     Connection is NOT established.
c     The "rest" for modifying DPRS is "current" cluster of 1st t.c.
c
                  hitn_rest_f = hitn_1_c_f
                  itr_rest = itr1
                  nhits_rest = nhits1
                  inddat_dprs_rest = inddat_dprs_1
                endif
              else
c
c     Layer gap requirement is NOT satisfied.
c     Connection is NOT established
c     The "rest" for modifying DPRS is "current" cluster of 1st t.c.
c
                  hitn_rest_f = hitn_1_c_f
                  itr_rest = itr1
                  nhits_rest = nhits1
                  inddat_dprs_rest = inddat_dprs_1
              endif
c            else
c
c     The merging failed shortly before these two clusters.
c     In the present code it's impossible, since this case is treated at the
c     moment when insertiona fails.
c
c              if(num_w_saved.gt.0) then
c
c     Some pieces of t.c. have been merged. Update the DPRS end exit
c
c              endif
            endif
c
c     Modify DPRS and exit
c
            go to 111
          endif
c
c     We have "next" cluster of 1st t.c.. Check it for second connection
c
          if(layer_dir_1*(layer_1_n-layer_2_c) .gt. 0) then
c
c     Layer condition is satisfied. Cluster of 2nd t.c. is in between 2
c     adjacent clusters of 1st t.c. Try to insert it between them.
c
            insert_status = insert_inbetween( 
     &                    layer_1_c,layer_1_n,layer_2_c,
     &                    inddat_dprs_1,nhits1,inddat_dprs_2,nhits2,
     &                    hitn_1_c_f,hitn_1_c_l,hitn_1_n_f,hitn_1_n_l,
     &                    hitn_2_c_f,hitn_2_c_l,
     &                    num_w_saved,same_layer_f)
            if(insert_status .lt. 0 .and. num_w_saved .gt. 0) then
c
c     Insertion failed and something has been already saved into merging
c     buffer this means that t.c. are merged up to this point. Stop merging. 
c     Modify DPRS by copying merging buffer and the rest of t.c., "current"
c     cluster of which was used as "next" at previous insertion step (in
c     other words this cluster has been already checked on having connection)
c     The "rest" quantaies have been already defined at the previous merging
c     stage 
c
              go to 111
            endif
c
c     Nothing has been already saved into merging buffer or insertion succeeded
c     continue procedure. 
c
            if(same_layer_f) then
c
c     The only important thing after insertion attempt is whether 
c     the "next" cluster of 1st t.c. and the last one of possible
c     supercluster of the 2nd t.c. are in the same layer or not.
c
c     The "next" cluster of 1st t.c. and the last one of possible
c     supercluster of the 2nd t.c. are IN THE SAME layer,
c
c        1. take new clusters of both t.c. as "current" 
c
              hitn_1_c_f = hitn_1_n_l+1    
              if(hitn_1_c_f.le.nhits1) then
                 hitn_1_c_l = get_layer_cluster(
     &                    nhits1,hitn_1_c_f,
     &                    inddat_dprs_1,work_l)
                 layer_dir_1=work_l-layer_1_c
                 layer_1_c=work_l
              endif
              hitn_2_c_f = hitn_2_c_l+1    
              if(hitn_2_c_f.le.nhits2) then
                 hitn_2_c_l = get_layer_cluster(
     &                    nhits2,hitn_2_c_f,
     &                    inddat_dprs_2,work_l)
                 layer_dir_2=work_l-layer_2_c
                 layer_2_c=work_l
              endif
c
c     There is a question in this case : how to proceed with modification of 
c     DPRS banks if merging stops at this step (attempt to merge next clusters
c     will fail). Namely,the hits of which of two t.c. should be copied as the
c     rest into the DPRS bank of new 3d t.c. In contrast to real insertion of
c     the wire cluster between to others, in combining the clusters are in the 
c     same layer, so there is no preference (in case of combining failure)
c     which of 2 t.c. shoud be taken to be the end of new 3d candidate.
c     I would like to stress that the logic of this merging scheme imply that
c     one of t.c. is a 3d t.c. and another is 1-view t.c.. It seems to me more
c     reasonable to keep alive already merged 3d and kill the rest of 1-view
c     t.c.
c     Of course, this considerations have a sence only if both t.c.
c     have "next" clusters. Otherwise the "rest" t.c. is obvious.
c
              if(hitn_1_c_f.le.nhits1 .and. hitn_2_c_f.le.nhits2) then
c
c     Both t.c. have NOT reacehed their ends
c
                if(view_n1 .eq. 3) then
c
c     1st t.c. is 3d one. The "rest" for modifying DPRS starts at
c     "current" cluster of 1st t.c. 
c
                  hitn_rest_f = hitn_1_c_f
                  itr_rest = itr1
                  nhits_rest = nhits1
                  inddat_dprs_rest = inddat_dprs_1
                else if(view_n2 .eq. 3) then
c
c     2nd t.c. is 3d one. The "rest" for modifying DPRS starts at
c     "current" cluster of 2nd t.c. 
c
                  hitn_rest_f = hitn_2_c_f
                  itr_rest = itr2
                  nhits_rest = nhits2
                  inddat_dprs_rest = inddat_dprs_2
                endif
              else if(hitn_1_c_f.le.nhits1) then
c
c     2nd t.c. ends at "current" cluster. The "rest" for modifying DPRS
c     starts at "current" cluster of 1st t.c.
c
                hitn_rest_f = hitn_1_c_f
                itr_rest = itr1
                nhits_rest = nhits1
                inddat_dprs_rest = inddat_dprs_1
              else if(hitn_2_c_f.le.nhits2) then
c
c     1st t.c. ends at "current" cluster. The "rest" for modifying DPRS
c     starts at "current" cluster of 2nd t.c.
c
                hitn_rest_f = hitn_2_c_f
                itr_rest = itr2
                nhits_rest = nhits2
                inddat_dprs_rest = inddat_dprs_2
              else
c
c     Both t.c. have reacehed their ends. There is NO any "rest's" to
c     save in modifying DPRS. To be coinsistent with the logic of the
c     modify_DPRS_DHRE routine let's use as the rest 1st t.c. and define
c     hitn_rest_f to be out of the hit range of the 1st t.c.
c
                itr_rest = itr1
                nhits_rest = nhits1
                hitn_rest_f = nhits_rest +1
                inddat_dprs_rest = inddat_dprs_1
              endif
            else
c
c     The "next" cluster of 1st t.c. and the last one of possible
c     supercluster of the 2nd t.c. are NOT in the same layer,
c        1. redefine "next" cluster of the 1st t.c. as "current" one
c        2. define "current" cluster of 1st t.c. as the beginning of hit list
c           to be saved after merging buffer in modified DPRS
c        3. take new cluster of the 2nd t.c. as "current" 
c
              hitn_1_c_f = hitn_1_n_f                   
              hitn_1_c_l = hitn_1_n_l                   
              layer_1_c  = layer_1_n
c
              hitn_rest_f = hitn_1_c_f
              itr_rest = itr1
              nhits_rest = nhits1
              inddat_dprs_rest = inddat_dprs_1
c
              hitn_2_c_f = hitn_2_c_l+1    
              if(hitn_2_c_f.le.nhits2) then
                 hitn_2_c_l = get_layer_cluster(
     &                    nhits2,hitn_2_c_f,
     &                    inddat_dprs_2,work_l)
                 layer_dir_2=work_l-layer_2_c
                 layer_2_c=work_l
              endif                     
            endif
          else if(layer_dir_1*(layer_1_n-layer_2_c) .lt. 0) then
c
c     "next" layer cluster of 1st t.c. is also before than "current" cluster
c     of 2nd t.c.. Extend "current" cluster of 1st t.c. to supercluster by
c     adding to it its "next" cluster and continue loop over wires/clusters 
c
c     This scheme should be improved for t.c. which change their movement
c     direction 
c
            hitn_1_c_l = hitn_1_n_l
            layer_1_c  = layer_1_n
          else if(layer_1_n .eq. layer_2_c) then
c
c     "next" cluster of 1st t.c. and "current" one of 2nd t.c. are in the same
c     layer. 
c     1. Save into merging buffer "current" cluster of 1st t.c.. (only
c        in case when isertion/combining of the previous clusters has
c        succeeded)  
c     2. Redefine "next" cluster of 1st t.c. as "current" and go to the
c        beginning of cluster loop. (the case of combining two clusters of the
c        same layer will be treated correctly). 
c     3. The "rest" for modifying DPRS is "next" cluster of 1st t.c. 
c
            if(insert_status .ge. 0 .or. n_comb_wires .gt.0) then
              num_w_saved=save_clust2buf(
     &                    inddat_dprs_1,hitn_1_c_f,hitn_1_c_l,
     &                    num_w_saved)
            else
c
c     Special case of combining. One of t.c. obviously starts closer to
c     interaction region than another. We should redefine "to be saved"
c     and "to be dropped" t.c. in a such way that one with greater
c     layer number of the first cluster to be saved and another to be
c     dropped. 
c
              hitn_save_l= hitn_1_c_l
              itr_save = itr1
              nhits_save = nhits1
              inddat_dprs_save = inddat_dprs_1
              itr_drop=itr2
              nhits_drop=nhits2
              inddat_dprs_drop=inddat_dprs_2
            endif
c                  
            hitn_1_c_f = hitn_1_n_f                   
            hitn_1_c_l = hitn_1_n_l                   
            layer_1_c  = layer_1_n
c
            hitn_rest_f = hitn_1_n_f
            itr_rest = itr1
            nhits_rest = nhits1
            inddat_dprs_rest = inddat_dprs_1
          endif
        else if(layer_dir_2*(layer_2_c-layer_1_c) .lt. 0) then
c
c     "Current" cluster of 2nd t.c. is inner than that of 1st t.c.
c     Take next layer cluster of 2nd t.c. and check if current cluster
c     of 1st t.c. is in between.
c
          hitn_2_n_f = hitn_2_c_l+1    
          if(hitn_2_n_f.le.nhits2) then
            hitn_2_n_l = get_layer_cluster(nhits2,hitn_2_n_f,
     &                    inddat_dprs_2,layer_2_n)
            layer_dir_2=layer_2_n-layer_2_c
          else
c
c     One layer cluster remains in 2nd t.c. We have almost done the job.
c     Check what happens with previous clusters
c
            if(insert_status .eq. 0) then
c
c     Insertion/Combining of most previous clusters succeeded.
c     Merging is in progress. Check layer and azimuth gaps between two current
c     clusters
c 
              if(abs(layer_1_c - layer_2_c) .le. LAYER_GAP) then
c
c     Layer gap between "current" clusters is ok
c     Check now azimuthal distance between last wire of 2nd t.c. cluster
c     and first wire of 1st t.c. cluster Azimuthal gap is not constant
c     and depends on the layer numbers. 
c
                if(check_azim_gap(hitn_2_c_l,inddat_dprs_2,
     &                            hitn_1_c_f,inddat_dprs_1)) then
c
c     Azimutal gap is ok. Connection is established.
c     We should save into merging buffer "current" cluster of 2nd t.c and copy
c     into modified DPRS the rest of 1st t.c. starting with hitn_1_c_f
c
                  num_w_saved=save_clust2buf(
     &                        inddat_dprs_2,hitn_2_c_f,hitn_2_c_l,
     &                        num_w_saved)
                  hitn_rest_f = hitn_1_c_f
                  itr_rest = itr1
                  nhits_rest = nhits1
                  inddat_dprs_rest = inddat_dprs_1
                else
c
c     Azimutal gap requirement is NOT satisfied.
c     Connection is NOT established.
c     The "rest" for modifying DPRS is "current" cluster of 2nd t.c.
c
                  hitn_rest_f = hitn_2_c_f
                  itr_rest = itr2
                  nhits_rest = nhits2
                  inddat_dprs_rest = inddat_dprs_2
                endif
              else
c
c     Layer gap requirement is NOT satisfied.
c     Connection is NOT established
c     The "rest" for modifying DPRS is "current" cluster of 2nd t.c.
c
                  hitn_rest_f = hitn_2_c_f
                  itr_rest = itr2
                  nhits_rest = nhits2
                  inddat_dprs_rest = inddat_dprs_2
              endif
c            else
c
c     The merging failed shortly before these two clusters.
c     In the present code it's impossible, since this case is treated at the
c     moment when insertiona fails.
c
c              if(num_w_saved.gt.0) then
c
c     Some pieces of t.c. have been merged. Update the DPRS end exit
c
c              endif
            endif
c
c     Modify DPRS and exit
c
            go to 111
          endif
c
c     We have "next" cluster of 2nd t.c.. Check it for second connection
c
          if(layer_dir_2*(layer_2_n-layer_1_c) .gt. 0) then
c
c     Layer condition is satisfied. Cluster of 1st t.c. is in between 2
c     adjacent clusters of 2nd t.c. Try to insert it between them.
c
            insert_status = insert_inbetween( 
     &                    layer_2_c,layer_2_n,layer_1_c,
     &                    inddat_dprs_2,nhits2,inddat_dprs_1,nhits1,
     &                    hitn_2_c_f,hitn_2_c_l,hitn_2_n_f,hitn_2_n_l,
     &                    hitn_1_c_f,hitn_1_c_l,
     &                    num_w_saved,same_layer_f)
            if(insert_status .lt. 0 .and. num_w_saved .gt. 0) then
c
c     Insertion failed and something has been already saved into merging
c     buffer this means that t.c. are merged up to this point. Stop merging. 
c     Modify DPRS by copying merging buffer and the rest of t.c., "current"
c     cluster of which was used as "next" at previous insertion step (in
c     other words this cluster has been already checked on having connection)
c
c     The "rest" quantaies have been already defined at the previous merging
c     stage 
c
              go to 111
            endif
            if(same_layer_f) then
c
c     The only important thing after insertion attempt is whether 
c     the "next" cluster of 2nd t.c. and the last one of possible
c     supercluster of the 1st t.c. are in the same layer or not.
c
c     The "next" cluster of 2nd t.c. and the last one of possible
c     supercluster of the 1st t.c. are IN THE SAME layer,
c        1. take new clusters of both t.c. as "current" 
c
              hitn_2_c_f = hitn_2_n_l+1    
              if(hitn_2_c_f.le.nhits2) then
                 hitn_2_c_l = get_layer_cluster(
     &                    nhits2,hitn_2_c_f,
     &                    inddat_dprs_2,work_l)
                 layer_dir_2=work_l-layer_2_c
                 layer_2_c=work_l
              endif
              hitn_1_c_f = hitn_1_c_l+1    
              if(hitn_1_c_f.le.nhits1) then
                 hitn_1_c_l = get_layer_cluster(
     &                    nhits1,hitn_1_c_f,
     &                    inddat_dprs_1,work_l)
                 layer_dir_1=work_l-layer_1_c
                 layer_1_c=work_l
              endif
c
              if(hitn_1_c_f.le.nhits1 .and. hitn_2_c_f.le.nhits2) then
c
c     Both t.c. have NOT reacehed their ends
c
                if(view_n1 .eq. 3) then
c
c     1st t.c. is 3d one. The "rest" for modifying DPRS starts at
c     "current" cluster of 1st t.c. 
c
                  hitn_rest_f = hitn_1_c_f
                  itr_rest = itr1
                  nhits_rest = nhits1
                  inddat_dprs_rest = inddat_dprs_1
                else if(view_n2 .eq. 3) then
c
c     2nd t.c. is 3d one. The "rest" for modifying DPRS starts at
c     "current" cluster of 2nd t.c. 
c
                  hitn_rest_f = hitn_2_c_f
                  itr_rest = itr2
                  nhits_rest = nhits2
                  inddat_dprs_rest = inddat_dprs_2
                endif
              else if(hitn_1_c_f.le.nhits1) then
c
c     2nd t.c. ends at "current" cluster. The "rest" for modifying DPRS
c     starts at "current" cluster of 1st t.c.
c
                hitn_rest_f = hitn_1_c_f
                itr_rest = itr1
                nhits_rest = nhits1
                inddat_dprs_rest = inddat_dprs_1
              else if(hitn_2_c_f.le.nhits2) then
c
c     1st t.c. ends at "current" cluster. The "rest" for modifying DPRS
c     starts at "current" cluster of 2nd t.c.
c
                hitn_rest_f = hitn_2_c_f
                itr_rest = itr2
                nhits_rest = nhits2
                inddat_dprs_rest = inddat_dprs_2
              else
c
c     Both t.c. have reacehed their ends. There is NO any "rest's" to
c     save in modifying DPRS. To be coinsistent with the logic of the
c     modify_DPRS_DHRE routine let's use as the rest 1st t.c. and define
c     hitn_rest_f to be out of the hit range of the 1st t.c.
c
                itr_rest = itr1
                nhits_rest = nhits1
                hitn_rest_f = nhits_rest +1
                inddat_dprs_rest = inddat_dprs_1
              endif
            else
c
c     The "next" cluster of 2nd t.c. and the last one of possible
c     supercluster of the 1st t.c. are NOT in the same layer,
c        1. redefine "next" cluster of the 2nd t.c. as "current" one
c        2. define "current" cluster of 2nd t.c. as the beginning of hit list
c           to be saved after merging buffer in modified DPRS
c        3. take new cluster of the 1st t.c. as "current" 
c
              hitn_2_c_f =  hitn_2_n_f                   
              hitn_2_c_l =  hitn_2_n_l                   
              layer_2_c  =  layer_2_n
c
              hitn_rest_f = hitn_2_c_f
              itr_rest = itr2
              nhits_rest = nhits2
              inddat_dprs_rest = inddat_dprs_2
c
              hitn_1_c_f = hitn_1_c_l+1    
              if(hitn_1_c_f.le.nhits1) then
                 hitn_1_c_l = get_layer_cluster(
     &                    nhits1,hitn_1_c_f,
     &                    inddat_dprs_1,work_l)
                 layer_dir_1=work_l-layer_1_c
                 layer_1_c=work_l
              endif                     
            endif
          else if(layer_dir_2*(layer_2_n-layer_1_c) .lt. 0) then
c
c     "next" layer cluster of 2nd t.c. is also before than "current" cluster
c     of 1st t.c.. Extend "current" cluster of 2nd t.c. to supercluster by
c     adding to it its "next" cluster and continue loop over wires/clusters 
c
c     This scheme should be improved for t.c. which change their movement
c     direction 
c
            hitn_2_c_l = hitn_2_n_l
            layer_2_c  = layer_2_n
          else if(layer_2_n .eq. layer_1_c) then
c
c     "next" cluster of 2nd t.c. and "current" one of 1st t.c. are in the same
c     layer. 
c     1. Save into merging buffer "current" cluster of 2nd t.c..(only
c        in case when isertion/combining of the previous clusters has
c        succeeded)  
c     2. Redefine "next" cluster of 2nd t.c. as "current" and go to the
c        beginning of cluster loop. (the case of combining two clusters of the
c        same layer will be treated correctly). 
c     3. The "rest" for modifying DPRS is "next" cluster of 2nd t.c. 
c
            if(insert_status .ge. 0 .or. n_comb_wires .gt.0) then
              num_w_saved=save_clust2buf(
     &                     inddat_dprs_2,hitn_2_c_f,hitn_2_c_l,
     &                     num_w_saved)
            else
c
c     Special case of combining. One of t.c. obviously starts closer to
c     interaction region than another. We should redefine "to be saved"
c     and "to be dropped" t.c. in a such way that one with greater
c     layer number of the first cluster to be saved and another to be
c     dropped. 
c
              hitn_save_l= hitn_2_c_l
              itr_save = itr2
              nhits_save = nhits2
              inddat_dprs_save = inddat_dprs_2
              itr_drop=itr1
              nhits_drop=nhits1
              inddat_dprs_drop=inddat_dprs_1
            endif
c                  
            hitn_2_c_f = hitn_2_n_f                   
            hitn_2_c_l = hitn_2_n_l                   
            layer_2_c  = layer_2_n
c
            hitn_rest_f = hitn_2_n_f
            itr_rest = itr2
            nhits_rest = nhits2
            inddat_dprs_rest = inddat_dprs_2
          endif
        else
c
c     "Current" clusters of both t.c. are in the same layer. They should be
c     combined. 
c     First, define azimuth direction, on the base of layer direction and sign
c     of curvature
c
          if(layer_dir_1 .ne. 0) then
            phi_dir_cur_1=sign(1.,layer_dir_1*rw(inddat_dprs_1i+DPRCUR))
          else
            phi_dir_cur_1=0
          endif
          if(layer_dir_2 .ne. 0) then
            phi_dir_cur_2=sign(1.,layer_dir_2*rw(inddat_dprs_2i+DPRCUR))
          else
            phi_dir_cur_2=0
          endif
c
c     Perform combining
c
          n_comb_wires=combine_clusters(
     &           hitn_1_c_f,hitn_1_c_l,inddat_dprs_1,nhits1,
     &           hitn_2_c_f,hitn_2_c_l,inddat_dprs_2,nhits2,
     &           combine_buffer)
          if(n_comb_wires .lt. 0 .and. num_w_saved .gt. 0) 
c
c     Combining failed and something has been already saved into merging
c     buffer this means that t.c. are merged up to this point. Stop merging. 
c     Modify DPRS by copying merging buffer and the rest of t.c., "current"
c     cluster of which was used as "next" at previous insertion step (in
c     other words this cluster has been already checked on having connection)
c     The "rest" quantaies have been already defined at the previous merging
c     stage 
c
     &         go to 111
c
c     The clusters of the same layer have been succsessfully combined.
c     Copy the combining buffer into merging one 
c
          cycle=1
          do while(cycle.le.n_comb_wires .and.
     &             num_w_saved .lt. BUFF_LENGTH)
             num_w_saved = num_w_saved +1
             merge_buff(num_w_saved) = combine_buffer(cycle)
             cycle = cycle + 1
          enddo
c
c     Take new clusters of both t.c. as "current" 
c
          hitn_1_c_f = hitn_1_c_l+1    
          if(hitn_1_c_f.le.nhits1) then
             hitn_1_c_l = get_layer_cluster(
     &                nhits1,hitn_1_c_f,
     &                inddat_dprs_1,work_l)
             layer_dir_1=work_l-layer_1_c
             layer_1_c=work_l
          endif
          hitn_2_c_f = hitn_2_c_l+1    
          if(hitn_2_c_f.le.nhits2) then
             hitn_2_c_l = get_layer_cluster(
     &                nhits2,hitn_2_c_f,
     &                inddat_dprs_2,work_l)
             layer_dir_2=work_l-layer_2_c
             layer_2_c=work_l
          endif
          if(hitn_1_c_f.le.nhits1 .and. hitn_2_c_f.le.nhits2) then
c
c     Both t.c. have NOT reacehed their ends
c
            if(view_n1 .eq. 3) then
c
c     1st t.c. is 3d one. The "rest" for modifying DPRS starts at
c     "current" cluster of 1st t.c. 
c
              hitn_rest_f = hitn_1_c_f
              itr_rest = itr1
              nhits_rest = nhits1
              inddat_dprs_rest = inddat_dprs_1
            else if(view_n2 .eq. 3) then
c
c     2nd t.c. is 3d one. The "rest" for modifying DPRS starts at
c     "current" cluster of 2nd t.c. 
c
              hitn_rest_f = hitn_2_c_f
              itr_rest = itr2
              nhits_rest = nhits2
              inddat_dprs_rest = inddat_dprs_2
            endif
          else if(hitn_1_c_f.le.nhits1) then
c
c     2nd t.c. ends at "current" cluster. The "rest" for modifying DPRS
c     starts at "current" cluster of 1st t.c.
c
            hitn_rest_f = hitn_1_c_f
            itr_rest = itr1
            nhits_rest = nhits1
            inddat_dprs_rest = inddat_dprs_1
          else if(hitn_2_c_f.le.nhits2) then
c
c     1st t.c. ends at "current" cluster. The "rest" for modifying DPRS
c     starts at "current" cluster of 2nd t.c.
c
            hitn_rest_f = hitn_2_c_f
            itr_rest = itr2
            nhits_rest = nhits2
            inddat_dprs_rest = inddat_dprs_2
          else
c
c     Both t.c. have reacehed their ends. There is NO any "rest's" to
c     save in modifying DPRS. To be coinsistent with the logic of the
c     modify_DPRS_DHRE routine let's use as the rest 1st t.c. and define
c     hitn_rest_f to be out of the hit range of the 1st t.c.
c
            itr_rest = itr1
            nhits_rest = nhits1
            hitn_rest_f = nhits_rest +1
            inddat_dprs_rest = inddat_dprs_1
          endif
        endif
      enddo
c
c     Modify DPRS on conditions established during the merging procedure
c
  111 call modify_DPRS_DHRE(
     &     itr_save,nhits_save,inddat_dprs_save,hitn_save_l,
     &     itr_rest,nhits_rest,inddat_dprs_rest,hitn_rest_f,
     &     num_w_saved,itr_drop,nhits_drop,inddat_dprs_drop)
  112 return
      end
C===========================================================================
      subroutine modify_DPRS_DHRE(
     &            itr1,nhits1,inddat_dprs_1,hitn_1_l,
     &            itr2,nhits2,inddat_dprs_2,hitn_2_f,
     &            num_w_saved,itr_drop,nhits_drop,inddat_dprs_drop)
$$IMPLICIT
      integer 
     &            itr1,nhits1,inddat_dprs_1,hitn_1_l,
     &            itr2,nhits2,inddat_dprs_2,hitn_2_f,
     &            num_w_saved,itr_drop,nhits_drop,inddat_dprs_drop
C-----------------------------------------------------------------------
C-
C-   Created   	4-Jun-1996   Alexander Andryakov
C-   
C-   Purpose: Modify DPRS bank of itr1 t.c. to include merging results.
C-            It's supposed that itr1 t.c. has the first hit in the new merged
C-            t.c. and the itr2 t.c. contains "tail" hits. In particular case
C-            they can be the same t.c.
C-            Modify DHRE bank to put 0 into DHRTRN word of the hits not
C-            belonging to new merged chain
C-   Input :  
C-           itr1          - DPRS bank nubmer of t.c. containing the 1st hit
C-           itr2          - DPRS bank nubmer of t.c. containing "tail" hits
C-           inddat_dprs_1 \ pointer to the beginning of the hit list of DPRS
C-           inddat_dprs_2 / banks of both t.c.
C-           nhits1        \ number of hits of both t.c.
C-           nhits2        /
C-           hitn_1_l      - DHRE number of the last hit before merging region
C-           hitn_2_f      - DHRE number of the first hit after merging region
C-           num_w_saved   - number of hits in merging buffer
C-           itr_drop      - DPRS bank nubmer of t.c. to be dropped
C-        inddat_dprs_drop - pointer to the beginning of the hit list of DPRS
C-                           bank to be dropped
C-           nhits_drop    - number of hits of this t.c.
C----------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$INC:ERLEVL.INC'
$$INCLUDE 'K$ITRK:CTIDRI.INC'
c$$INCLUDE 'K$ITRK:CDTHIT.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DHRE.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
C
      CHARACTER*36 BNKTYP
      DATA BNKTYP/'2I4,9R4,2I4,R4,2I4,2R4,I4,XXX(I4,R4)'/
C
c
      INTEGER BTYMAK,BCOPY,MDROP
c
      INTEGER 
     &        nhits_new,
     &        status,work_lng,work_ind,work_inddat,work_itr,
     &        new_ind,new_inddat,
     &        cycle,hit_cycle,layer,nneg,npos,
     &        inddat_dprs1_n,dhre_w_n,dhre_pos
C
      LOGICAL ch_dir,first
      INTEGER layer_max,layer_min,layer_dir,layer_pr,temp
c
c     For a moment
c  
      if(num_w_saved.le.0) return
c
      work_itr = 1
c
c     Stupid check
c
      if(itr1.eq.itr_drop) then
        write (6,'('' modify_DPRS_DHRE .... itr1,itr_drop:'',2i10)')
     &        itr1,itr_drop
        stop
      endif
c
c     Change DHRE to free all hits belonging to "host" t.c.
c
      cycle=1
      do while(cycle .le. nhits1)
         dhre_w_n = iw(inddat_dprs_1 + DPRLWI*(cycle-1)+DPRIWI) 
         iw(inddat_dhre + dhre_e_size*(dhre_w_n-1) + DHRTRN)=0
         cycle=cycle+1
      enddo
c
c     Change DHRE to free all hits belonging to "gifter" t.c.
c
      cycle=1
      do while(cycle .le. nhits_drop)
         dhre_w_n = iw(inddat_dprs_drop + DPRLWI*(cycle-1)+DPRIWI) 
         iw(inddat_dhre + dhre_e_size*(dhre_w_n-1) + DHRTRN)=0
         cycle=cycle+1
      enddo
c
c     Copy into working DPRS bank the DPRS bank of the t.c. that contains first
c     hit 
c
      status=BCOPY(iw,'DPRS',itr1,'WORK',work_itr,work_ind,work_inddat)
      if(status .ne. YESUCC) then
c
c     DPRS bank of 1st t.c. cannot be copied to working DPRS 
c     This event should be reprocessed
c     
         call ERLOGR('modify_DPRS_DHRE',ERSEVR,0,0,
     +               'Bank DPRS cannot be copied')
         return
      endif
c
c     Calculate new number of hits
c
      nhits_new=hitn_1_l + 
     &          num_w_saved +
     &          nhits2-hitn_2_f+1
      if(nhits_new.gt.999) nhits_new=999
      write (BNKTYP(27:29),'(I3)') nhits_new
c
c     Enlarge working DPRS bank
c
      status = BTYMAK(iw,'WORK',work_itr,BNKTYP,
     &              work_lng,work_ind,work_inddat)
      if(status.ne.YESUCC) then
c
c     Working DPRS bank cannot be enlarged due to lack of space and has
c     been lost. This event should be reprocessed
c     
         call ERLOGR('modify_DPRS_DHRE',ERSEVR,0,0,
     +               'Bank WORK cannot be enlarged')
         return
      endif

c     Initialisation for t.c. area definition
c
      layer_max=-1
      layer_min=1000
      ch_dir=.FALSE.
      first=.TRUE.
      layer_dir=0
c
c     First, count the number of + and - wires before the merged part 
c     and assign new t.c. number to these hits in DHRE
c
      work_inddat = work_inddat + iw(work_inddat+DPRHDS)
      inddat_dprs1_n = work_inddat  + DPRCEN
      nneg=0
      npos=0
      hit_cycle=1
      do while(hit_cycle .le. hitn_1_l .and.
     &         hit_cycle .le. nhits_new)
         dhre_w_n = iw(inddat_dprs1_n+DPRLWI*(hit_cycle-1)+DPRIWI)
         dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n-1)
         iw(dhre_pos + DHRTRN)=itr1
         layer = iw(dhre_pos + DHRSLR)
         if(TIDST(layer).gt.0) then 
           npos=npos+1
         else if(TIDST(layer).lt.0) then
           nneg=nneg+1
         endif
         hit_cycle =  hit_cycle + 1
c
c    Redefine layer boundary of the piece of t.c. 
c
         if(.not.first) then
           if(layer_dir.ne.0 .and. .not.ch_dir) 
     &       ch_dir = ch_dir .or. 
     &                layer_dir*(layer - layer_pr) .lt. 0
           layer_dir = layer - layer_pr
         else
           first=.FALSE.
         endif
         layer_pr=layer
         if(layer .lt. layer_min) layer_min = layer
         if(layer .gt. layer_max) layer_max = layer
      enddo
c
c     Copy merging buffer into enlarged working DPRS starting from hit
c     next to hitn_1_l and count the number of + and - wires in this sample
c
      cycle=1
      do while(cycle .le. num_w_saved .and.
     &         hit_cycle .le. nhits_new)
         iw(inddat_dprs1_n+DPRLWI*(hit_cycle-1)+DPRIWI)=
     &      merge_buff(cycle)
         dhre_pos = inddat_dhre + dhre_e_size*(merge_buff(cycle)-1)
         iw(dhre_pos + DHRTRN)=itr1
         layer = iw(dhre_pos + DHRSLR)
         if(TIDST(layer).gt.0) then 
           npos=npos+1
         else if(TIDST(layer).lt.0) then
           nneg=nneg+1
         endif
         cycle=cycle+1
         hit_cycle=hit_cycle+1
c
c    Redefine layer boundary of the piece of t.c. 
c
         if(.not.first) then
           if(layer_dir.ne.0 .and. .not.ch_dir) 
     &       ch_dir = ch_dir .or. 
     &                layer_dir*(layer - layer_pr) .lt. 0
           layer_dir = layer - layer_pr
         else
           first=.FALSE.
         endif
         layer_pr=layer
         if(layer .lt. layer_min) layer_min = layer
         if(layer .gt. layer_max) layer_max = layer
      enddo
c
c     Copy the rest of DPRS bank of that t.c., which has "tail" hits
c     And count the number of + and - wires in this sample
c
      cycle=hitn_2_f
      do while(cycle .le. nhits2 .and.
     &         hit_cycle .le. nhits_new)
         dhre_w_n = iw(inddat_dprs_2+DPRLWI*(cycle-1)+DPRIWI)
         iw(inddat_dprs1_n+DPRLWI*(hit_cycle-1)+DPRIWI)=dhre_w_n
         dhre_pos = inddat_dhre + dhre_e_size*(dhre_w_n-1)
         iw(dhre_pos + DHRTRN)=itr1
         layer = iw(dhre_pos + DHRSLR)
         if(TIDST(layer).gt.0) then 
           npos=npos+1
         else if(TIDST(layer).lt.0) then
           nneg=nneg+1
         endif
         cycle=cycle+1
         hit_cycle=hit_cycle+1
c
c    Redefine layer boundary of the piece of t.c. 
c
         if(.not.first) then
           if(layer_dir.ne.0 .and. .not.ch_dir) 
     &       ch_dir = ch_dir .or. 
     &                layer_dir*(layer - layer_pr) .lt. 0
           layer_dir = layer - layer_pr
         else
           first=.FALSE.
         endif
         layer_pr=layer
         if(layer .lt. layer_min) layer_min = layer
         if(layer .gt. layer_max) layer_max = layer
      enddo
c*************************************************** debug only
c
c    Stupid debug check
c
      if(nneg+npos.ne.nhits_new) then
        write (6,'(''   merge_1_into_2 ....'',
     &             ''nneg, npos, nhits_new:'',3i10)')
     &               nneg, npos, nhits_new
        stop
      endif
c*************************************************** debug only
c
c    Hit list has been modified.
c        Modify now kinematic variables. For a moment only curvature and
c        quality are modified.
c        There is a small question how to modify curvature. 
c        In case of complete merging: nhits1 + nhits_drop = npos + nneg the
c        idea is very simple curvatures are weightted according to the number
c        of contributed hits.
c        In case of incomplete merging: nhits1 + nhits_drop > npos + nneg
c        it's not very easy to calculate the number of contributed hits. In
c        this case simple avareging of 2 curvatures is performed if the
c        shortest t.c. is at least 1/3 of the other one. If it's even shorter
c        then the curvature of the longest t.c. is taken.
c
      if(nhits1 + nhits_drop .eq. npos + nneg) then
        rw(work_inddat+DPRCUR) = (nhits1*rw(work_inddat+DPRCUR) +
     &                nhits_drop*rw(inddat_dprs_drop-DPRCEN+DPRCUR))/
     &                (npos+nneg)
      else
        if(nhits1.gt.nhits_drop) then
          if(nhits1/nhits_drop.lt.3) 
     &       rw(work_inddat+DPRCUR) = 0.5*(rw(work_inddat+DPRCUR) +
     &                          rw(inddat_dprs_drop-DPRCEN+DPRCUR))
        else
          if(nhits_drop/nhits1.lt.3) then 
             rw(work_inddat+DPRCUR) = 0.5*(rw(work_inddat+DPRCUR) +
     &                          rw(inddat_dprs_drop-DPRCEN+DPRCUR))
          else
             rw(work_inddat+DPRCUR) = rw(inddat_dprs_drop-DPRCEN+DPRCUR)
          endif
        endif
      endif
c
c     Modyfication to the initial azimuth angle of the t.c. momentum
c     Simple averaging is not good enough due to the fact that sometimes
c     very short t.c. can have absolutely wrong phi0 (even of the opsite
c     sign and not within 2pi).
c
      if(rw(work_inddat+DPRPHI)*rw(inddat_dprs_drop-DPRCEN+DPRPHI).gt.0)
     &  then
        rw(work_inddat+DPRPHI) = (nhits1*rw(work_inddat+DPRPHI) +
     &     nhits_drop*rw(inddat_dprs_drop-DPRCEN+DPRPHI))/(npos+nneg)
      else if(nhits1.lt.nhits_drop) then
        rw(work_inddat+DPRPHI) = rw(inddat_dprs_drop-DPRCEN+DPRPHI)
      endif        
c     Since "quality" is "something chi**2 like" - N.D.F., it seems to
c     me more natural summ up these values instead of avareging them
c
      rw(work_inddat+DPRQUA) = rw(work_inddat+DPRQUA) +
     &                          rw(inddat_dprs_drop-DPRCEN+DPRQUA)
      iw(work_inddat+DPRPOS) = npos
      iw(work_inddat+DPRNEG) = nneg
      iw(work_inddat+DPRPOK)=3
c
c    Put new boundaries of t.c.
c
      temp=abs(iw(work_inddat+DPRLRG))/10000
      if(ch_dir) then
        iw(work_inddat+DPRLRG)=-(temp*10000 +
     +                           layer_max*100 + layer_min)
      else
        iw(work_inddat+DPRLRG)=  temp*10000 +
     +                           layer_max*100 + layer_min
      endif
      rw(work_inddat+DPRPHL)=-101.
c
c    Copy working DPRS into DPRS of 1st t.c. (the bank is also enlarged
c    during this copy)
c
      status = BCOPY(iw,'WORK',work_itr,'DPRS',itr1,
     &                new_ind,new_inddat)
      if(status.ne.YESUCC) then
c
c     Working DPRS bank cannot be copied to 1st DPRS bank
c     This event should be reprocessed
c     
         call ERLOGR('modify_DPRS_DHRE',ERSEVR,0,0,
     +               'Bank DPRS cannot be updated')
      else
        inddat_dprs_array(itr1) = new_inddat + iw(new_inddat+DPRHDS)
      endif 
c
c     Drop one of DPRS bank 
c
      status = MDROP(iw,'DPRS',itr_drop)
      inddat_dprs_array(itr_drop)=0
c
c     A little extracalculation usefull in the FIRST merging loop
c
      if(itr1 .gt. 0 .and. itr1 .lt. first_itr2) then
        n_itr1_checked = n_itr1_checked +1
      else if(itr1 .ge. first_itr2 .and. itr1 .le. last_itr2) then 
        n_itr2_checked = n_itr2_checked +1
      endif
      if(itr_drop .gt. 0 .and. itr_drop .lt. first_itr2) then
        n_itr1_checked = n_itr1_checked +1
      else if(itr_drop .ge. first_itr2 .and. itr_drop .le. last_itr2)
     &       then 
        n_itr2_checked = n_itr2_checked +1
      endif
      return
      end
C===========================================================================
      integer function save_clust2buf(
     &        inddat_dprs,cl_f,cl_l,
     &        num_w_saved)
$$IMPLICIT
      integer
     &        inddat_dprs,cl_f,cl_l,num_w_saved
C----------------------------------------------------------------------
C-
C-   Created   27-May-1996   Alexander Andryakov
C-
C-   Input :  
C-           inddat_dprs - pointer to the beginning of the data block of 
C-                         DPRS bank of the t.c.
C-           cl_f          \ 
C-           cl_l          / first & last wires in the cluster of the t.c.
C-           num_w_saved   - number of wires already saved in this buffer
C-   Return :
C-           new number of wires saved in the buffer
C----------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
c
      INTEGER cycle, n_w
c
      cycle = 0
      n_w = cl_l-cl_f
      do while (num_w_saved + cycle .lt. BUFF_LENGTH .and. 
     &          cycle .le. n_w)
         merge_buff(num_w_saved + cycle +1)=
     &      iw(inddat_dprs + DPRLWI*(cl_f + cycle - 1)+DPRIWI)
         cycle = cycle + 1
      enddo
      if(n_w + 1 + num_w_saved .gt. BUFF_LENGTH) then
         save_clust2buf = BUFF_LENGTH + 1
      else
         save_clust2buf = num_w_saved + cycle
      endif
      return 
      end
      
C===========================================================================
      subroutine z0_ctgth
$$IMPLICIT
C----------------------------------------------------------------------
C-
C-   Created   3-DEC-1993   Alexander Andryakov
C-   Updated  25-Jun-1993   Alexander Andryakov (for new merging code)
C-   
C-   Purpose: Performs 0 approximation fit of z0 and cot(theta) 
C-            for each 3d t.c. 
C-
C----------------------------------------------------------------------
$$INCLUDE 'K$INC:BCS.INC'
$$INCLUDE 'YBOS$LIBRARY:ERRCOD.INC'
$$INCLUDE 'K$INC:ERLEVL.INC'
$$INCLUDE 'K$ITRK:CTIDRI.INC'
$$INCLUDE 'K$ITRK:CDTHIT.INC'
$$INCLUDE 'K$ITRK:CDTCUT.INC'
$$INCLUDE 'K$ITRK:CTRACK.INC'
$$INCLUDE 'K$ITRK:DPRS.INC'
$$INCLUDE 'K$ITRK:DHRE.INC'
$$INCLUDE 'K$ITRK:DCMERGINT.INC'
c
      INTEGER BLOCAT,BNEXT,BDATA
c
      INTEGER dhre_w_n,dhre_w_n_p,dhre_w_p,
     &        status,ind_dprs,inddat_dprs,inddat_dprs_bhl,
     &        i_tr_ass,layer_c,last_wire,
     &        cycle,nhif,layer_p,n_z_meas,i_point
      REAL path_rphi,zr_sum,z_sum,r_sum,r2_sum,x0_1,y0_1,
     &     r0_1,ri0_1,dir_x_1,dir_y_1,dir_z_1,x0_2,y0_2,
     &     r0_2,ri0_2,dir_x_2,dir_y_2,dir_z_2,
     &     ddir_x,ddir_y,ddir_z,dx_0,dy_0,a1,a2,b,c,
     &     denominator,wire_path_1,delta_wire_path,
     &     x_1,y_1,z_1,wire_path_2,
     &     x_2,y_2,z_2,space_points(2000,3),delta_r2,delta_r,
     &     avcon,cot_theta,z_0 
c
c    Loop over track candidates found by the pattern recognition code
c     Start with the first t.c. in DPRS chain (take it as current)
c
      status=BLOCAT(iw,'DPRS',-1,ind_dprs,inddat_dprs)
      do while (status.eq.YESUCC.and.ind_dprs.gt.0)
c
c     DPRS bank of current t.c. located succesfully
c          skip the header
c
        inddat_dprs=inddat_dprs+IW(inddat_dprs+DPRHDS)  
        inddat_dprs_bhl = inddat_dprs+DPRCEN
c
c     Check first if this t.c. is 3-d t.c.
c
        if(iw(inddat_dprs +DPRPOK).eq.3) then
c
c     Get number of hits of located t.c. 
c     and make some preparations for wire loop 
c
          nhif=iw(inddat_dprs +DPRPOS)+iw(inddat_dprs +DPRNEG)
          dhre_w_n = iw(inddat_dprs_bhl + DPRIWI)
          dhre_w_p = inddat_dhre + dhre_e_size*(dhre_w_n-1)
          i_tr_ass= iw(dhre_w_p + DHRTRN) 
          layer_c = iw(dhre_w_p + DHRSLR)
          layer_p=layer_c
          dhre_w_n_p=dhre_w_n
          path_rphi= 0.                                         
          zr_sum   = 0.                                         
          z_sum    = 0.                                         
          r_sum    = 0.                                         
          r2_sum   = 0.                                         
          n_z_meas = 0
          last_wire=0
c
c     Loop over wires of located t.c.
c
          do cycle=2,nhif
c
c     Get the wire position in DHRE bank and define the layer number
c
            dhre_w_n = iw(inddat_dprs_bhl + DPRLWI*(cycle-1) +DPRIWI)
            dhre_w_p = inddat_dhre + dhre_e_size*(dhre_w_n-1)
            layer_c = iw(dhre_w_p + DHRSLR)
c
c     Put the track number of the first hit to all others
c
            iw(dhre_w_p + DHRTRN) = i_tr_ass
c
c    Find point of layer changing. 
c    Compare layer number of the current hit with that of the previous hit
c
            if(abs(layer_p-layer_c).eq.1) then
            
c            Two adjacent hits are in ajacent layers
c            What is 3-d coordinates of these two hits?
c           
              x0_1=DTXH_K(dhre_w_n_p)  !  previous hit is 1st
              y0_1=DTYH_K(dhre_w_n_p)
              r0_1=x0_1**2+y0_1**2
              if(r0_1.lt.1.e-10) go to 111
              ri0_1=1./sqrt(r0_1)
              dir_x_1=-TIDST(layer_p)*y0_1*ri0_1
              dir_y_1= TIDST(layer_p)*x0_1*ri0_1
              dir_z_1= TIDSC(layer_p)
              x0_2=DTXH_K(dhre_w_n)    !  current one is 2nd
              y0_2=DTYH_K(dhre_w_n)
              r0_2=x0_2**2+y0_2**2
              if(r0_2.lt.1.e-10) go to 111
              ri0_2=1./sqrt(r0_2)
              dir_x_2=-TIDST(layer_c)*y0_2*ri0_2
              dir_y_2= TIDST(layer_c)*x0_2*ri0_2
              dir_z_2= TIDSC(layer_c)
              ddir_x = dir_x_2-dir_x_1 
              ddir_y = dir_y_2-dir_y_1
              ddir_z = dir_z_2-dir_z_1
              dx_0=x0_2-x0_1
              dy_0=y0_2-y0_1
              a1=dx_0*ddir_x +dy_0*ddir_y                  
              a2=dx_0*dir_x_2+dy_0*dir_y_2
              b=ddir_x**2      + ddir_y**2      + ddir_z**2  
              c=ddir_x*dir_x_2 + ddir_y*dir_y_2 + ddir_z*dir_z_2
              if(abs(b-c**2).lt.1.e-10) then  !  system is unsolvable
                write(6,'('' wires do not cross ???'')')
                go to 111                     !   skip hit
              endif
              denominator=1./(b-c**2)
              wire_path_1     = -(a1  -a2*c)*denominator
              delta_wire_path = -(a2*b-a1*c)*denominator
              x_1=x0_1 + dir_x_1*wire_path_1   !  3-d coordinates 1st hit
              y_1=y0_1 + dir_y_1*wire_path_1
              z_1=       dir_z_1*wire_path_1
              wire_path_2 = wire_path_1 +delta_wire_path
              x_2=x0_2 + dir_x_2*wire_path_2   !  3-d coordinates 2nd hit
              y_2=y0_2 + dir_y_2*wire_path_2
              z_2=       dir_z_2*wire_path_2
c              write(6,'('' x,y,z,l = '',3g15.4,i5)') x_1,y_1,z_1,85-layer_p
c              write(6,'('' x,y,z,l = '',3g15.4,i5)') x_2,y_2,z_2,85-layer_c
              space_points(n_z_meas+1,1)=x_1
              space_points(n_z_meas+1,2)=y_1
              space_points(n_z_meas+1,3)=z_1
              space_points(n_z_meas+2,1)=x_2
              space_points(n_z_meas+2,2)=y_2
              space_points(n_z_meas+2,3)=z_2
              n_z_meas = n_z_meas + 2
              last_wire=dhre_w_n
  111         continue
            endif
            layer_p=layer_c
            dhre_w_n_p=dhre_w_n
          enddo  !  loop over wires of the current track
c
c    Calculate cot(theta) and Z0. (l.s.f.)
c
          do i_point=2,n_z_meas
            delta_r2 = 
     &        (space_points(i_point,1)-space_points(i_point-1,1))**2 +
     &        (space_points(i_point,2)-space_points(i_point-1,2))**2 
            delta_r  = sqrt(delta_r2)
            path_rphi= path_rphi + delta_r
            zr_sum   = zr_sum + space_points(i_point,3)*path_rphi
            z_sum    = z_sum + space_points(i_point,3)
            r_sum    = r_sum + path_rphi
            r2_sum   = r2_sum + path_rphi**2
          enddo
          avcon=1./(n_z_meas-1)
          denominator=r2_sum-avcon*r_sum**2
          if(abs(denominator).lt.1.e-10) then !  cot(theta)=infinity
cw          write(6,'(''  track can. '',i3,''  is near parallel to z'')')
cw       &       itrack
            call INERR(216,1)
          else  
            cot_theta= (zr_sum-avcon*z_sum*r_sum)/denominator
            z_0      = avcon*(z_sum-cot_theta*r_sum)
c
c     Put this values into DPRS 
c
c     Fill z0 and cot(theta). 
c          It should be stressed that in present version of the code z0
c          corresponds to the point of first z measurement (which is not true
c          initial point of the t.c. but something corresponding to the
c          intersection of the two adjacent wires in two layers with OPOSITE
c          sign of  stereo angle)
c      
            rw(inddat_dprs+DPRZCO)=z_0
            rw(inddat_dprs+DPRCTT)=cot_theta
c
c     Fill coordinates of the last point
c          Similar to what was said on z0 is applicable here for the last z.
c
            rw(inddat_dprs+DPRXLS)=DTXH_K(last_wire)
            rw(inddat_dprs+DPRYLS)=DTYH_K(last_wire)
            rw(inddat_dprs+DPRZLS)=z_0+cot_theta*path_rphi
          endif
        endif    !    Check if t.c. is 3d one
c
c     Locate next DPRS bank
c
        status=BNEXT(iw,ind_dprs,ind_dprs)
        if (status.eq.YESUCC) status=BDATA(iw,ind_dprs,inddat_dprs)
      enddo   !  loop over DPRS banks
      call vzero(DTXH_K,NUMHIT)
      call vzero(DTYH_K,NUMHIT)
      END
[KLOE] [Offline Doc] [TRK Files]
Generated with Light on Thu Apr 8 13:00:16 MET DST 1999 .
Mail comments and suggestions.