/* **********************************************************************
 * *                                                                    *
 * *   Common Structure & Memory Definitions for RVP8/Proc Processes    *
 * *                                                                    *
 * **********************************************************************
 * File: include/rvp8proc.h
 *
 *                     COPYRIGHT (c) 2002, 2003  BY
 *          SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 */
#ifndef SIGMET_RVP8PROC_H
#define SIGMET_RVP8PROC_H 1

/* *******************************
 * *                             *
 * * Message Catalog Definitions *
 * *                             *
 * *******************************
 */
#define      NOPROCSLOT        1
#define PROC_NOPROCSLOT       (RVP8PROC_FACILITY + NOPROCSLOT)
#define      BADCMDNUM         2
#define PROC_BADCMDNUM        (RVP8PROC_FACILITY + BADCMDNUM)
#define      MMINITNOTNULL     3
#define PROC_MMINITNOTNULL    (RVP8PROC_FACILITY + MMINITNOTNULL)
#define      MMEXITWHENNULL    4
#define PROC_MMEXITWHENNULL   (RVP8PROC_FACILITY + MMEXITWHENNULL)
#define      PSINITNOTIDLE     5
#define PROC_PSINITNOTIDLE    (RVP8PROC_FACILITY + PSINITNOTIDLE)
#define      PSEXITWHENIDLE    6
#define PROC_PSEXITWHENIDLE   (RVP8PROC_FACILITY + PSEXITWHENIDLE)
#define      PULSECNTERR       7
#define PROC_PULSECNTERR      (RVP8PROC_FACILITY + PULSECNTERR)
#define      PRVSHRSYNC        8
#define PROC_PRVSHRSYNC       (RVP8PROC_FACILITY + PRVSHRSYNC)
#define      EXITREQUEST       9
#define PROC_EXITREQUEST      (RVP8PROC_FACILITY + EXITREQUEST)
#define      EXITFORCE        10
#define PROC_EXITFORCE        (RVP8PROC_FACILITY + EXITFORCE)

#ifndef MESSAGE_ONLY                      

/* *************************************
 * *                                   *
 * *  Local Parameters and Structures  *
 * *                                   *
 * *************************************
 */
/* Include the small IPP header definitions (but not the huge list of
 * IPP prototypes) so that we can freely reference its structures and
 * typedefs in all of the RVP8 prototypes.
 */
#include "ippdefs.h"

/* Check compilation flags
 */
#ifndef STRUCTMAP  /* Skip during 'structmap' invocations */

#ifndef _REENTRANT
#error Missing _REENTRANT symbol required by pthreads
#endif

#ifdef SIGMET_DSP_LIB_H
#error RVP8/Proc must not be compiled with dsp_lib.h
#endif

#if defined(SIGMET_RVP8MAIN_H) || defined(RVP8MAIN)
#error RVP8/Proc must not be included in RVP8/Main build
#endif

#endif /* #ifndef STRUCTMAP */

/* Special profiling support required by pthreads
 */
#ifdef __PROFILING		/* See rda/rdasubs/threads.c */
#define pthread_create gprof_pthread_create
#define LPROFILING TRUE
#else
#define LPROFILING FALSE
#endif

#define DEBUG_SIGNAL_HANDLER  0 /* Debug signal handler hits */
#define DEBUG_INITEXIT        0	/* Major mode and PROC section INIT/EXIT */

/* **************************************************
 * *                                                *
 * *  Structures and Parameters only for RVP8/Proc  *
 * *                                                *
 * **************************************************
 */
/* ------------------------------
 * Fundamental autocorrelation and moment structures.  Note that the
 * processing code will often assume that all of the elements of all
 * of these structures are FLT4 (or IPP equivalent), and that term by
 * term FLT4 summation always makes sense.
 */
struct ctBinMomRaw {		/* Basic moment info for raw input bins */
  FLT4 t0, r0 ;			/*   Total power, Filtered power */
  Ipp32fc rCors[NBINMOMCORS] ;	/*   Complex correlations R1,R2... */
} ;
/* Additional moments required during polarization modes.  These are
 * further broken down according to the Tx/Rx style being used.
 */
struct ctBinPolRawFix {		/* Fixed H or V transmission */
  struct ctBinMomRaw Mco, Mcx ;	/*   Moments for Co/Cross Rx channels */
  Ipp32fc CxCo ;		/*   Sum of (Cross x Co*) */
} ;
struct ctBinPolRawStar {        /* Simultaneous H and V transmission */
  struct ctBinMomRaw Mhh, Mvv ;	/*   Moments for VV and HH (Co) channels */
  Ipp32fc VvHh ;		/*   Sum of (Svv x Shh*) */
} ;
struct ctBinPolRawAlt {	        /* Alternating H and V transmission */
  struct ctBinMomRaw Mhh, Mvv ;	/*   Moments for VV and HH (Co) channels */
  struct ctBinMomRaw Mvh, Mhv ;	/*   Moments for VH and HV (Cx) channels */
  Ipp32fc CxCo[2] ;		/*   Sum of (Cross x Co*) for each Tx */
  Ipp32fc Rab[2] ;		/*   Sum of (Svv x Shh*) & (Shh x Svv*) */
  Ipp32fc Rho2T ; 		/*   Sum of (Co[n] x Co[n-2]*), both Tx's combined */
} ;
union ctBinPolRaw {		/* Basic moment info at one raw input bin */
  struct ctBinPolRawFix  Fix ;	/*   Fixed transmit case */
  struct ctBinPolRawStar Star ;	/*   Simultaneous H&V case */
  struct ctBinPolRawAlt  Alt ;	/*   Alternating case */
} ;

