Module tdc_mod

module tdc_mod

        ! Uses
    use PRECISION_mod
    use det_geom_mod
    use chambers_mod

        ! Types
    public type tdc_TYPE
    public type tdc_SC_type
    public type tdcraw_TYPE
    public type adc_PC_type
    public type adc_SC_type
    public type whits_TYPE

        ! Variables
    integer (kind=i4), public, PARAMETER :: kMaxHitsPerWire = 10
    type (tdc_TYPE), private, POINTER :: niltdcP
    type (tdc_SC_type), private, POINTER :: niltdc_SCP
    type (whits_TYPE), private, POINTER :: nilwhitsP
    type (wire_TYPE), private, POINTER :: nilwireP
    type (scint_type), private, POINTER :: nilscintP
    type (adc_PC_type), private, POINTER :: niladc_PCP
    type (adc_SC_type), private, POINTER :: niladc_SCP

        ! Interfaces
    public interface sortwires
    public interface insert
    public interface remove_whit
    public interface tdc_clear
    public interface adc_clear

        ! Subroutines and functions
    public function tdcfill_DC_PC (tdc, ihits, whits, nphits, nwhits, wireP, iwire, time, width, iflag)
    public function tdcfill_SC (tdc, ihits, whits, nphits, nwhits, scintP, iwire, time, width, iflag)
    public function adcfill_PC (adc, ihits, whits, nphits, nwhits, wireP, iwire, time, width, e_lost, iflag)
    public function adcfill_SC (adc, ihits, whits, nphits, nwhits, scintP, iwire, time, width, e_lost, iflag)
    public subroutine SortWires (whits, nphits, nplanes, tdc)
    private subroutine SortWires1 (whits, N, tdc)
    public function insert_whit_DC_PC (ihit, whit, tdc, nphits)
    public function insert_whit_SC (ihit, whit, tdc, nphits)
    public function insert_whit_adc_PC (ihit, whit, adc, nphits)
    public function insert_whit_adc_SC (ihit, whit, adc, nphits)
    public function insert_whit1 (ihit, whits, nphits, iwire)
    public function insert_sorted (ihit, whits, nphits, iwire)
    public function remove_whit0 (hit, whits, nphits)
    public function remove_whit1 (hit, whits, tdc, nphits, nwhits)
    public function remove_whit2 (hit, whits, nphits, nwhits)
    public function next (whits, nphits, iplane, iwire)
    public function tdc_init (whits, nwhits)
    public function tdc_clear_DC_PC (tdc, ihits, nwhits, nphits, nplanes)
    public function tdc_clear_SC (tdc, ihits, nwhits, nphits, nscints)
    public function adc_clear_PC (adc, ihits, nwhits, nphits, nplanes)
    public function adc_clear_SC (adc, ihits, nwhits, nphits, nscints)

end module tdc_mod
---------------------------------------------------------------------
     Objects containing TDC info  for dc's and pc's 
     tdc   winfo whits ihits 
    Together with routines that fill and list these objects 
     Decode TDC  DATA from 1877 TDC
---------------------------------------------------------------------
     Input:
       PRINT-LOG*4  - PRINT flag (TRUE = PRINT on, FALSE = PRINT off)
     RETURN Status code :
                      0 = no problems
                      1 = fatal problem, no DATA available 
                      2 = DATA FORMAT error, some DATA might be available
                      3 = DATA size too large, DATA was truncated
---------------------------------------------------------------------
   Modified and expanded : 23-oct-1998 Renee Poutissou  
  F90 version with new data structures 16- Jul-1999 Art Olin 
------------------------------------------------------------------

Author: Art Olin, Renee Poutissou


Description of Types

tdc_TYPE

public type tdc_TYPE
    real (kind=R4) :: time
    real (kind=R4) :: width
    integer (kind=I4) :: flag
    type (whits_TYPE), POINTER :: whitsP
    type (wire_TYPE), POINTER :: wireP
end type tdc_TYPE

tdc_SC_type

public type tdc_SC_type
    real (kind=r4) :: time
    real (kind=r4) :: width
    integer (kind=i4) :: flag
    type (whits_TYPE), POINTER :: whitsP
    type (scint_TYPE), POINTER :: scintP
