      subroutine trkeventpkt(runerror,event_file_name)

      include '../commonyoda/commontracker.f'
      include '../commonyoda/dataformat.f'
c      include '../commonyoda/trk_calib_parameters.f'
      include '../commonyoda/level0.f'

      logical DEBUG
      common/DEBUGflag/DEBUG
c      data DEBUG/.true./
      data DEBUG/.false./


      integer ndummy
      data ndummy/1000/
      
      integer runerror          !readevent error flag
      integer ffd_pkt           !pkt file descriptor
                                !(file temporaneo)     
      character*60 event_file_name !nome file

      integer lun_pkt
      data lun_pkt/10/


      open(unit=lun_pkt, 
     $     name=EVENT_FILE_NAME(1:lnblnk(EVENT_FILE_NAME)), 
     $     status='old', 
     $     form='unformatted'
     $     )
      ffd_pkt = FNum(lun_pkt)   !reads unix file descriptor


      call initlevel0

      TOTDATAlength = 0.        !total length of data buffer
      do iview=1,ndummy         !loop on views               
         call searchtrkheader(runerror,ffd_pkt)
c         if(runerror.eq.-1) goto 24
         if(runerror.eq.-1) goto 2222
         if(runerror.eq.1) then                  
c            print*,' '
c            print*,'readraw: END OF CPU PACKET '
c            print*,'______________________________________ '
c     goto 9900  !end loop on files 
c            goto 8800           !end loop on views (DSP pkt)
            goto 2222         
         endif
         
         if(checkheader.ne.2) then
c            print*,'>>>> ERROR <<<< (trkeventpkt)'
c            print*,'>>>> CPU packet type ',!pkt_type, 
c     $           ' does not match DSP type ',checkheader
c     goto 9909  ! next event (==> search another CPU header)
            DAQmode_temp = ishft(iand(header(1),z'03f0'),-4)
            DSPnumber_temp = iand(header(1),z'000f')
c            print*,'  -----------------------------------'
c     $           ,iview
c            print*,'  DSP number-----',int(DSPnumber_temp)
c            print*,'  DAQ mode-------',int(DAQmode_temp)
c            print*,'  -----------------------------------'
            goto 2525           !next view (==> search another DSP header)
         endif
         
         call unpackdata(runerror,ffd_pkt)
c         if(runerror.eq.-1) goto 24
         if(runerror.eq.-1) goto 2222
c         if(runerror.eq.1) goto 23
         if(runerror.eq.1) goto 2222
                          
         if(DEBUG)then
            print*,'  '
            print*,'  -----------------------------------',iview
            print*,'  DSP number-----',DSPnumber_dat
            print*,'  DAQ mode-------',DAQmode_dat
            print*,'  event number   ',eventn_dat
            print*,'  datalength (13-bit w) ---- ',datalength_dat
c     print*,'  NCLUST---',nclust_dat
c     print*,'  CUTC-----',cutc_dat
c     print*,'  CUTCL----',cutcl_dat
            print*,'  L-1  addr---',addrcluster_dat(1)
            print*,'       signal-',signcluster_dat(1)
            print*,'  L-2  addr---',addrcluster_dat(2)
            print*,'       signal-',signcluster_dat(2)
            print*,'  L-3  addr---',addrcluster_dat(3)
            print*,'       signal-',signcluster_dat(3)
            print*,'  FC------',fc_dat 
            print*,'  compression time ',compressiontime_dat 
            print*,'  FL1--',fl1_dat
            print*,'  FL2--',fl2_dat
            print*,'  FL3--',fl3_dat
            print*,'  FL4--',fl4_dat
            print*,'  FL5--',fl5_dat
            print*,'  FL6--',fl6_dat
c     print*,'  checksum-',checksum_dat 
         endif         

         trk_DSP_ok(DSPnumber_dat)=1
                  
         call fillview(iview)
         
 2525    continue
      enddo                     !end loop on views
      
 2222 continue

      close (lun_pkt)
      return
      end

*     **********************************************