/* ------------------------------
 * Intermediate results computed for one bin during Random Phase (and
 * related) processing modes.
 */
struct rphBinMomRaw {
  /* The following autocorrelation results are produced from the raw
   * time series in the alternate trip.
   */
  struct ctBinMomRaw Alt ;

  /* The following autocorrelation results for the current trip are
   * produced from the adaptive filtering and recohering process.
   */
  struct ctBinMomRaw Cur ;

  FLT4 fKill ;	   /* Fraction of spectrum that has been 'whitened' */
} ;

/* ------------------------------
 * Scientific output parameter structures and intermediate conversion
 * structures.
 */
struct ctSciBinMom {		/* BinMoments prepared for scientific conversions */
  FLT4 t0, r0 ;			/*   Total power, Filtered power */
  FLT4 rMags[NBINMOMCORS] ;	/*   Magnitudes of R1,R2... */
  FLT4 rPhases[NBINMOMCORS] ;	/*   Phase angles (radians) of R1,R2... */
} ;
struct velQual {		/* Qualified velocity, as binary angle */
  BIN2  iVel ;			/*   The velocity itself */
  UINT1 lOkay ;			/*   Flag indicating okay */
  char  pad3x1[1] ;
} ;
struct ctSciPrmTZVW {		/* Extracted T/Z/V/W scientific parameters */
  UINT1 ldBT_ok, ldBZ_ok ;	/*   Okay flags for most parameters */
  UINT1 lWidth_ok, lTotalSNR_ok, lFilterSNR_ok, pad5x3[3] ; 

  UINT1		                /*   Bit mask of thresholds passed (TCFBIT_xxx) */
    iTCFBits[ PPRMS_N_COUNT ] ;	/*     for each possible parameter type. */

  FLT4  fdBT ;			/*   Total power above noise, in dB */
  FLT4  fdBZ ;			/*   Clutter corrected and qualified dBT */
  FLT4  fWidth ;		/*   Spectral width on Nyquist interval */
  FLT4  fTotalSNR ;		/*   Total power above noise, as SNR in dB */
  FLT4  fFilterSNR ;		/*   Filtered power above noise, as SNR in dB */
  FLT4  fSQI ;			/*   Signal-Quality-Index (|R1|/R0) */

  struct velQual velocity ;	/*   Nyquist velocity (possibly unfolded) */
  struct velQual velOther ;	/*   Alternate velocity (usually from 'other' PRF) */
} ;

/* Additional scientific output parameters for polarization systems.
 * Not all of these slots may be used in a given Rx/Tx combination.
 */
struct ctSciPrmPolar {		/* Polarization scientific parameters */
  UINT1 lZdr_ok, lRhoHV_ok ;	/*   Okay flags for most of the parameters */
  UINT1 lKdp_ok, lLdrH_ok, lLdrV_ok, lRhoH_ok, lRhoV_ok ;
  char  pad7x1[1] ;

  FLT4 fZdr ;			/*   Differential reflectivity */
  FLT4 fRhoHV ;			/*   HH-VV correlation coefficient */
  FLT4 fPhiDP ;			/*   HH-VV differential phase  */
  FLT4 fKdp ;			/*   Specific differential phase */
  FLT4 fLdrH, fRhoH, fPhiH ;	/*   H-Chan depolarization and covariance */
  FLT4 fLdrV, fRhoV, fPhiV ;	/*   V-Chan depolarization and covariance */
} ;

/* ------------------------------
 * Special filtering structures
 */
struct winGaussClutterModel {
  FLT4 fClutterWidth ; SINT4 iWinType, iSpecSize, iMainLobePts ;
  FLT4 fModelPwr[ SPFILTMAXPTS ] ;
} ;

/* ------------------------------
 * Ray formatting and output structures
 */
struct paramFmtOne {		/* Control parameters for iFmtOneXXX() */
  UINT1 lSixteenBit ;		/*   Generate 16-bit data, else 8-bit */
  UINT1 lSpan180 ;		/*   For phase data, use 180-deg span */
  char  pad2x2[2] ;
  struct data_convert conv ;	/*   Unit conversion information */
} ;

typedef UINT2 outputFormatFloat_f( FLT4 fVal_a, const struct paramFmtOne *conv_a ) ;
typedef UINT2 outputFormatAngle_f( BIN2 iAng_a, const struct paramFmtOne *conv_a ) ;

#define PROCOUTPARAMS 		/* Output parameter pointer for PROC routines */ \
  ( &MM->out[ MM->procCPI.nCPIs % ORAYDEPTH ] )