end type tdc_SC_type

tdcraw_TYPE

public type tdcraw_TYPE
    integer (kind=I4) :: time
    integer (kind=I4) :: width
    integer (kind=I4) :: plane
    integer (kind=I4) :: wire
    integer (kind=I4) :: slot
    integer (kind=I4) :: channel
    integer (kind=I4) :: flag
end type tdcraw_TYPE

adc_PC_type

public type adc_PC_type
    integer :: time
    integer :: width
    integer :: flag
    real (kind=r4) :: e_lost
    type (whits_type), POINTER :: whitsP
    type (wire_type), POINTER :: wireP
end type adc_PC_type

adc_SC_type

public type adc_SC_type
    integer :: time
    integer :: width
    integer (kind=i4) :: flag
    real (kind=r4) :: e_lost
    type (whits_type), POINTER :: whitsP
    type (scint_type), POINTER :: scintP
end type adc_SC_type

whits_TYPE

public type whits_TYPE
    integer (kind=i4) :: nhits
    integer (kind=i4), dimension (kMaxHitsPerWire) :: hits
    integer (kind=I4) :: iwire
end type whits_TYPE

Description of Variables

kMaxHitsPerWire

integer (kind=i4), public, PARAMETER :: kMaxHitsPerWire = 10

niltdcP

type (tdc_TYPE), private, POINTER :: niltdcP

niltdc_SCP

type (tdc_SC_type), private, POINTER :: niltdc_SCP

nilwhitsP

type (whits_TYPE), private, POINTER :: nilwhitsP

nilwireP

type (wire_TYPE), private, POINTER :: nilwireP

nilscintP

type (scint_type), private, POINTER :: nilscintP

niladc_PCP

type (adc_PC_type), private, POINTER :: niladc_PCP

niladc_SCP

type (adc_SC_type), private, POINTER :: niladc_SCP

Description of Interfaces

sortwires

public interface sortwires
    module procedure sortwires
    module procedure sortwires1
end interface sortwires

insert

public interface insert
    module procedure insert_whit_DC_PC
    module procedure insert_whit_SC
    module procedure insert_whit1
    module procedure insert_whit_ADC_PC
    module procedure insert_whit_ADC_SC
end interface insert

remove_whit

public interface remove_whit
    module procedure remove_whit0
    module procedure remove_whit1
    module procedure remove_whit2
end interface remove_whit

tdc_clear

public interface tdc_clear
    module procedure tdc_clear_DC_PC
    module procedure tdc_clear_SC
end interface tdc_clear

adc_clear

public interface adc_clear
    module procedure adc_clear_PC
    module procedure adc_clear_SC
end interface adc_clear

Description of Subroutines and Functions

tdcfill_DC_PC

public function tdcfill_DC_PC (tdc, ihits, whits, nphits, nwhits, wireP, iwire, time, width, iflag)
    type (tdc_TYPE), INTENT(inout), dimension (:) :: tdc
    integer (kind=I4), INTENT(inout) :: ihits
    type (whits_TYPE), INTENT(inout), TARGET, dimension (:) :: whits
    integer (kind=I4), INTENT(inout) :: nphits
    integer (kind=I4), INTENT(inout) :: nwhits
    type (wire_TYPE), POINTER :: wireP
    integer (kind=I4), INTENT(IN) :: iwire
    real (kind=R4), INTENT(in) :: time
    real (kind=R4), INTENT(in) :: width
    integer (kind=I4), INTENT(IN) :: iflag
    integer (kind=i4) :: tdcfill_DC_PC
    ! Calls: kerror
end function tdcfill_DC_PC
========================================================================
 Fill tdc and whits from do_record
 Whits structures now sorted by wire ascending
 AO mod July 2002
========================================================================

Author: Art Olin

Version: July 2002

tdcfill_SC