c      subroutine trk_calib_pkt(runerror,ffd_pkt)
      subroutine trkcalibpkt(runerror,event_file_name)

      include '../commonyoda/commontracker.f'
      include '../commonyoda/dataformat.f'
      include '../commonyoda/trk_calib_parameters.f'
     
      integer ndummy
      data ndummy/1000/
      
      integer runerror          !readevent error flag
      integer ffd_pkt           !pkt file descriptor
                                !(file temporaneo)     
      character*60 event_file_name !nome file

      logical DEBUG
c      data DEBUG/.true./
      data DEBUG/.false./
ccc      common/DEBUGflag/DEBUG


      integer lun_pkt
      data lun_pkt/10/


      open(unit=lun_pkt, 
     $     name=EVENT_FILE_NAME(1:lnblnk(EVENT_FILE_NAME)), 
     $     status='old', 
     $     form='unformatted'
     $     )
      ffd_pkt = FNum(lun_pkt)   !reads unix file descriptor
      

      
      do iview=1,ndummy         !loop on views (DSP pkt)
         call searchtrkheader(runerror,ffd_pkt)
c         if(runerror.eq.-1) goto 24
         if(runerror.eq.-1) goto 2222
         if(runerror.eq.1) then                  
c            print*,' '
c            print*,'readraw: END OF CPU PACKET '
c            print*,'______________________________________ '
            goto 2222           !end loop on views (DSP pkt)
         endif
         if(checkheader.ne.3) then
c            print*,'>>>> ERROR <<<< (trkcalibpkt)'
c            print*,'>>>> CPU packet type ',!pkt_type, 
c     $           ' does not match DSP type ',checkheader
            DAQmode_temp = ishft(iand(header(1),z'03f0'),-4)
            DSPnumber_temp = iand(header(1),z'000f')
c            print*,'  -----------------------------------'
c     $           ,iview
c            print*,'  DSP number-----',int(DSPnumber_temp)
c            print*,'  DAQ mode-------',int(DAQmode_temp)
c            print*,'  -----------------------------------'
            goto 2424           !next view (==> search another DSP header)
         endif                     
         
         call unpackcalibration(runerror,ffd_pkt)
c         if(runerror.eq.-1) goto 24
         if(runerror.eq.-1) goto 2222
c         if(runerror.eq.1) goto 23
         if(runerror.eq.1) goto 2222
                  
         if(DEBUG)then

            print*,'Calibration packet ==> ',iview
            
            print*,'---- Calibration packet ',iview,' ----'
            print*,'  DSP number       ',DSPnumber_cal
            print*,'  DAQ mode         ',DAQmode_cal
            print*,'  calibration run  ',calibrationnumber
            print*,'  n. event used    ',nused_event
            print*,'  <PED> ladder 1   ',ped_1
            print*,'  <PED> ladder 2   ',ped_2
            print*,'  <PED> ladder 3   ',ped_3
            print*,'  <SIG> ladder 1   ',sig_1
            print*,'  <SIG> ladder 2   ',sig_2
            print*,'  <SIG> ladder 3   ',sig_3
            print*,'  n.BAD ladder 1   ',nbad_1
            print*,'  n.BAD ladder 2   ',nbad_2      
            print*,'  n.BAD ladder 3   ',nbad_3
            print*,'  error flag       ',ff
            if(nused_event.ne.0.or.ff.ne.0)then
               print*,'*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*'
               print*,'*     !!! CALIBRATION FAILURE !!!     *'
               print*,'*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*'
            endif
         endif

         DAQmode(iview)=DAQmode_cal
         DSPnumber(iview)=DSPnumber_cal
         calibnumber(iview)=calibrationnumber
         ncalib_event(iview)=nused_event
         ped_l1(iview)=ped_1
         ped_l2(iview)=ped_2
         ped_l3(iview)=ped_3
         sig_l1(iview)=sig_1
         sig_l2(iview)=sig_2
         sig_l3(iview)=sig_3
         nbad_l1(iview)=nbad_1
         nbad_l2(iview)=nbad_2
         nbad_l3(iview)=nbad_3
         cal_flag(iview)=ff

         do is=1,nstrips_view
            DSPbad_par(iview,is)=DSPbad_o(DSPnumber_cal,is)
            DSPped_par(iview,is)=DSPped_o(DSPnumber_cal,is)
            DSPsig_par(iview,is)=DSPsig_o(DSPnumber_cal,is)
         enddo
c         
         trk_DSP_ok(DSPnumber_cal)=1