/* ******************************************
 * *                                        *
 * * Common Memory Available to All Threads *
 * *                                        *
 * ******************************************
 */

/* ---------------------------- NOTE ----------------------------
 * All of the variables defined below are put here because they are
 * referenced by more than one thread.  Therefore, the 'volatile'
 * qualifier is the appropriate default in almost all cases.  The only
 * exceptions are variables that are known to be initialized only
 * once, and for which LIBC problems arise with the 'volatile' cast
 * (e.g. FILE*).
 */
#ifdef PROCOMMON_ALLOCATE
#define XM
#define VM volatile
#else
#define XM extern
#define VM extern volatile
#endif

/* ------------------------------
 * Pointers to the various shared memory segments are put in common so
 * that they are available to all threads.  These areas are writable
 * by all RVP8/Main threads, but often will be mapped read-only by
 * other processes that share the data.  We omit the "_c" suffixes
 * because these symbols are used in zillions of places.
 */
VM const struct rvp8Global * const GM ;
VM       struct rvp8MMProc * const MM ;

XM Rvp8TS *TS ;

/* ------------------------------
 * Process control
 */
VM UINT1 lQuitFlag_c ;		/* Request to quit this process */

XM UINT1 lHaveRootPrivs_c ;	/* We can get root privileges if needed */
XM SINT4 iProc_c ;		/* Our own process slot number */

/* -----------------------------------------------------------------
 * ------------ RVP8/Proc Callback Function Definitions ------------
 * -----------------------------------------------------------------
 *
 * Callback functions that are exclusively for RVP8/Proc.  These
 * consist mostly of the custom routines that should be called to
 * handle different stages of processing in the current major mode.
 * See also the generic major mode info in GM->MMode.
 */

/* Compute autocorrelation moments from timeseries data, including
 * all side effect results from those computations.  Note that the
 * BINMOMENTS phase uses a fixed distribution of range bins to each
 * processing thread based on how the (I,Q) data can be efficiently
 * extracted from the timeseries API.  Thus, no range information is
 * passed in here.
 *
 *    pHdrs[] : The timeseries pulse headers to be handled.
 *              Note that the 'volatile' attribute is stripped from
 *              the pulse headers at this point because this group
 *              is considered stable for the duration of processing.
 *
 *       EXIT : Mode-specific moment data written to privateData
 */
typedef void ( ctBinMoments_f )
     ( const struct rvp8PulseHdr *pHdrs_a[]
       ) ;

/* The remaining signal processing passes all use identical calling
 * conventions.  As each compute process enters a given pass it is
 * guaranteed that all other processors have entirely completed the
 * work for all previous passes.  This provides a simple mechanism
 * for allocating work that must be done in multiple phases to the
 * available processing threads.  Typically, there might be three
 * passes such as:
 *
 *   Extract scientific parameters from autocorrelation results at
 *   each range bin.
 *
 *   Carry out larger spatial algorithms that apply to complete
 *   rays, or to groups of rays.
 *
 *   Formatting of final parameter data that will be output to the
 *   host computer.
 */
typedef void ( ctAlgorPass_f )
     ( const struct ctRngInfo *RngInfo_a
       ) ;

/* Major mode definitions for the compute threads.
 */
struct rvp8ProcMajorMode {
  /* The following pointers define the custom memory segments that are
   * active for the current major mode.  The SHAREDDATA is shared and
   * writable by all compute processes, and is used to exchange data
   * among them.  The PRIVATEDATA is unique to each process.
   */
  void *privateData ;		/* ==> Data for this process only */

  void *sharedData ;		/* ==> Data shared among all processes */
  SINT4 sharedSize, sharedChan ;

  /* Exit routine to release resources (if any) when done we exit
   * entirely from the current major mode. See rvp8main.h for
   * additional notes.
   */
  void ( *exitMajorMode[MAXEXITDEPTH] )( void ) ;

  /* Pair of routines that will be called whenever the RVP8 enters and
   * exits active timeseries acquisition and processing.  See
   * rvp8main.h for additional notes.
   */
  void ( *initProcSection )( void ) ;
  void ( *exitProcSection )( void ) ;

  /* First pass BINMOMENTS processing phase, and list of subsequent
   * processing passes (all of which will be executed sequentially).
   */
  ctBinMoments_f *ctBinMoments ;
  ctAlgorPass_f  *ctAlgorPasses[ MAXALGORPASSES ] ;
} ;

XM struct rvp8ProcMajorMode MMode_c ;

/* ****************************************
 * *                                      *
 * *  RVP8/Proc/Core Function Prototypes  *
 * *                                      *
 * ****************************************
 */

/* --------------------- rvp8proc_main.c ---------------------
 */
int rvp8proc_main( int argc_a, char *argv_a[] ) ;

/* --------------------- dispatch.c ---------------------
 * Both the private and the shared memory resources are allocated upon
 * entry into each major mode, and are deallocated when the mode is
 * exited.  The shared data are common to all compute processes and
 * allow them to exchange results; but it is not visible to the
 * RVP8/Main threads.  Likewise, the private data are unique to each
 * compute process.
 */