public function tdcfill_SC (tdc, ihits, whits, nphits, nwhits, scintP, iwire, time, width, iflag)
    type (tdc_SC_type), INTENT(inout), dimension (:) :: tdc
    integer (kind=i4), INTENT(inout) :: ihits
    type (whits_type), INTENT(inout), TARGET, dimension (:) :: whits
    integer (kind=i4), INTENT(inout) :: nphits
    integer (kind=i4), INTENT(inout) :: nwhits
    type (scint_type), POINTER :: scintP
    integer (kind=i4), INTENT(in) :: iwire
    real (kind=r4), INTENT(in) :: time
    real (kind=r4), INTENT(in) :: width
    integer (kind=i4), INTENT(in) :: iflag
    integer (kind=i4) :: tdcfill_SC
    ! Calls: kerror
end function tdcfill_SC

adcfill_PC

public function adcfill_PC (adc, ihits, whits, nphits, nwhits, wireP, iwire, time, width, e_lost, iflag)
    type (adc_PC_TYPE), INTENT(inout), dimension (:) :: adc
    integer (kind=I4), INTENT(inout) :: ihits
    type (whits_TYPE), INTENT(inout), TARGET, dimension (:) :: whits
    integer (kind=I4), INTENT(inout) :: nphits
    integer (kind=I4), INTENT(inout) :: nwhits
    type (wire_TYPE), POINTER :: wireP
    integer (kind=I4), INTENT(IN) :: iwire
    integer (kind=I4), INTENT(IN) :: time
    integer (kind=I4), INTENT(IN) :: width
    real (kind=R4), INTENT(in) :: e_lost
    integer (kind=I4), INTENT(IN) :: iflag
    integer (kind=i4) :: adcfill_PC
    ! Calls: kerror
end function adcfill_PC

adcfill_SC

public function adcfill_SC (adc, ihits, whits, nphits, nwhits, scintP, iwire, time, width, e_lost, iflag)
    type (adc_SC_type), INTENT(inout), dimension (:) :: adc
    integer (kind=i4), INTENT(inout) :: ihits
    type (whits_type), INTENT(inout), TARGET, dimension (:) :: whits
    integer (kind=i4), INTENT(inout) :: nphits
    integer (kind=i4), INTENT(inout) :: nwhits
    type (scint_type), POINTER :: scintP
    integer (kind=i4), INTENT(in) :: iwire
    integer (kind=i4), INTENT(in) :: time
    integer (kind=i4), INTENT(in) :: width
    real (kind=r4), INTENT(in) :: e_lost
    integer (kind=i4), INTENT(in) :: iflag
    integer (kind=i4) :: adcfill_SC
    ! Calls: kerror
end function adcfill_SC

SortWires

public subroutine SortWires (whits, nphits, nplanes, tdc)
    type (Whits_TYPE), INTENT(INOUT), dimension (:,:) :: whits
    integer (kind=I4), INTENT(IN), dimension (:) :: nphits
    integer (kind=I4), INTENT(IN) :: nplanes
    type (tdc_type), INTENT(INOUT), dimension (:) :: tdc
    ! Calls: sortwires1
end subroutine SortWires
 ===============================================================
  Date: December 15, 1999.
 ---------------------------------------------------------------
  Description:

   Sort the wire numbers in the structure DCWhits and PCWhits in
   assending order. This is useful later on for checking whether
   the hit wires are adjacent for purposed of cross talk studies
   and pattern recognition. Adapted from Numerical Recipes.
  AO ADDED LAYER SO SINGLE PLANE OF WHITS COULD BE SORTED ALSO 
  ML Added tdc argument so whitsP pointers are updated too.
 ===============================================================

Author: Maher Quraan

Version: 2.0

SortWires1

private subroutine SortWires1 (whits, N, tdc)
    type (Whits_TYPE), INTENT(INOUT), TARGET, dimension (:) :: whits
    integer (kind=i4), INTENT(IN) :: N
    type (tdc_type), INTENT(INOUT), dimension (:) :: tdc
end subroutine SortWires1
FOR ONE PLANE

insert_whit_DC_PC

public function insert_whit_DC_PC (ihit, whit, tdc, nphits)
    integer (kind=i4), INTENT(in) :: ihit
    type (whits_TYPE), INTENT(inout), dimension (:,:) :: whit
    type (tdc_TYPE), INTENT(in) :: tdc
    integer (kind=i4), INTENT(inout), dimension (:) :: nphits
    integer (kind=i4) :: insert_whit_DC_PC