c----------------------------------------------------------
c     NVIEWS calibration packets should have been found
c----------------------------------------------------------
c                  if(n_cal_pkt.eq.nviews)then
c                     found_cal_pkt = .true.
c                     n_cal_pkt = 0
c                  endif
 2424    continue
      enddo                     ! end loop on views (calibration pkt)
 2222 continue

      close (lun_pkt)

      return
      end

***...***...***...***...***...***...***...***...***...***...***...***...***...***...***...***
*
*
*
*
*
*
*
*
***...***...***...***...***...***...***...***...***...***...***...***...***...***...***...***

      subroutine searchtrkheader(runerror,ffd)
C.............................................................
C     Search for a valid tracker DSP header (=>one view) 
C     and return the type of header
C.............................................................

      include '../commonyoda/commontracker.f'
      include '../commonyoda/dataformat.f'

      integer ffd               !input file descriptor
      integer runerror          !readevent error flag

c--------------------------------------------------
c     N.B.13 bit packing is done for each DSP header+datablock, 
C     so each DSP 13 bit 
c     first word starts at the beginnig of a 16 bit word
c--------------------------------------------------
 9100 continue
      runerror=0                !error flag initialization
      checkheader=0

c--------------------------------------------------
c     looks for a DSP header beginning 
C     (a word beginning with 1110)
c--------------------------------------------------
      call findstart(runerror,ffd)
      
      if(runerror.eq.1) goto 200
      if(runerror.eq.-1)then
         runerror=1             !in this case I dont want the 
                                !the program to crash
         goto 200
      endif
c--------------------------------------------------
c     the first word could be a DSP header first word: 
C     reads 13 8-bit words and 
c     writes them in 16 13-bit words to check for all 
C     DSP header features
c--------------------------------------------------
      runerror=0
      
      call hunpacker(header,runerror,ffd)
      
      if(runerror.eq.1) goto 200
c      if(runerror.eq.-1) goto 200
      if(runerror.eq.-1)then
         runerror=1             !in this case I dont want the 
                                !the program to crash
         goto 200
      endif
c--------------------------------------------------
c     extracts and controls header:
c--------------------------------------------------
C     last header word must be:
c     |0001|1100|0000|0000| for acquisition
c     |0001|1111|1111|1111| for calibration
c--------------------------------------------------
      if(iand(header(16),z'ffff').eq.z'1c00') then !last header
         checkheader=2          ! event
      elseif(iand(header(16),z'ffff').eq.z'1fff') then !last header
         checkheader=3          ! calibration packet
      else
         checkheader=1          ! not a valid DSP header
      endif
c--------------------------------------------------
c     first header word must be:  
c     |0001|110x|xxxx|xxxx|
c--------------------------------------------------
      if(iand(header(1),z'fe00').ne.z'1c00') 
     $     checkheader=1        !not a valid DSP header
c--------------------------------------------------
c     intermediate header words must be:  
c     |0001|010x|xxxx|xxxx|
c--------------------------------------------------
      do i=2,15    
         if(iand(header(i),z'fc00').ne.z'1400') 
     $        checkheader=1     !not a valid DSP header
      enddo
c--------------------------------------------------
c     if checkheader = 1 
c     then this is not a DSP header (or some 
c     noise lurks around) so go a word ahead and 
c     try again
c--------------------------------------------------
      if(checkheader.eq.1) then
         call skipbyte(ffd)
         goto 9100
      endif
 200  continue
      end

*.............................................................      


*.............................................................      

      subroutine unpackcalibration(runerror,ffd)
*.............................................................
*     decode calibration data
*     header + data(PED SIG BAD) + trailer
*............................................................
      include '../commonyoda/commontracker.f'
      include '../commonyoda/dataformat.f'

      integer ffd               !input file descriptor
      integer runerror          !readevent error flag
c     buffer temporanei
      integer*2 templ(nstrips_ladder) 
      real*4 tempf(nstrips_ladder)
      

 12   format(z4)

*-----------------------------------------------------------
*     HEADER
*     (N.B. during test 2003 the header of calibration packets
*     was only partially filled)
*
*     the following is the final calibration header
*-----------------------------------------------------------
      DAQmode_cal = ishft(iand(header(1),z'03f0'),-4)
      DSPnumber_cal = iand(header(1),z'000f')
      dataword = ior(ishft(iand(header(2),z'03ff')
     $     ,10),iand(header(3),z'03ff'))