void procCmdHandler( SINT4 iCmd_a ) ;
void ctPushExitMajorMode( void(* exitMajorMode_a )( void ) ) ;

MESSAGE procAllocatePrvShrMem( SINT4 iPrivateSize_a, SINT4 iSharedSize_a ) ;
void procReleasePrvShrMem( void ) ;

void proc_run_as_root( void ) ;
void proc_run_as_operator( void ) ;

void memoryBarrier( void ) ;

/* ****************************************
 * *                                      *
 * *  RVP8/Proc/Open Function Prototypes  *
 * *                                      *
 * ****************************************
 */

/* ------------------------------
 * Initialization routines for OPEN major modes.  The only function
 * prototype that should appear here for each major mode is the INIT
 * routine for that mode.  It is inappropriate for one mode to call
 * another's processing routines directly, because the private and
 * shared data for each mode are different.
 */
void ctInitMajorMode_fft  ( void ) ;
void ctInitMajorMode_ppp  ( void ) ;
void ctInitMajorMode_rph  ( void ) ;
void ctInitMajorMode_dpt2 ( void ) ;
void ctInitMajorMode_batch( void ) ;

/* ------------------- rvp8proc.c -------------------
 */
UINT1 lProcOpenProfiling( void ) ;
UINT4 iProcOpenUnique( void ) ;

/* -------------------- binmoments.c --------------------
 */
struct binMomDataRx {		/* Data args that are different for each Rx */
  const FLT4 *fTS ;		/*   ==> Input timeseries for the selected bin */
  const Ipp32fc	*cPhUVecs ;	/*   ==> Unit vectors recohere 2nd trip from 1st*/
  FLT4 *fSpecs[MAXTRIPS] ;      /*   ==> Optional working/view/output spectra */
} ;
struct bmfReturn {		/* Ancillary returned information per bin */
  UINT4 iFlags ;		/*   Propagated forward, bits defined per major mode */
  UINT1 iTripMask ;		/*   Mask of trip numbers that were filled in */
  UINT1 iWinType ;		/*   Data window that was used (if any) */
  UINT1 lSaturatedIF ;		/*   Some of the timeseries data were saturated */
  char pad7x1[1] ;
} ;
typedef void ( binMomFunc_f )	/* Major mode BinMoments function */
  ( const struct binMomDataRx     /* ==> Working data for each of the */
      pDataRx_a[ MAXVIQPERBIN ],  /*       channels being received. */
    const struct rvp8PulseHdr	  /* ==> Pulse headers for the entire */
      *pHdrs_a[],		  /*       set of available pulses. */
    SINT4 iBin_a,		  /* Input acquired bin number, */
    SINT4 nPulses_a,		  /* Number of pulses available */
    struct bmfReturn *pRet_a,     /* Ancillary returned info per bin */
    void *binMomArgs_a		  /* ==> Private custom arguments */
    ) ;

void genericBinMoments		      /* Master framework for BinMoments phase */
( const struct rvp8PulseHdr *pHdrs_a[],	/* List of pulse headers to be processed */
  SINT4 nPulses_a,		        /* Number of headers in pHdrs_a[] */
  UINT4 iFlags_a,		        /* Processing options (See below) */
  binMomFunc_f *binMomFunc_a,	        /* BinMoments kernel function, and */
  void *binMomArgs_a ) ;	        /*   customized list of arguments. */

/* Flag bits passed in iFlags_a
 */
#define GBMF_SAVEIQ     0x0001	/* Preserve (I,Q) and Spectral data so that */
#define GBMF_SAVESPEC   0x0002	/*   all processing phases can access them. */
#define GBMF_ALLCHANS   0x0004	/* Supply all Rx data, else just "Co" channel */

void printBinMomRaw( volatile const struct ctBinMomRaw *pRaw_a, SINT4 nTerms_a ) ;

void ctBinMomRawAverage
( struct ctBinMomRaw *pAvg_a, const struct ctBinMomRaw *pNew_a ) ;

void ctBinMomRawZap( struct ctBinMomRaw *pMom_a ) ;

void genRawTZMomsFromTS
( const Ipp32fc *cTS_a, struct ctBinMomRaw *rawMoms_a,
  SINT4 nPulses_a, UINT4 iFlags_a ) ;
#define GRTZM_DCREMOVAL 0x0001	/* Use DC removal clutter filtering */

/* -------------------- binparams.c --------------------
 */
void binParamsTZVW_dflt
( const struct ctRngInfo *rngInfo_a, struct ctBinMomRaw *rawMoms_a,
  struct ctBinMomRaw *avgMoms_a, struct ctSciBinMom *sciMoms_a,
  struct ctSciPrmTZVW *sciTZVW_a, FLT4 fLag2Ratio_a ) ;

void sciParamsTZVW_dflt
( SINT4 nBins_a, volatile const struct ctAvailBin *ctAvail_a,
  struct ctSciPrmTZVW *pTZVW_a, const struct ctSciBinMom *sciMoms_a,
  UINT1 lR2Algorithms_a, FLT4 fLag2Ratio_a,
  FLT4 fMesNoise_a, FLT4 fCalNoise_a ) ;