end function insert_whit_DC_PC
==============================================================
Description:  Insert hit into  whit_type (plane:wire) structure 
and update counters. Tdc(ihit) is also passed. This
pair of routines are defined as a generic insert function.
================================================================ 

Author: Art Olin

insert_whit_SC

public function insert_whit_SC (ihit, whit, tdc, nphits)
    integer (kind=i4), INTENT(in) :: ihit
    type (whits_type), INTENT(inout), dimension (:,:) :: whit
    type (tdc_SC_type), INTENT(in) :: tdc
    integer (kind=i4), INTENT(inout), dimension (:) :: nphits
    integer (kind=i4) :: insert_whit_SC
end function insert_whit_SC

insert_whit_adc_PC

public function insert_whit_adc_PC (ihit, whit, adc, nphits)
    integer (kind=i4), INTENT(in) :: ihit
    type (whits_TYPE), INTENT(inout), dimension (:,:) :: whit
    type (adc_PC_TYPE), INTENT(in) :: adc
    integer (kind=i4), INTENT(inout), dimension (:) :: nphits
    integer (kind=i4) :: insert_whit_adc_PC
end function insert_whit_adc_PC

insert_whit_adc_SC

public function insert_whit_adc_SC (ihit, whit, adc, nphits)
    integer (kind=i4), INTENT(in) :: ihit
    type (whits_type), INTENT(inout), dimension (:,:) :: whit
    type (adc_SC_type), INTENT(in) :: adc
    integer (kind=i4), INTENT(inout), dimension (:) :: nphits
    integer (kind=i4) :: insert_whit_adc_SC
end function insert_whit_adc_SC

insert_whit1

public function insert_whit1 (ihit, whits, nphits, iwire)
    integer (kind=i4), INTENT(in) :: ihit
    type (whits_TYPE), INTENT(inout), TARGET, dimension (:) :: whits
    integer (kind=i4), INTENT(inout) :: nphits
    integer (kind=i4), INTENT(inout) :: iwire
    integer (kind=i4) :: insert_whit1
    ! Calls: kerror
end function insert_whit1
==============================================================
Description:   Insert hit into a single whit_type plane and wire.
Update counters. Callable separately or from insert_whit. This
pair of routines are defined as a generic insert function.
ML July 2002.  This routine is currently used to insert 
a hit in the windowing whits structures. NOT sorted by wire order.

Author: rewritten by K.Olchanski. Original author: Art Olin

insert_sorted

public function insert_sorted (ihit, whits, nphits, iwire)
    integer (kind=i4), INTENT(in) :: ihit
    type (whits_TYPE), INTENT(inout), TARGET, dimension (:) :: whits
    integer (kind=i4), INTENT(inout) :: nphits
    integer (kind=i4), INTENT(inout) :: iwire
    integer (kind=i4) :: insert_sorted
    ! Calls: kerror
end function insert_sorted
==============================================================
ML July 2002. Copied from insert_whit1 and tdcfill_dc_pc.  
 Same as insert_whit1, but sorted by wire number.  
 Used for PCs in windowing.

remove_whit0

public function remove_whit0 (hit, whits, nphits)
    integer (kind=i4), INTENT(in) :: hit
    type (whits_TYPE), INTENT(inout), TARGET, dimension (:) :: whits
    integer (kind=i4), INTENT(inout) :: nphits
    integer (kind=i4) :: remove_whit0
end function remove_whit0
 =====================================================================
Description:
Remove a hit from a whits structure
 hit  - hit to be removed
 whits - whit index for hit plane
 nphits - hit wires counter (in one plane)
 Return 0 success -1 failure

 Function for when there is no pointer back to whits to update
 when removing hit from window or track whits substructure
 =====================================================================

Author: Art Olin

Version: 2.1

remove_whit1

public function remove_whit1 (hit, whits, tdc, nphits, nwhits)
    integer (kind=i4), INTENT(in) :: hit
    type (whits_TYPE), INTENT(inout), TARGET, dimension (:) :: whits
    type (tdc_type), INTENT(inout), dimension (:) :: tdc
    integer (kind=i4), INTENT(inout) :: nphits
    integer (kind=i4), INTENT(inout) :: nwhits
    integer (kind=i4) :: remove_whit1