c      calibrationnumber = ior(ishft(iand(header(4)
c     $     ,z'03ff'),10),iand(header(5),z'03ff'))
      calibrationnumber = iand(header(4),z'03ff')
      nused_event = iand(header(5),z'03ff')
      ped_1 = iand(header(6),z'03ff')
      ped_2 = iand(header(7),z'03ff')
      ped_3 = iand(header(8),z'03ff')
      ped_1 = ped_1 * 4
      ped_2 = ped_2 * 4
      ped_3 = ped_3 * 4
      sig_1 = iand(header(9),z'03ff')
      sig_2 = iand(header(10),z'03ff')
      sig_3 = iand(header(11),z'03ff')
      nbad_1 = iand(header(12),z'03ff')
      nbad_2 = iand(header(13),z'03ff')
      nbad_3 = iand(header(14),z'03ff')
      ff = ishft(iand(header(15),z'0300'),-8)
      checksum_cal = iand(header(15),z'00ff') 

      runerror=0
      call readtrailer(trailer,runerror,ffd)
c$$$      do i=1,3
c$$$         write(*,12)trailer(i)
c$$$      enddo
c-----------------------------------------------------------
c     the checksum is a 8-bit word calculated as the 
c     XOR of the 16-bit data words,
c     hence the XOR between the two halfs
C----------------------------------------------------------
      do il=1,3                 !loop on ladders

         call readped(tempf,runerror,ffd)
         do is=1,nstrips_ladder
            iss=is+nstrips_ladder*(il-1)
            DSPped_o(DSPnumber_cal,iss)=tempf(is)
c            print*,il,iss,DSPped_o(DSPnumber,iss)
c            print *,DSPnumber_cal,iss,tempf(is)

         enddo

         call readsig(tempf,runerror,ffd)
         do is=1,nstrips_ladder
            iss=is+nstrips_ladder*(il-1)
            DSPsig_o(DSPnumber_cal,iss)=tempf(is)
c            print*,DSPsig_o(DSPnumber,iss)
         enddo

         call readbad(templ,runerror,ffd)
         do is=1,nstrips_ladder
            iss=is+nstrips_ladder*(il-1)
            DSPbad_o(DSPnumber_cal,iss)=templ(is)
c            print*,il,is,iss,DSPbad_o(DSPnumber,iss)
         enddo

C//// CAPIRE PERCHE` NON C'E` LA PAROLA DI FINE LADDER \\\\
c         call readeol(word,runerror,ffd)
 11      format(i1,'   ',z4)
c         write(*,11)il,word
         call readtrailer(trailer,runerror,ffd)
c$$$         do i=1,3
c$$$            write(*,12)trailer(i)
c$$$         enddo

c     print*,'fine ladder' !???
         
      enddo                     !end loop on ladders
      
      return
      end
*.............................................................      


      subroutine unpackdata(runerror,ffd)
*.............................................................
*     decode event data
*     header + data + trailer
*............................................................
      include '../commonyoda/commontracker.f'
      include '../commonyoda/dataformat.f'
      include '../commonyoda/level0.f'

      integer ffd               !input file descriptor
      integer runerror          !readevent error flag
      integer l_tra


 12   format(z4)

*-----------------------------------------------------------
*     HEADER
*-----------------------------------------------------------

      DAQmode_dat = ishft(iand(header(1),z'03f0'),-4)
      DSPnumber_dat = iand(header(1),z'000f')
C     ------------------------------------------------------
c     words 2 and 3 give tshe number of transmitted 16-bit
c     words ( 13 header words + data )
c     NB: data are packed from 13-bit to 16-bit words, 
c     so the stream is complited with zeros in order to have 
c     a number of bits multiple of 16
      l_tra = ior(ishft(iand(header(2),z'03ff')
     $     ,10),iand(header(3),z'03ff'))
      l_tra=l_tra-13            