void sciReflectivity_dflt
( SINT4 nBins_a, volatile const struct ctAvailBin *ctAvail_a,
  const struct ctSciBinMom *sciMoms_a, struct ctSciPrmTZVW *pTZVW_a,
  FLT4 fMesNoise_a, FLT4 fCalNoise_a ) ;

void sciVelocity_dflt
( SINT4 nBins_a, volatile const struct ctAvailBin *ctAvail_a,
  const struct ctSciBinMom *sciMoms_a, struct ctSciPrmTZVW *pTZVW_a ) ;

void sciVelocityOther
( SINT4 nBins_a, volatile const struct ctAvailBin *ctAvail_a,
  const struct ctSciBinMom *sciMoms_a, struct ctSciPrmTZVW *pTZVW_a ) ;

void sciSpectralWidth_dflt
( SINT4 nBins_a, volatile const struct ctAvailBin *ctAvail_a,
  const struct ctSciBinMom *sciMoms_a, struct ctSciPrmTZVW *pTZVW_a,
  UINT1 lR2Algorithms_a, FLT4 fLag2Ratio_a, FLT4 fMesNoise_a ) ;

void sciApplyThreshTZVW_dflt
( SINT4 nBins_a, volatile const struct ctAvailBin *ctAvail_a,
  struct ctSciPrmTZVW *pTZVW_a ) ;

typedef BIN2 ( iUnfoldVel_f )
     ( BIN2 iPriVel_a, BIN2 iSecVel_a, UINT1 lLowPRF_a, UINT4 iUmode_a ) ;

void sciApplyDualPRF_dflt
( SINT4 nBins_a, volatile const struct ctAvailBin *ctAvail_a,
  iUnfoldVel_f *iUnfoldVel_a, struct ctSciPrmTZVW *pTZVW_a ) ;

iUnfoldVel_f iUnfoldRawVelPair_textbook ;
iUnfoldVel_f iUnfoldRawVelPair_dflt ;
iUnfoldVel_f iUnfoldRawVelPair_simul ;

typedef UINT1 ( lPopFilterOkay_f )( const void *pMom_a, FLT4 fCCRThrLinear_a ) ;

void oneDimSpeckleTZVW_dflt
( SINT4 nBins_a, SINT4 iStartBin_a, struct ctSciPrmTZVW *sciTZVW_a ) ;

void oneDimSpecklePass1
( const UINT1 *pOkay_a, UINT1 *pSpkl_a,
  SINT4 nBins_a, SINT4 iStartBin_a, SINT4 iStride_a ) ;

void oneDimSpecklePass2
( UINT1 *pOkay_a, const UINT1 *pSpkl_a,
  SINT4 nBins_a, SINT4 iStartBin_a, SINT4 iStride_a ) ;

void pointClutter_dflt
( const struct ctRngInfo *rngInfo_a, struct ctBinMomRaw *rawMoms_a,
  UINT2 iPtCltDetect_a, UINT2 iPtCltCensor_a ) ;

void rangeAvgMom_dflt
( const struct ctRngInfo *rngInfo_a,
  const void *rawMoms_a, void *avgMoms_a, SINT4 iMomSize_a,
  lPopFilterOkay_f *lPopFilterOkay_a, FLT4 fCCRThrLinear_a ) ;

UINT1 lUsePopFilter( void ) ;

FLT4 fMakeNoiseThresh( SINT2 iZnsThr_a, FLT4 fNoise_a ) ;

void sciMomsFromBinMoms
( SINT4 nBins_a, volatile const struct ctAvailBin *ctAvail_a,
  struct ctSciBinMom *sciMoms_a, const struct ctBinMomRaw *rawMoms_a ) ;

lPopFilterOkay_f lPopFilterOkayBMR ;
FLT4 fCoPolRxNoise( void ) ;

/* -------------------- dualpol.c --------------------
 */
struct pbmDfltArgs { /* ====== polarBinMoments_dflt() arguments ====== */
  union ctBinPolRaw *rawPols ;	      /* Output moment results */
  const struct rvp8DftConf *dftConf ; /* How to compute clutter filter DFTs */
} ;
binMomFunc_f polarBinMoments_dflt ;
binMomFunc_f polarBinMomentsNofilt_dflt ;

void polarComputeBinMomRaw
( struct ctBinMomRaw *pMom_a, const FLT4 *fTS_a, SINT4 nPulses_a ) ;

void polarComputeCxCo
( Ipp32fc *pCxCo_a, const FLT4 *fCxTS_a, const FLT4 *fCoTS_a, SINT4 nPulses_a ) ;

void polarXformPass1
( Ipp32fc *cDft_a, FLT4 *fSpec_a, const FLT4 *fTS_a,
  const struct rvp8DftConf *dftConf_a, SINT4 iFilterCode_a,
  SINT4 *pLeft_a, SINT4 *pRight_a ) ;

