function sot_bitcomp, data, lut, version=progver, name=prognam, verbose=verbose

;+
; NAME:
;       SOT_BITCOMP
;
; PURPOSE:
;       Apply MDP bit compression to raw SOT data.
;
; CATEGORY:
;	Engineering
;
; SAMPLE CALLING SEQUENCE:
;	DATA_OUT = SOT_BITCOMP(DATA_IN, N_LUT $
;                     [, /VERBOSE, NAME=NAME, VERSION=VERSION])
;
; INPUTS:
;	DATA_IN	  - Input data (any dimension)
;	N_LUT	  - Bit compression Look-Up-Table number. 
;                   0: no compression
;                   1: 16U   -> 12U
;                   2: 14U   -> 12U
;                   3: 16S   -> 12U
;                   4: 14.5S -> 12U
;                   5: 13S   -> 12U
;                   6: 12U   -> 12U
;
; OUTPUTS:
;       DATA_OUT  - Output data
;
; OPTIONAL INPUT KEYWORD PARAMETERS: 
;	VERBOSE   - Set for a few more messages
;
; OUTPUT KEYWORD PARAMETERS: 
;	VERSION   - The current version number of the program
;       NAME      - The name of this routine
;
; MODIFICATION HISTORY:
;V1.0 20-Feb-2008. Created   YK
;
;-

prognam = 'SOT_BITCOMP.PRO'
progver = 'V1.0'

loud = 0b
if KEYWORD_SET(verbose) then loud = 1b

; Check LUT number input
IF (lut lt 0) or (lut ge 7) then begin
    MESSAGE, 'The look-up-table number is out of range!',/cont
    MESSAGE, 'Return the original data as is.',/cont
    RETURN, data
ENDIF

CASE lut OF
    0: str = 'No compression'
    1: begin ; '16U->12U
        s = 0b
        f = 0b
        u = 4095l
        a = 1087d/4
        b = 3588d/16
        c = -1176712d/16
        d = 384l
        str = '16U->12U'
    end
    2: begin ; 14U->12U
        s = 0b
        f = 0b
        u = 4095l
        a = 943./4
        b = 14981d/16
        c = -7039978d/16
        d = 704l
        str = '14U->12U'
    end
    3: begin ; 16S->12U
        s = 1b
        f = 0b
        u = 4095l
        a = 2431d/4
        b = 1033d/16
        c = -644163d/16
        d = 640l
        str = '16S->12U'
    end
    4: begin ; 14.5S->12U
        s = 1b
        f = 0b
        u = 4095l
        a = 2144d/4
        b = 3326d/16
        c = -1955756d/16
        d = 640l
        str = '14.5S->12U'
    end
    5: begin ; 13S->12U
        s = 1b
        f = 0b
        u = 4095l
        a = 3072d/4
        b = 8192d/16
        c = -7340032d/16
        d = 1024l
        str = '13S->12U'
    end
    6: begin ; 12U->12U
        s = 0b
        f = 0b
        u = 4095l
        a = 16380d/4
        b = 0d
        c = 0d
        d = 4095l
        str = '12U->12U'
    end
ENDCASE

IF loud THEN begin
    MESSAGE, /info,'Bit compression LUT: #'+string(lut,form='(I1)') $
      +' ('+str+')'
endif

; If LUT#0, return the original data
IF lut eq 0 then return, data

; output
data_out = uint(data)

; linear region
ss0 = where(abs(data) le d, ns0, comp = ss1, ncomp=ns1)
if ns0 ge 1 then data_out[ss0] = ishft(abs(data[ss0]),-1*f)

; sqrt region
if ns1 ge 1 then data_out[ss1] = round((4.*sqrt(b*abs(data[ss1])+c)+4.*a)/4.)

; check upperlimit
ss = where(data_out ge u, ns)
if ns ge 1 then data_out[ss] = u

; check sign
if s then begin
    ss0= where(data ge 0, ns0, comp=ss1, ncomp=ns1)
    if ns0 ge 1 then data_out[ss0] = (data_out[ss0]+2048)<4095
    if ns1 ge 1 then data_out[ss1] = (2048-data_out[ss1])>0
endif

return, data_out

end