C     ------------------------------------------------------
      eventn_dat = ior(ishft(iand(header(4),z'03ff')
     $     ,10),iand(header(5),z'03ff'))
      nclust_dat = ishft(iand(header(6),z'0380'),-7)
      cutc_dat = ishft(iand(header(6),z'0070'),-4)
      cutcl_dat = iand(header(6),z'000f')
      addrcluster_dat(1) = iand(header(7),z'03ff')
      signcluster_dat(1) = iand(header(8),z'03ff')
      addrcluster_dat(2) = iand(header(9),z'03ff')
      signcluster_dat(2) = iand(header(10),z'03ff')
      addrcluster_dat(3) = iand(header(11),z'03ff')
      signcluster_dat(3) = iand(header(12),z'03ff')
      fc_dat = ishft(iand(header(13),z'0300'),-8)
      compressiontime_dat = iand(header(13),z'00ff')
      fl5_dat = ishft(iand(header(14),z'0300'),-8)
      fl4_dat = ishft(iand(header(14),z'0300'),-6)
      fl3_dat = ishft(iand(header(14),z'0300'),-4)
      fl2_dat = ishft(iand(header(14),z'0300'),-2)
      fl1_dat = iand(header(14),z'0300')
      fl6_dat = ishft(iand(header(15),z'0300'),-8)
      checksum_dat = iand(header(15),z'00ff') 
c-----------------------------------------------------------
c     the cheacksum is a 8-bit word calculated as the 
c     XOR of the 16-bit data words,
c     hence the XOR between the two halfs
C----------------------------------------------------------
      runerror=0
      nqualcosa=0
      if(l_tra.eq.0)then 
c         call skipbyte(ffd)
         goto 18                !empty buffer
      endif
      call dunpacker(l_tra,b_tra,runerror,ffd)
      nqualcosa = (real(l_tra))/13*16
      xx = b_tra(nqualcosa)
      if (xx.eq.0) nqualcosa=nqualcosa -1
      
 18   datalength_dat= nqualcosa
 
c$$$      TOTDATAlength = TOTDATAlength + datalength_dat
c$$$      do i=1,datalength_dat  
c$$$         id = id + 1
c$$$         datatracker(id) = b_tra(i)
c$$$      enddo



 11   format(i1,'   ',z4)
c     write(*,11)il,word
      call readtrailer(trailer,runerror,ffd)
c$$$      do i=1,3
c$$$         write(*,12)trailer(i)
c$$$      enddo
      
***************************************************************      
*                      TRAILER                                *
***************************************************************

      pnum_dat=ishft(iand(trailer(1),z'f000'),-12)
      cmdnum_dat=ishft(iand(trailer(1),z'0f00'),-8)
      bid1_dat=ishft(iand(trailer(1),z'00c0'),-6)
      bid2_dat=ishft(iand(trailer(1),z'0030'),-4)
      bid3_dat=ishft(iand(trailer(1),z'000c'),-2)
      bid4_dat=iand(trailer(1),z'0003')
      bid5_dat=ishft(iand(trailer(2),z'c000'),-14)
      bid6_dat=ishft(iand(trailer(2),z'3000'),-12)
      bid7_dat=ishft(iand(trailer(2),z'0c00'),-10)
      alarm_dat=ishft(iand(trailer(2),z'0300'),-8)   
      aswr_dat=ior(ishft(iand(trailer(2),z'00ff'),8)
     $      ,ishft(iand(trailer(3),z'ff00'),-8))
      crc_dat=iand(trailer(3),z'00ff')

      bid_dat_sum = (bid1_dat + bid2_dat + bid3_dat + bid4_dat +
     &     bid5_dat + bid6_dat + bid7_dat) 

      bid_dat = bid_dat_sum/7

      if (bid_dat.ne.1.and.bid_dat.ne.2) then
c      write(*,*) '*** *** *** *** *** *** *** *** *** ***'
c      write (*,*) 'unpack_data: TRAILER PACKET CORRUPTED - BID '
c     $     ,bid_dat
c      write(*,*) '*** *** *** *** *** *** *** *** *** ***'
      endif
      if (mod(bid_dat_sum,7).ne.0) then
         bid_dat = 0
c         write(*,*) '*** *** *** *** *** *** *** *** *** ***'
c         write (*,*) 'unpack_data: TRAILER PACKET CORRUPTED - BID '
c     $        ,bid_dat
c         write(*,*) '*** *** *** *** *** *** *** *** *** ***'
      endif
      
      if (alarm_dat.eq.3) then