void polarXformPass2
( Ipp32fc *cDft_a, FLT4 *fSpec_a, struct ctBinMomRaw *binMoms_a,
  const struct rvp8DftConf *dftConf_a, SINT4 iLeft_a, SINT4 iRight_a ) ;

void polarXformCxCo
( Ipp32fc *cCxCo_a, const Ipp32fc *cCxDFT_a, const Ipp32fc *cCoDFT_a,
  const struct rvp8DftConf *dftConf_a ) ;

void binParamsPolar_dflt
( const struct ctRngInfo *rngInfo_a,
  const union ctBinPolRaw *rawPols_a, union ctBinPolRaw *avgPols_a,
  struct ctBinMomRaw *binMoms_a, struct ctSciBinMom *sciMoms_a,
  struct ctSciPrmTZVW *sciTZVW_a, struct ctSciPrmPolar *sciPolar_a ) ;

void stdMomsFromBinPols
( SINT4 nBins_a, volatile const struct ctAvailBin *ctAvail_a,
  struct ctBinMomRaw *stdMoms_a, const union ctBinPolRaw *binPols_a ) ;

void sciParamsPolar_dflt
( SINT4 nBins_a, volatile const struct ctAvailBin *ctAvail_a,
  struct ctSciPrmPolar *sciPolar_a, const union ctBinPolRaw *binPols_a,
  const struct ctSciPrmTZVW *sciTZVW_a, const FLT4 fRxNoises_a[2][2] ) ;

void makeGdrXdr( FLT4 *pGdr_a, FLT4 *pXdr_a ) ;

void makeNoiseMesCal
( FLT4 fRxTxNoises_a[2][2], FLT4 *pMesNoise_a, FLT4 *pCalNoise_a ) ;

lPopFilterOkay_f lPopFilterOkayPolar ;

void oneDimSpecklePolar_dflt
( SINT4 nBins_a, SINT4 iStartBin_a, struct ctSciPrmPolar *sciPolar_a ) ;

void rayParamsPolar_dflt
( const struct ctRngInfo *rngInfo_a, struct ctSciPrmPolar *sciPolar_a ) ;
void makeKdpFromPhiDP_dflt
( const struct ctRngInfo *rngInfo_a, struct ctSciPrmPolar *sciPolar_a ) ;

void rayFormatPolar_dflt
( const struct ctRngInfo *rngInfo_a,
  const struct ctSciPrmPolar *sciPolar_a,
  volatile const struct data_convert *conv_a ) ;

outputFormatFloat_f iFmtOneZDR ;
outputFormatFloat_f iFmtOneLDR ;
outputFormatFloat_f iFmtOneKDP ;

/* -------------------- phasemod.c --------------------
 */
struct rphbmArgs ;
typedef FLT4 ( whitenSpectrum_f ) /* Spectral whitening algorithm for Tx phase seq */
     ( Ipp32fc *winDFT_a, const Ipp32fc cPhUVecs_a[RVP8MAXPULSES],
       const struct ctBinMomRaw *pCor_a, const struct rvp8DftConf *dftConf_a,
       SINT4 iTrip_a, SINT4 iBin_a, FLT4 *pViewRawRes_a ) ;

typedef FLT4 ( applySpecFilter_f ) /* How to filter clutter from power spectra */
     ( FLT4 *fSpec_a, volatile const struct rvp8SpecFilt *pSpecFilt_a,
       const struct rvp8DftConf *dftConf_a, FLT4 fSamplePRF_a,
       FLT4 fNoisePower_a, struct winGaussClutterModel *WGCM_a ) ;

typedef void ( rphBinMomentsGroup_f ) /* RPH algorithms on Spectrum-Size group */
     ( const FLT4 *fTS_a, const Ipp32fc cPhUVecs_a[RVP8MAXPULSES], SINT4 iBin_a,
       struct rphBinMomRaw moms_a[2], FLT4 fViewSpecs_a[2][RVP8MAXPULSES],
       SINT4 iWinType_a, const struct rphbmArgs *pArgs_a ) ;

typedef void ( rphBinMomentsOneSide_f ) /* Fundamental one-sided RPH algorithms */
     ( Ipp32fc *winDFT_a, const Ipp32fc cPhUVecs_a[RVP8MAXPULSES],
       SINT4 iBin_a, struct rphBinMomRaw *rph_a, SINT4 iTrip_a,
       SINT4 iView_a, FLT4 fViewSpec_a[RVP8MAXPULSES],
       const struct rphbmArgs *pArgs_a ) ;

typedef SINT4 ( iRphTripSelections_f ) /* Final decisions of which trips to use */
     ( struct rphBinMomRaw moms_a[2] ) ;

typedef void ( rphThresholding_f ) /* Thresholding criteria for trip moments */
     ( struct rphBinMomRaw moms_a[2] ) ;

struct rphbmArgs {	 /* ====== rphBinMoments() arguments ====== */
  rphBinMomentsGroup_f   *rphBinMomentsGroup ;
  rphBinMomentsOneSide_f *rphBinMomentsOneSide ;
  iRphTripSelections_f   *iRphTripSelections ;
  applySpecFilter_f      *applySpecFilter ;
  whitenSpectrum_f       *whitenSpectrum ;
  rphThresholding_f      *rphThresholding ;