end function remove_whit1
 =====================================================================
 Added June 28 2001
Description:
Remove a hit from a whits structure
 hit  - hit to be removed
 whits - whit index for hit plane
 tdc - tdc structure (dc or pc)
 nphits - hit wires counter (in one plane)
 nWhits - total hit wires counter
 nHits - total hits counter
 Return 0 success -1 failure
 Repoints the dctdc pointers !Not needed for window whits structures, etc
 where there is no pointer back to whits
 =====================================================================

Author: Art Olin

Version: 2.1

remove_whit2

public function remove_whit2 (hit, whits, nphits, nwhits)
    integer (kind=i4), INTENT(in) :: hit
    type (whits_TYPE), INTENT(inout), TARGET, dimension (:) :: whits
    integer (kind=i4), INTENT(inout) :: nphits
    integer (kind=i4), INTENT(inout) :: nwhits
    integer (kind=i4) :: remove_whit2
    ! Calls: kerror
end function remove_whit2
 =====================================================================
 Added July 11 2002 by Marc Lalancette
 Same as previous without adjusting tdc pointers. This is needed when looking
 for Xtalk in a specific window, because the tdc pointers are associated to 
 the main Whits structures, not the ones in windows.
 =====================================================================

next

public function next (whits, nphits, iplane, iwire)
    type (whits_type), INTENT(in), dimension (:,:) :: whits
    integer (kind=i4), INTENT(in), dimension (:) :: nphits
    integer (kind=i4), INTENT(inout) :: iplane
    integer (kind=i4), INTENT(inout) :: iwire
    integer (kind=i4) :: next
end function next
 =====================================================================
Description:
Functions to traverse whits structure in plane,wire order
 Wouldn't this be faster with a linked list
 Not presently used because I expect very inefficient
==============================================================

Author: Art Olin

Version: 2.1

tdc_init

public function tdc_init (whits, nwhits)
    type (whits_TYPE), INTENT(out), dimension (:,:) :: whits
    integer, INTENT(out) :: nwhits
    integer :: tdc_init
end function tdc_init

tdc_clear_DC_PC

public function tdc_clear_DC_PC (tdc, ihits, nwhits, nphits, nplanes)
    type (tdc_TYPE), INTENT(inout), dimension (:) :: tdc
    integer (kind=i4), INTENT(inout) :: ihits
    integer (kind=i4), INTENT(inout) :: nwhits
    integer (kind=i4), INTENT(inout), dimension (:) :: nphits
    integer (kind=i4), INTENT(in) :: nplanes
    integer (kind=i4) :: tdc_clear_DC_PC
end function tdc_clear_DC_PC

tdc_clear_SC

public function tdc_clear_SC (tdc, ihits, nwhits, nphits, nscints)
    type (tdc_SC_type), INTENT(inout), dimension (:) :: tdc
    integer (kind=i4), INTENT(inout) :: ihits
    integer (kind=i4), INTENT(inout) :: nwhits
    integer (kind=i4), INTENT(inout), dimension (:) :: nphits
    integer (kind=i4), INTENT(in) :: nscints
    integer (kind=i4) :: tdc_clear_SC
end function tdc_clear_SC

adc_clear_PC

public function adc_clear_PC (adc, ihits, nwhits, nphits, nplanes)
    type (adc_PC_TYPE), INTENT(inout), dimension (:) :: adc
    integer (kind=i4), INTENT(inout) :: ihits
    integer (kind=i4), INTENT(inout) :: nwhits
    integer (kind=i4), INTENT(inout), dimension (:) :: nphits
    integer (kind=i4), INTENT(in) :: nplanes
    integer (kind=i4) :: adc_clear_PC
end function adc_clear_PC

adc_clear_SC

public function adc_clear_SC (adc, ihits, nwhits, nphits, nscints)
    type (adc_SC_type), INTENT(inout), dimension (:) :: adc
    integer (kind=i4), INTENT(inout) :: ihits
    integer (kind=i4), INTENT(inout) :: nwhits
    integer (kind=i4), INTENT(inout), dimension (:) :: nphits
    integer (kind=i4), INTENT(in) :: nscints
    integer (kind=i4) :: adc_clear_SC
end function adc_clear_SC