c         write(*,*) '*** *** *** *** *** *** *** *** *** ***'
c         write(*,*) 'unpack_data: AQUISITION ALARM'
c         write(*,*) '*** *** *** *** *** *** *** *** *** ***'         

      endif
       
         if (alarm_dat.ne.3.and.alarm_dat.ne.0) then
c         write(*,*) '*** *** *** *** *** *** *** *** *** ***'
c         write(*,*) 'unpack_data: TRAILER PACKET CORRUPTED - ALARM '
c     $        ,alarm_dat
c         write(*,*) '*** *** *** *** *** *** *** *** *** ***'         

      endif

      
      return
      end


*.............................................................................
      subroutine initlevel0
      
       include '../commonyoda/level0.f'


      do i=1, nviews
         
         DAQmode(i) = 0
         DSPnumber(i) = 0
         eventn(i) = 0
         nclust(i) = 0
         cutc(i) = 0
         cutcl(i) = 0
         addrcluster(i,1) = 0
         signcluster(i,1) = 0
         addrcluster(i,2) = 0
         signcluster(i,2) = 0
         addrcluster(i,3) = 0
         signcluster(i,3) = 0
         fc(i) = 0
         compressiontime(i) = 0
         fl5(i) = 0
         fl4(i) = 0 
         fl3(i) = 0  
         fl2(i) = 0  
         fl1(i) = 0  
         fl6(i) = 0  
         checksum(i) = 0
         DATAlength(i) = 0
         pnum(i)= 0
         cmdnum(i)= 0
         bid(i) = 1 
         alarm(i)= 0
         aswr(i) = 0
      enddo

      TOTDATAlength = 0
      good0=.true.

      return
      end


*     *** *** *** *** *** *** *** *** *** 
*
*
*
*
*
*
*     *** *** *** *** *** *** *** *** *** 
      subroutine fillview(i)
c     -----------------------------------------------------
c     fill variables related to view i
c     which will be stored in the level0 nt-ple
c     at the end of loop on views
c     ----------------------------------------------------

      include '../commonyoda/commontracker.f'
      include '../commonyoda/level0.f'
      include '../commonyoda/dataformat.f'

      logical DEBUG
      common/DEBUGflag/DEBUG


      DAQmode(i) = DAQmode_dat
      DSPnumber(i) =  DSPnumber_dat
      eventn(i) = eventn_dat
      nclust(i) = nclust_dat
      cutc(i) = cutc_dat
      cutcl(i) = cutcl_dat
      addrcluster(i,1) = addrcluster_dat(1)
      signcluster(i,1) = signcluster_dat(1)
      addrcluster(i,2) = addrcluster_dat(2)
      signcluster(i,2) = signcluster_dat(2)
      addrcluster(i,3) = addrcluster_dat(3)
      signcluster(i,3) = signcluster_dat(3)
      fc(i) = fc_dat
      compressiontime(i) = compressiontime_dat
      fl5(i) = fl5_dat
      fl4(i) = fl4_dat
      fl3(i) = fl3_dat  
      fl2(i) = fl2_dat
      fl1(i) = fl1_dat
      fl6(i) = fl6_dat
      checksum(i) = checksum_dat
      DATAlength(i) = datalength_dat

c    -----------------------------------------------------------------------
c     filling TRAILER variables
c     ----------------------------------------------------------------------

      pnum(i)= pnum_dat
      cmdnum(i)= cmdnum_dat
      bid(i) = bid_dat 
      alarm(i)= alarm_dat
      aswr(i) = aswr_dat

      if(DEBUG)then

         print*,'*-*-*-*-*-*-TRAILER-*-*-*-*-*-*'
         print*,'*  PNUM   (periferal num) ',pnum_dat
         print*,'*  CMDNUM (command)       ',cmdnum_dat
         print*,'*  BID    (board id)      ',bid_dat
         print*,'*  ALARM                  ',alarm_dat
         print*,'*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*'

      endif

      do idat=1,datalength_dat  
         id =  TOTDATAlength + idat
         datatracker(id) = b_tra(idat)
      enddo
      TOTDATAlength = TOTDATAlength + datalength_dat

c      print*,'TOTDATALENGTH ',TOTDATAlength 


      return
      end