  FLT4 fSamplePRF ;		/* Required by some clutter filters */
  struct winGaussClutterModel *WGCM ;
  const struct rvp8DftConf *dftConf ; /* Required DFT info */
  struct ctBinMomRaw *rawMoms ;	      /* Output moment results */
} ;
binMomFunc_f rphBinMoments ;

rphBinMomentsGroup_f   rphBinMomentsGroup_dflt ;
rphBinMomentsOneSide_f rphBinMomentsOneSide_dflt ;
iRphTripSelections_f   iRphTripSelections_dflt ;
rphThresholding_f      rphThresholding_dflt ;

whitenSpectrum_f whitenRandom_dflt ;
whitenSpectrum_f whiten_sz8_64_kernel ;
whitenSpectrum_f whiten_sz8_64_dflt ;

/* ------------------- rayformat.c -------------------
 */
void rayFormatTZVW_dflt
( const struct ctRngInfo *rngInfo_a,
  const struct ctSciPrmTZVW *sciTZVW_a,
  volatile const struct data_convert *conv_a ) ;

void rayfmtQualifiedFloat
( SINT4 nBins_a, const struct paramFmtOne *conv_a, volatile UINT2 *pOut_a,
  outputFormatFloat_f *iFmtFunc_a,  volatile const FLT4 *pData_a,
  volatile const UINT1 *pOkay_a, SINT4 iSciStride_a ) ;

void rayfmtVelocity
( SINT4 nBins_a, const struct paramFmtOne *conv_a, volatile UINT2 *pOut_a,
  volatile const struct velQual *pVel_a, SINT4 iSciStride_a ) ;

void rayfmtRangeFlags( SINT4 nBins_a, SINT4 iStartBin_a ) ;

outputFormatFloat_f iFmtOneFraction ;
outputFormatFloat_f iFmtOnePhaseInRads ;
outputFormatFloat_f iFmtOneReflectivity ;
outputFormatFloat_f iFmtOneSpectralWidth ;
outputFormatAngle_f iFmtOneVelocity ;

/* -------------------- spectra.c --------------------
 */
typedef void ( genMomFromSpec_f ) /* How to calculate moments from spectra */
     ( volatile struct ctBinMomRaw *pBinMom_a, const FLT4 *fSpec_a,
       const struct rvp8DftConf *dftConf_a ) ;

struct sbmDfltArgs { /* ====== specBinMoments_dflt() arguments ====== */
  SINT4 iStartPulse ;		/* Offset of first TS pulse to process */
  FLT4  fSamplePRF ;		/* Required by some clutter filters */
  struct winGaussClutterModel *WGCMs ;
  const struct rvp8DftConf *dftConf ; /* How to compute the required DFTs */
  struct ctBinMomRaw *rawMoms ;	      /* Output moment results */
} ;
binMomFunc_f genericSpecBinMoments ;
binMomFunc_f specBinMoments_dflt ;

genMomFromSpec_f  genMomFromSpec_dflt ;
applySpecFilter_f applySpecFilter_dflt ;

void specFilterWidthLegacy
( const FLT4 *fSpecLin_a, SINT4 iSpecSize_a, SINT4 iMinWidth_a,
  SINT4 iMaxWidth_a, SINT4 *piLeft_a, SINT4 *piRight_a ) ;

FLT4 fSpecFilterIGapLegacy
( FLT4 *fSpecLin_a, SINT4 iSpecSize_a, SINT4 iEdgePts_a,
  SINT4 iLeft_a, SINT4 iRight_a ) ;

FLT4 fSpecFilterIGapQuadratic
( FLT4 *fSpecLin_a, SINT4 iSpecSize_a, SINT4 iEdgePts_a,
  SINT4 iLeft_a, SINT4 iRight_a, FLT4 fNoisePower_a ) ;

FLT4 fSpecFilterGMAP
( FLT4 *fSpecLin_a, FLT4 fClutterWidth_a, FLT4 fNoisePower_a, SINT4 iWinType_a,
  const struct rvp8DftConf *dftConf_a, struct winGaussClutterModel *WGCM_a ) ;

/* Normalized ranking function for Poisson distributed noise.  This
 * deceptively simple looking expression is obtained by integrating
 * and inverting the assumed noise statistics.  Note that linear units
 * of power are returned, and the function is normalized relative to a
 * noise power of 1.0.  TERM ranges between zero and SIZE-1.
 */
#define POISSONNOISERANK( TERM, SIZE ) \
  ( -log( (((FLT4)((SIZE) - (TERM))) - 0.5) / (FLT4)(SIZE) ) )

struct specSort {		/* Element of rank ordered spectrum */
  FLT4  fdBVal ;		/*   Spectral value in dB */
  SINT2 iIndex ;		/*   Location in original spectrum */
  char  pad6x2[2] ;
} ;
void specSortFromDFT
( struct specSort *specSort_a, const Ipp32fc *pDFT_a, SINT4 iSpecSize_a ) ;
void specSortFromSpecLog
( struct specSort *specSort_a, const FLT4 *fSpecLog_a, SINT4 iSpecSize_a ) ;

SINT4 iSpecSortNoiseAnalysis
( const struct specSort *specSort_a, SINT4 iSpecSize_a, FLT4 *fNoiseTerm_a ) ;

void specSortGenSignalMask
( const struct specSort *specSort_a, SINT4 iSpecSize_a, SINT4 iSigIndex_a,
  UINT1 *lSigMask_a, UINT4 iFlags_a ) ;
#define SSGSM_FILL_NEARBY  0x0001 /* Fill likely points if near others */
#define SSGSM_FILL_GAPS    0x0002 /* Fill single-point gaps */
#define SSGSM_DESPECKLE    0x0004 /* Kill single-point speckles */

int specSortCompare( const void *arg1_a, const void *arg2_a ) ;

SINT4 iSpectrumSize( SINT4 iSize_a, SINT4 iMultipleOf_a ) ;

SINT4 iWinTypeFromFilterCode( SINT4 iFilterCode_a ) ;
SINT4 iWinTypeFromSpecFilt( volatile const struct rvp8SpecFilt *pSpecFilt_a ) ;

void specLogFromSpecLin
( FLT4 *fSpecLog_a, const FLT4 *fSpecLin_a, SINT4 iSpecSize_a ) ;
void specLinFromSpecLog
( FLT4 *fSpecLin_a, const FLT4 *fSpecLog_a, SINT4 iSpecSize_a ) ;

void initWinGaussClutterModel
( struct winGaussClutterModel *model_a, FLT4 fClutterWidth_a,
  SINT4 iWinType_a, const struct rvp8DftConf *dftConf_a ) ;

/* ****************************************
 * *                                      *
 * *  RVP8/Proc/Site Function Prototypes  *
 * *                                      *
 * ****************************************
 */

/* ------------------- ct_user.c -------------------
 */
void rvp8ProcSiteInit( void ) ;
void rvp8ProcSiteExit( void ) ;

void ctInitMajorMode_user1( void ) ;
void ctInitMajorMode_user2( void ) ;
void ctInitMajorMode_user3( void ) ;
void ctInitMajorMode_user4( void ) ;

UINT1 lCtInitMajorModeSwitch( SINT4 iMode_a ) ;

binMomFunc_f specBinMoments ;

applySpecFilter_f applySpecFilter ;

void binParamsTZVW
( const struct ctRngInfo *rngInfo_a, struct ctBinMomRaw *rawMoms_a,
  struct ctBinMomRaw *avgMoms_a, struct ctSciBinMom *sciMoms_a,
  struct ctSciPrmTZVW *sciTZVW_a ) ;

void pointClutter
( const struct ctRngInfo *rngInfo_a, struct ctBinMomRaw *rawMoms_a,
  UINT2 iPtCltDetect_a, UINT2 iPtCltCensor_a ) ;

void rayFormatTZVW
( const struct ctRngInfo *rngInfo_a,
  const struct ctSciPrmTZVW *sciTZVW_a,
  volatile const struct data_convert *conv_a ) ;

binMomFunc_f polarBinMoments ;
binMomFunc_f polarBinMomentsNofilt ;

void binParamsPolar
( const struct ctRngInfo *rngInfo_a,
  const union ctBinPolRaw *rawPols_a, union ctBinPolRaw *avgPols_a,
  struct ctBinMomRaw *binMoms_a, struct ctSciBinMom *sciMoms_a,
  struct ctSciPrmTZVW *sciTZVW_a, struct ctSciPrmPolar *sciPolar_a ) ;

void rayParamsPolar
( const struct ctRngInfo *rngInfo_a, struct ctSciPrmPolar *sciPolar_a ) ;

void rayFormatPolarTZVW
( const struct ctRngInfo *rngInfo_a,
  const struct ctSciPrmTZVW  *sciTZVW_a,
  const struct ctSciPrmPolar *sciPolar_a,
  volatile const struct data_convert *conv_a ) ;

rphBinMomentsGroup_f   rphBinMomentsGroup ;
rphBinMomentsOneSide_f rphBinMomentsOneSide ;
iRphTripSelections_f   iRphTripSelections ;
rphThresholding_f      rphThresholding ;
whitenSpectrum_f       whitenRandom ;
whitenSpectrum_f       whiten_sz8_64 ;

/* ------------------- demoparam.c -------------------
 */
void hclassInitMajorMode( void ) ;

void hclassFormatOutput
( const struct ctRngInfo *rngInfo_a,
  const struct ctSciPrmTZVW  *sciTZVW_a,
  const struct ctSciPrmPolar *sciPolar_a,
  volatile const struct data_convert *conv_a ) ;

/* ------------------- rvp8proc_site.c -------------------
 */
UINT1 lProcSiteProfiling( void ) ;
UINT4 iProcSiteUnique( void ) ;

#endif /* #ifndef MESSAGE_ONLY */
#endif /* #ifndef SIGMET_RVP8PROC_H */
