/**C*
 *
 * Vaisala software source code file
 *
 * Copyright (c) Vaisala Oyj 1989, 1990, 1992, 1995, 1996, 1997, 1998, 1999,
 * 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013.
 * All rights reserved.
 *
 **C*/

/** @file
 *
 * IRIS Product Definitions
 * Include requirements: sigtypes.h
 *                       headers.h
 *
 * $URL: https://subversion.vaisala.com/svn/repos/sigmet/wr_iris_rda/branches/release8.13.5/base/include/product.h $
 *
 * $Id: product.h 30091 2014-06-06 12:19:55Z rke $
 *
 */

#ifndef SIGMET_PRODUCT_H
#define SIGMET_PRODUCT_H 1

#ifdef __cplusplus
extern "C" {
#endif

#if 0
} /* Fix auto-indenter bug */
#endif

#define ENUM_IRIS_PRODUCT_TYPE_DEFINED 1
enum iris_product_type
{
    PROD_NULL        = 0,   /**<  No product at all */
    PROD_PPI         = 1,   /**<  PPI */
    PROD_RHI         = 2,   /**<  RHI */
    PROD_CAPPI       = 3,   /**<  CAPPI */
    PROD_CROSS       = 4,   /**<  Cross section */
    PROD_TOPS        = 5,   /**<  Echo tops */
    PROD_TRACK       = 6,   /**<  Storm track */
    PROD_RAIN1       = 7,   /**<  Precipitation 1 hour */
    PROD_RAINN       = 8,   /**<  Precipitation n hour */
    PROD_VVP         = 9,   /**<  Velocity Volume processing */
    PROD_VIL         = 10,  /**<  Vertically Integrated Liquid */
    PROD_SHEAR       = 11,  /**<  Wind shear */
    PROD_WARN        = 12,  /**<  Warning (overlay) */
    PROD_CATCH       = 13,  /**<  Rain catchments */
    PROD_RTI         = 14,  /**<  Range-Time-Display */
    PROD_RAW         = 15,  /**<  Raw data set (no display)*/
    PROD_MAX         = 16,  /**<  Maximum with side panels */
    PROD_USER        = 17,  /**<  Earth projection user product */
    PROD_USERV       = 18,  /**<  Section projection user product */
    PROD_OTHER       = 19,  /**<  Other user product (no display) */
    PROD_STATUS      = 20,  /**<  Status product (no display) */
    PROD_SLINE       = 21,  /**<  Shear Line Product */
    PROD_WIND        = 22,  /**<  Horizontal wind field */
    PROD_BEAM        = 23,  /**<  Beam pattern */
    PROD_TEXT        = 24,  /**<  Text */
    PROD_FCAST       = 25,  /**<  Forecast */
    PROD_NDOP        = 26,  /**<  Multi-Doppler */
    PROD_IMAGE       = 27,  /**<  Arbitrary graphics image */
    PROD_COMP        = 28,  /**<  Composite */
    PROD_TDWR        = 29,  /**<  TDWR Wind Alert */
    PROD_GAGE        = 30,  /**<  Raingage product */
    PROD_DWELL       = 31,  /**<  Dwell and bird detection product */
    PROD_SRI         = 32,  /**<  Surface Rainfall Intensity */
    PROD_BASE        = 33,  /**<  Echo bottoms */
    PROD_HMAX        = 34,  /**<  Height of Max Reflectivity */
    PROD_VAD         = 35,  /**<  Velocity azimuth display */
    PROD_THICK       = 36,  /**<  Echo thickness */
    PROD_SATELLITE   = 37,  /**<  Satellite data */
    PROD_LAYER       = 38,  /**<  Layer average */
    PROD_SWS         = 39,  /**<  Surface Weather Station */
    PROD_MLHGT       = 40   /**<  Melting level  */
};

#define PROD33_RANK     0       /*  BASE */
#define PROD23_RANK     1       /*  BEAM */
#define PROD3_RANK      2       /*  CAPPI */
#define PROD13_RANK     3       /*  CATCH */
#define PROD28_RANK     4       /*  COMP */
#define PROD31_RANK     5       /*  DWELL */
#define PROD25_RANK     6       /*  FCAST */
#define PROD30_RANK     7       /*  GAGE */
#define PROD34_RANK     8       /*  HMAX */
#define PROD27_RANK     9       /*  IMAGE */
#define PROD38_RANK    10       /*  LAYER */
#define PROD16_RANK    11       /*  MAX */
#define PROD40_RANK    12       /*  MLHGT */
#define PROD26_RANK    13       /*  NDOP */
#define PROD1_RANK     14       /*  PPI */
#define PROD7_RANK     15       /*  RAIN1 */
#define PROD8_RANK     16       /*  RAINN */
#define PROD15_RANK    17       /*  RAW */
#define PROD2_RANK     18       /*  RHI */
#define PROD14_RANK    19       /*  RTI */
#define PROD11_RANK    20       /*  SHEAR */
#define PROD21_RANK    21       /*  SLINE */
#define PROD32_RANK    22       /*  SRI */
#define PROD37_RANK    23       /*  SAT */
#define PROD20_RANK    24       /*  STATUS */
#define PROD39_RANK    25       /*  SWS */
#define PROD29_RANK    26       /*  TDWR */
#define PROD24_RANK    27       /*  TEXT */
#define PROD36_RANK    28       /*  THICK */
#define PROD5_RANK     29       /*  TOPS */
#define PROD6_RANK     30       /*  TRACK */
#define PROD35_RANK    31       /*  VAD */
#define PROD10_RANK    32       /*  VIP */
#define PROD9_RANK     33       /*  VVP */
#define PROD12_RANK    34       /*  WARN */
#define PROD22_RANK    35       /*  Wind */
#define PROD4_RANK     36       /*  XSECT */
#define PROD17_RANK    37       /*  USER */
#define PROD18_RANK    38       /*  USERV */
#define PROD19_RANK    39       /*  OTHER */
#define PROD_RANK_LIST                                                  \
    {       PROD1_RANK,  PROD2_RANK,  PROD3_RANK,  PROD4_RANK,  PROD5_RANK, \
            PROD6_RANK,  PROD7_RANK,  PROD8_RANK,  PROD9_RANK,  PROD10_RANK, \
            PROD11_RANK, PROD12_RANK, PROD13_RANK, PROD14_RANK, PROD15_RANK, \
            PROD16_RANK, PROD17_RANK, PROD18_RANK, PROD19_RANK, PROD20_RANK, \
            PROD21_RANK, PROD22_RANK, PROD23_RANK, PROD24_RANK, PROD25_RANK, \
            PROD26_RANK, PROD27_RANK, PROD28_RANK, PROD29_RANK, PROD30_RANK, \
            PROD31_RANK, PROD32_RANK, PROD33_RANK, PROD34_RANK, PROD35_RANK, \
            PROD36_RANK, PROD37_RANK, PROD38_RANK, PROD39_RANK, PROD40_RANK }
    
/* Product licensing bits */
#define LBIT_BASIC    (0x00000001)  /* Basic product set */
#define LBIT_CAPPI    (0x00000002)  /* Full product set */
#define LBIT_MAX      (0x00000004)  /* Full product set */
#define LBIT_RAIN     (0x00000008)  /* Full product set */
#define LBIT_TOPS     (0x00000010)  /* Full product set */
#define LBIT_VIL      (0x00000020)  /* Full product set */
#define LBIT_VVP      (0x00000040)  /* Full product set */
#define LBIT_WIND     (0x00000080)  /* Full product set */
#define LBIT_COMP     (0x00000100)  /* Optional product set */
#define LBIT_SHEAR    (0x00000200)  /* Optional product set */
#define LBIT_IMAGE    (0x00000400)  /* Special product set */
#define LBIT_TEXT     (0x00000800)  /* Special product set */
#define LBIT_USER     (0x00001000)  /* Special product set */
#define LBIT_LLWAS    (0x00002000)  /* Special product set */
#define LBIT_HYDROMET (0x00004000)  /* Optional product set */
#define LBIT_DWELL    (0x00008000)  /* Optional product set */
#define LBIT_UNUSED   (0x10000000)  /* Unused product set */

#define PROD1_LBIT    LBIT_BASIC    /* PPI */
#define PROD2_LBIT    LBIT_BASIC    /* RHI */
#define PROD3_LBIT    LBIT_CAPPI    /* CAPPI (full) */
#define PROD4_LBIT    LBIT_BASIC    /* Cross section */
#define PROD5_LBIT    LBIT_TOPS     /* Tops */
#define PROD6_LBIT    LBIT_BASIC    /* Track */
#define PROD7_LBIT    LBIT_RAIN     /* Rain1 */
#define PROD8_LBIT    LBIT_RAIN     /* RainN */
#define PROD9_LBIT    LBIT_VVP      /* VVP */
#define PROD10_LBIT   LBIT_VIL      /* VIP */
#define PROD11_LBIT   LBIT_SHEAR    /* Shear */
#define PROD12_LBIT   LBIT_BASIC    /* Warning */
#define PROD13_LBIT   LBIT_HYDROMET /* CATCH */  
#define PROD14_LBIT   LBIT_BASIC    /* RTI */
#define PROD15_LBIT   LBIT_BASIC    /* RAW */
#define PROD16_LBIT   LBIT_MAX      /* Max */
#define PROD17_LBIT   LBIT_USER     /* USER */
#define PROD18_LBIT   LBIT_USER     /* USERV */
#define PROD19_LBIT   LBIT_USER     /* OTHER */
#define PROD20_LBIT   LBIT_BASIC    /* Status */
#define PROD21_LBIT   LBIT_SHEAR    /* SLine */
#define PROD22_LBIT   LBIT_WIND     /* Wind */
#define PROD23_LBIT   LBIT_BASIC    /* Beam */
#define PROD24_LBIT   LBIT_TEXT     /* Text */
#define PROD25_LBIT   LBIT_BASIC    /* Forecast */
#define PROD26_LBIT   LBIT_COMP     /* NDOP */
#define PROD27_LBIT   LBIT_IMAGE    /* Image */
#define PROD28_LBIT   LBIT_COMP     /* COMP */
#define PROD29_LBIT   LBIT_LLWAS    /* LLWAS */
#define PROD30_LBIT   LBIT_HYDROMET /* GAGE */
#define PROD31_LBIT   LBIT_DWELL    /* DWELL */
#define PROD32_LBIT   LBIT_CAPPI    /* SRI */
#define PROD33_LBIT   LBIT_BASIC    /* BASE */
#define PROD34_LBIT   LBIT_BASIC    /* HMAX */
#define PROD35_LBIT   LBIT_BASIC    /* VAD */
#define PROD36_LBIT   LBIT_TOPS     /* THICK */
#define PROD37_LBIT   LBIT_USER     /* SAT */
#define PROD38_LBIT   LBIT_VIL      /* LAYER */
#define PROD39_LBIT   LBIT_BASIC    /* SWS */
#define PROD40_LBIT   LBIT_TOPS     /* MLHGT */


#define PROD_LBIT_LIST                                                  \
    {       PROD1_LBIT,  PROD2_LBIT,  PROD3_LBIT,  PROD4_LBIT,  PROD5_LBIT, \
            PROD6_LBIT,  PROD7_LBIT,  PROD8_LBIT,  PROD9_LBIT,  PROD10_LBIT, \
            PROD11_LBIT, PROD12_LBIT, PROD13_LBIT, PROD14_LBIT, PROD15_LBIT, \
            PROD16_LBIT, PROD17_LBIT, PROD18_LBIT, PROD19_LBIT, PROD20_LBIT, \
            PROD21_LBIT, PROD22_LBIT, PROD23_LBIT, PROD24_LBIT, PROD25_LBIT, \
            PROD26_LBIT, PROD27_LBIT, PROD28_LBIT, PROD29_LBIT, PROD30_LBIT, \
            PROD31_LBIT, PROD32_LBIT, PROD33_LBIT, PROD34_LBIT, PROD35_LBIT, \
            PROD36_LBIT, PROD37_LBIT, PROD38_LBIT, PROD39_LBIT, PROD40_LBIT }



/*
 * ==========================================================================
 * ==================== Product Configuration ===============================
 * ==========================================================================
 *
 * The product configuration structure holds information that defines what to
 * do in order to make a product.  It does not hold related information about
 * the particular INGEST data that goes into a particular product.  That info
 * is placed in the product file header, defined in the next section.
 *
 */
#define PRODUCT_CONFIGURATION_SIZE  (320)
#define STRUCT_PRODUCT_CONFIGURATION_DEFINED 1
struct product_configuration
{
    struct structure_header hdr;  /* Generic Header */

    uint16_t iptype;    /* Product Type Code, see enum iris_product_type */

    /* The following variables are used to schedule the running of this
     * product configuration.  Starting from EPOCH, either the next
     * available data, or all available data (as per ISCH) will be
     * processed.  The various time structures have the following meaning.
     *
     *  1) The "ing_time" time structure has different meaning depending on
     *  the type of product.  TZ determined by iMinutesWest and sTZName.
     *
     *  a) For "immediate" products (i.e., PPI, RHI, SHEAR, and single
     *     sweep RAW), the "ing_time" structure holds the starting time
     *     of the specific sweep that was used to make the product.
     *
     *  b) For "volume scan" products (i.e., all others), the "ing_time"
     *     structure holds the time of the start of the earliest INGEST
     *     volume scan that was used in making the product.  For example,
     *     if a TOPS product is made from two hybrid tasks "TASK_B" and
     *     "TASK_C", then the TOPS "ing_time" would be the starting time
     *     of the "B" volume scan.
     *
     *    2) The "epoch" time holds the next-data-time while the product
     *  configuration is in the product schedule.  Once the product is
     *  made, this the value of "b)" above, regardless of whether
     *  the product is an "immediate" or "volume scan" type.  Thus, as an
     *  "immediate" product runs through the individual tilts of a volume
     *  scan, the "epoch" time remains fixed at the volume scan starting
     *  time, whereas the "ing_time" time marchs forward for each sweep
     *  processed.
     *
     *    3) The "prod_time" time structure refers to the time that the
     *  product file was produced on whatever machine originally
     *  generated it.
     *  TZ determined by the setup question.
     */
    uint16_t  isch;              /* Scheduling */
#define PSC_HOLD      0              /*  Do not run at all. */
#define PSC_NEXT      1              /*  Run once on next available data */
#define PSC_ALL       2              /*  Run as data becomes available */
#define PSC_AGAIN     3              /*  Run again on data last used */
#define PSC_ONCE      4              /*  Run once then remove from schedule */

    int32_t isch_skip;           /* # seconds between runs */

    struct ymds_time prod_time;  /* Time product was created */
    struct ymds_time ing_time;   /* Time of ingest data product was made from */
    /* For RAIN1 and RAINN, end of time interval */

    struct ymds_time epoch;      /* Beginning of scheduling time period */

    /* The following text strings must be in upper case: */

    char ipad56x6[6];
    char spname[12];             /* Product configuration name */

    char stname[12];             /* Task configuration name */

    uint16_t iflags;             /* Flags */
    /* Flags in the file, and in the inventory
     */
#define PF_KEEP        (0x0020)  /* Do not remove this file    */
#define PF_CLUTTER     (0x0040)  /* This is a clutter map      */
#define PF_COMPOSITED  (0x0800)  /* This product has been composited*/
#define PF_DWELL       (0x1000)  /* This product is a dwell product*/
#define PF_ZR_SOURCE0  (0x2000)  /* Source of Z/R numbers: */
#define PF_ZR_SOURCE1  (0x4000)  /* 0:TypeIn, 1:Setup, 2:Disdro, 3:Unused */

    /* Product type specific flags in the file, and in the inventory
     */
#define PF_WARN_TDWR   (0x0002)  /* Make TDWR style messages */
#define PF_WARN_SAY    (0x0080)  /* Speak warning messages */

    /* Bits stored in the file
     */
#define PF_IN_FILE (PF_KEEP|PF_CLUTTER|PF_WARN_TDWR|PF_WARN_SAY|PF_COMPOSITED|PF_DWELL|PF_ZR_SOURCE0|PF_ZR_SOURCE1)

    /* Bits controlled by PCF menu
     */
#define PF_IN_PCF  (PF_WARN_TDWR|PF_WARN_SAY|PF_ZR_SOURCE0|PF_ZR_SOURCE1)

    /* Flags in the product schedule
     */
#define PF_RUNNING    (0x0004)  /* This pcf is being run               */
#define PF_HEADER     (0x0008)  /* Header, placeholder only, dont execute  */

    /* Flags in the product inventory only
     */
#define PF_DELETE     (0x0010)  /* Delete this product        */
#define PF_REINGEST   (0x0100)  /* Tagged for reingesting     */
#define PF_TIMEOUT    (0x0200)  /* Status product has timed out*/
#define PF_PENDING    (0x0001)  /* Status product from before startup*/

    /* Flags in server-to-client report */
#define PF_CHECKED    (0x0400)  /* Status product checking enabled for this site*/

    int32_t ixscale, iyscale, izscale ; /* Scale in cm/pixel  */
    int32_t ixsize , iysize , izsize  ; /* Size of (up to 3) dimensions     */

#define MIN_PRODUCT_SIZE     (3) /* Min/Max sizes of X & Y */
#define MAX_PRODUCT_SIZE   (3100)
#define MAX_PRODUCT_SURFACES (50) /* CAPPI, MAX, etc., horizontal surface bound */

    int32_t ixrad, iyrad, izrad; /*  Location of radar in pixels*1000 */

    /* The following variable is only used in the version 2.0 structures with
     * version numbers 1 or less.
     */
    int32_t irange_last_v20;     /* Range of last bin in cm (raw only) */
    uint8_t iHydroClassMerger;   /* Merger options (enum classifier_merger) */
    char ipad129x1;
    uint16_t idata_out;          /* Data type of data generated by product gen*/

    /* This section for version 2.1+ products
     */
    char  sprojection_name[12];  /* Projection name, null terminated */
    uint16_t idata_in;           /*  Data type used by the generator */
    uint8_t iprojection_type;    /* Projection type for map */
    char ipad147x1;
    int16_t iradial_smooth;      /* Range in km*100 over which radial  */
    /* smoothing should be done.  0:none. */
    uint16_t iruns;              /* # of times this pcf has been run   */
    int32_t izr_const;           /* Z-R or Z-W constant and exponent   */
    int32_t izr_exp;             /*  in 1/1000 of integers             */
    int16_t ix_smooth;           /* X-Y Smoothing parameters for 2D */
    int16_t iy_smooth;           /*  products.  km*100,  0:none */

    /* ---- Product Specific Parameters ----
     * The following area conveys information needed for each specific
     * product.
     */
    PSI psi;

#define PCF_TASK_MINOR_SIZE (16)
    char sTaskMinorList[PCF_TASK_MINOR_SIZE]; /* Null terminated list of hybrid extensions */
#define PCF_QPE_ALGORITHM_SIZE (12)
    /* Null terminated name of QPE algorithm, (might use all 12 characters) */
    char sQPE_algorithm[PCF_QPE_ALGORITHM_SIZE];
    char ipad272x48[48];
} ;

typedef struct product_configuration PCF;


/* This is for the client receiving data from the server
 */
struct serv_product_configuration
{
    struct serv_structure_header hdr; /* Generic Header */

    uint32_t iptype;             /* Product Type Code */

    struct serv_ymds_time ing_time; /* Time of ingest data product was made */

    /* For RAIN1 and RAINN, end of time interval
     */
    struct serv_ymds_time epoch; /* Beginning of scheduling time period */

    uint32_t  isch;              /*  Scheduling */

    int32_t isch_skip;           /*  # seconds between runs */

    /* The following text strings must be in upper case
     */
    char spname[12];             /* Product configuration name */
    char stname[12];             /* Task configuration name */

    uint32_t iflags;             /* Flags */

    int32_t ixscale, iyscale, izscale; /*  Scale in cm/pixel  */
    int32_t ixsize, iysize, izsize;    /*  Size of (up to 3) dimensions     */
    int32_t ixrad;               /*  Location of radar in pixels*1000 */
    char ipad_radpos[8];

    uint32_t iHydroClassMerger;  /* Merger options (enum classifier_merger) */
    uint32_t idata_out;          /* Data type of data generated by product gen */

    char  sprojection_name[16];  /* Projection name, null terminated */
    uint32_t idata_in;           /*  Data type used by the generator */
    uint32_t iprojection_type;   /* Projection type for map */
    int32_t iradial_smooth;      /* Range in km*100 over which radial  */
    /*  smoothing should be done.  0:none. */
    int32_t izr_const;           /* Z-R or Z-W constant and exponent   */
    int32_t izr_exp;             /*  in 1/1000 of integers             */
    int32_t ix_smooth;           /* X-Y Smoothing parameters for 2D */
    int32_t iy_smooth;           /*  products.  km*100,  0:none */

    /* ---- Product Specific Parameters ---- */
    /* The following area conveys information needed for each specific
     * product.
     */
    SPSI spsi;
    char sTaskMinorList[PCF_TASK_MINOR_SIZE]; /* Null terminated list of hybrid extensions */
    /* Definately null terminated QPE algorithm name */
    char sQPE_algorithm[PCF_QPE_ALGORITHM_SIZE+4];
    struct server_color_scale_def unused_colors;
};
typedef struct serv_product_configuration SPCF;


/* =========================================================================
 * ==================== Product End ========================================
 * =========================================================================
 */
#define PRODUCT_END_SIZE  (308)

struct product_end
{
    char sprod_sitename[16];  /* Name of product generator site, space padded */
    char sprod_version[8];       /* Product IRIS version, null terminated */
    char sing_version[8];        /* Ingest IRIS version, null terminated */
    
    struct ymds_time old_ing;    /* Oldest data in this file */
    char ipad44x28[28];

    int16_t iLocalWest;          /* # minutes local standard time is west of GMT */
    char  sIngHardwareName[16];  /* Hardware name of ingest site, space padded*/

    /* Information about the radar site.  Latitude and Longitude are
     * stored as 32-bit binary angles, where 20000000 Hex is 45 degrees
     * North Latitude or East Longitude.  For products of many tasks,
     * these are taken from the first site.  For track product, these are
     * taken from the site making the track.
     */
    char  sing_sitename[16];     /* Name of ingest site, space padded */
    int16_t iMinutesWest;        /* # minutes recorded standard time is west of GMT */
    BIN4  ilat_center;           /* Latitude of center of product */
    BIN4  ilon_center;           /* Longitude of center of product */
    int16_t ignd_hgt;            /* Ground height (m above sea level) */
    int16_t irad_hgt;            /* Radar height (m above ground) */

    /* Signal processing related numbers.  These are mostly copied from
     * the task configuration structure.
     */
    int32_t iprf;                /* PRF in hertz */
    int32_t ipw;                 /* Pulse width in 1/100 usec */
    uint16_t idsptype;
    uint16_t itrig;              /* Trigger rate scheme */
    int16_t isamp;               /* # samples used */
    char  sfilter[12];           /* Clutter filter file name */
    uint16_t idop_filter_first;  /* Doppler filter used on first bin */
    int32_t ilambda;             /* Wavelength in cm*100 */
    int32_t itrunc;              /* Truncation height (cm above the radar) */
    int32_t ibin_first;          /* Range of first bin in cm */
    int32_t ibin_last;           /* Range of last bin in cm */
    int32_t ibin_out_num;        /* Number of output bins */

    int16_t iPEFlags;            /* Was iflags */

    /* If the Disdrometer was selected as the Z/R source, but it was not
     * available, then we switch to setup source, and set this bit.
     */
#define PEF_ZR_FALLBACK (0x0001)

    int16_t input_cnt;           /* Number of ingest and product files
                                  * processed to produce this product
                                  * (only for accumulating products). */

    uint16_t ipolar;             /* Type of polarization, see POL_* in dsp.h */
    int16_t iI0Horiz;            /* I0 number from calibration, 1/100 of dB */
    int16_t iCalNoiseHoriz;      /* Noise at calibration time, 1/100 of dBm */
    int16_t iRadarConstantHoriz; /* Radar constant, 1/100 of dB */
    uint16_t iReceiverBandwidth; /* Receiver bandwidth, in kHz */
    int16_t iActNoiseHoriz;      /* Noise level, 1/100 of dBm */
    int16_t iActNoiseVert;       /* Noise level, 1/100 of dBm */
    int16_t iLdrBias;            /* LDR calibration offset, 1/100 of dBm */
    int16_t iZdrBias;            /* ZDR calibration offset, 1/100 of dBm */
    uint16_t iTcfCalFlags;       /* Calibration flags copied from task_calib_info */
    uint16_t iTcfCalFlags2;      /* These 2 flags were added in 8.12.3 */

    char ipad194x18[18];

    BIN4  iStdParallel1; /* Standard parallels used in Lambert Conformal Conic */
    BIN4  iStdParallel2;
    uint32_t iEarthRadius;       /* Earth's equitorial radius in cm */
    uint32_t iFlattening;        /* 1/Flattening in 1/1000000 */

    /* System fault status at the time the task was started.  See the
     * 'ICFB_..." macros in ingest.h for the definition of these bits.
     */
    uint32_t iFaultBits ;

    uint32_t iSiteMask;          /* Mask of sites in the product (if PF_COMPOSITED) */
    uint16_t ilog_filter_first;  /* Log filter used on first bin */
    uint16_t lclutmap_used;      /* Clutter map applied to DSP data */

    BIN4  ilat_ref;              /* Latitude of projection reference point */
    BIN4  ilon_ref;              /* Longitude of projection reference point */

    /* The following sequence number can be used whenever product files
     * need to be ordered or indexed in some way.  For example, when the
     * Nth product is written to a tape, the value is filled in with N.
     */
    uint16_t isequence_num;

    /* byte 250 was used for color set numbers before 8.11.4 */
    char  ipad250x32[32];

    int16_t iMeltingHeight;    /*Melting height MSB complemented (m above MSL)*/
    int16_t iReferenceOffset;  /* Height of radar above Reference in meters */

    /* The number of results elements at the end of the file.  Used for
     * WARN, SLINE, STAT, TRACK only.  In STAT products, there is always one
     * status_results structure, followed by iresults_count-1 status_one_message
     * structures.
     */
    int16_t iresults_count;

    /* Wind speed and direction, if available.  Set to zero if unknown.  If
     * the wind speed is known, but is zero, then set direction to 255.  Speed
     * is in nearest 0.5 m/s, and direction is binary angle.
     */
    uint8_t iWindSpeed;
    uint8_t iWindDirection;
    char  ipad290x2[2];
    char  sLocalTZName[8];       /* Name of timezone of local time */
    /* Offset of the optional extended product header from the start of
     * file */
    uint32_t iExtendedHeaderOffset;
    char  ipad304x4[4];
};

/* =========================================================================
 * ==================== Product Header =====================================
 * =========================================================================
 *
 * The following structure is the header for Product data files.  The header
 * holds the product config structure, plus related information about the files
 * that were used to make the product.  The product header is followed by the
 * data itself.
 */
#define PRODUCT_HDR_SIZE (STRUCT_HEADER_SIZE + PRODUCT_CONFIGURATION_SIZE + \
                          PRODUCT_END_SIZE)
#define STRUCT_PRODUCT_HDR_DEFINED 1
struct product_hdr
{
    struct structure_header      hdr; /* Generic Header */
    struct product_configuration pcf; /* Product Config Info */
    struct product_end           end; /* Product end info */
};
typedef struct product_hdr PHD;

/* ======================================================================
 * These specific_options structures are all long words because they
 * are served out and must be byte swapped correctly.
 */
struct generic_specific_options
{
    uint32_t iPType;             /* Not used in shared memory */
#define DEVICE_INDEX_WEB  (-1)
    int32_t  iDeviceIndex;       /* Origin 0 device index, not used in shared memory */
};

struct vad_specific_options
{
    uint32_t iPType;             /* Not used in shared memory */
    int32_t  iDeviceIndex;       /* Origin 0 device index, not used in shared memory */
#define OP_VAD_ONEPLOT (0x00000001) /* Display single VAD plot only */
    uint32_t iflags;
    uint32_t iel_index;          /* Origin 0 elevation index if one plot */
    uint32_t imax_vel;           /* Units: 2-byte velocity */
};

enum out_vvp_flags{
    OP_VVP_TIMEHEIGHT     = (0x00000001),  // Display as time/height not graphs
    // Each of these threshold control bits enables a threshold number:
    OP_VVP_THRESH_MAX_STD     = (0x00000002),  // Max hvel std
    OP_VVP_THRESH_MIN_HVEL    = (0x00000004),  // Min hvel
    OP_VVP_THRESH_MAX_HVEL    = (0x00000008),  // Max hvel
    OP_VVP_THRESH_MAX_VVEL    = (0x00000010),  // Max vvel
    OP_VVP_THRESH_MAX_REFL    = (0x00000020),  // Max average reflectivity
    OP_VVP_THRESH_MIN_SAMPLES = (0x00000040)   // Min sample size
};

struct vvp_specific_options
{
    uint32_t iPType;             /* Not used in shared memory */
    int32_t  iDeviceIndex;       /* Origin 0 device index, not used in shared memory */
    uint32_t iflags;             // Flags defined in enum out_vvp_flags
    int32_t  iheight_max;        /* Height max (cm above reference) */
    int32_t  iheight_step;       /* Step in cm */
    uint32_t ithresh_hvel_std;   /* Threshold value (0 to 100%) */

    /* Options here are for graph display only */
#define VVP_GRAPH_PLOT_MAX (5)   /* Max number of plots we will allow */
    uint32_t igr_plot_mask;      /* Mask of data to plot */
    int32_t  igr_max_hvel;       /* Units: 2-byte velocity */
    int32_t  igr_max_diverg;
    int32_t  igr_max_vvel;       /* Units: 2-byte velocity */
    int32_t  igr_max_deform;
    int32_t  igr_max_dbz;        /* Units: 2-byte dBZ */
    int32_t  igr_min_rhohv;      /* Units: 2-byte RhoHV */

    /* Options here are for time height display only */
    uint32_t ith_time_span;      /* Time span in seconds */
    uint32_t ith_time_step;      /* Min time step in seconds */
    uint32_t ith_under_plot;     /* Data to plot as underlay */
    uint32_t ith_over_plot;      /* Data to plot as overlay */
#define VVP_WIND_BARBS   (1)
#define VVP_WIND_STRINGS (2)
#define VVP_AXDIL_LINES  (3)
    uint32_t ithresh_min_hvel;   /* Minimum horizontal velocity, DB_VEL2 */
    uint32_t ithresh_max_hvel;   /* Maximum horizontal velocity, DB_VEL2 */
    uint32_t ithresh_max_vvel;   /* Maximum vertical velocity, DB_VEL2 */
    uint32_t ithresh_max_refl;   /* Maximum average reflectivity, DB_DBZ2 */
    int32_t  ithresh_min_vsamples; /* Minimum velocity sample size */
};

struct warn_specific_options
{
    uint32_t iPType;             /* Not used in shared memory */
    int32_t iDeviceIndex;        /* Origin 0 device index, not used in shared memory */
    int32_t iForecastSeconds;    /* Forecast time for arrow, none if <=0 */

    int32_t iCentroidLabel;      /* How we should label the centroids */
#define CENTROID_LABEL_NONE    (0)
#define CENTROID_LABEL_MAXIMUM (1)
#define CENTROID_LABEL_AVERAGE (2)
#define CENTROID_LABEL_SPEED   (3)

    int32_t iCentroidFill;       /* How we should fill the centroids */
#define CENTROID_FILLED  0
#define CENTROID_HATCHED 1
#define CENTROID_OPEN    2

};

struct wind_specific_options
{
    uint32_t iPType;             /* Not used in shared memory */
    int32_t iDeviceIndex;        /* Origin 0 device index, not used in shared memory */
#define OP_WIND_STRINGS (0x00000001) /* Display as strings rather than barbs */
#define OP_WIND_SUBMEAN (0x00000002) /* Subtract mean wind before displaying */
    uint32_t iflags;
    int32_t iHeight;             /* Height for CAPPIs (cm above reference)*/
    int32_t iMaxHVel;            /* Max velocity for strings, Units: 2-byte velocity */
    uint32_t iThreshold;         /* Threshold value (0 to 100%) */
};

struct thick_specific_options
{
    uint32_t iPType;             /* Not used in shared memory */
    int32_t iDeviceIndex;        /* Origin 0 device index, not used in shared memory */
#define OP_THICK_AVERZ (0x00000001) /* Display average Z rather than echo thickness */
    uint32_t iflags;
};

enum out_sws_flags{
    OP_SWS_TEMP       = (0X00000001),  //Temperature 
    OP_SWS_WEATHER    = (0x00000002),  //Weather
    OP_SWS_DEWPOINT   = (0x00000004),  //Dewpoint 
    OP_SWS_CEILING    = (0x00000008),  //Ceiling
    OP_SWS_VISIBILITY = (0x00000010),  //Visibility
    OP_SWS_SKY_COVER  = (0x00000020),  //Sky Cover
    OP_SWS_ALTIMETER  = (0x00000040),  //Altimeter
    OP_SWS_WIND       = (0x00000080),  //Wind
    OP_SWS_STATION_ID = (0x00000100),  //Station ID
    OP_SWS_EVERYTHING = (0x000001ff)
};

#define SWS_FLAGS_COUNT (9)  //Number of OP_SWS Flags 

struct sws_specific_options
{
    uint32_t iPType;             /* Not used in shared memory */
    int32_t  iDeviceIndex;       /* Origin 0 device index, not used in shared memory */
    uint32_t iflags;             /* Flags defined in enum out_sws_flags */
};

union  product_specific_options2
{
    struct vad_specific_options     Vad;
    struct vvp_specific_options     Vvp;
    struct warn_specific_options    Warn;
    struct wind_specific_options    Wind;  /* Also: CAPPI, NDOP, FCAST */
    struct thick_specific_options   Thick; /* Echo thickness options */
    struct sws_specific_options     Sws;   /* Surface Weather Station */
};


struct apo_spec
{
    uint32_t iptype;
    char     spname[16];         /* Null terminated */
    uint32_t iopacity;           /* Value between 0 and 100 (percent) */
};

/* Output options structure
 */
struct output_options
{
    struct apo_spec apo[3];      /* APO control */
  
    uint16_t iSepFlags;          /* output flags, separate for each product */
#define OP_LEGEND      (0x001)       /*Draw legend on output*/
#define OP_OVERLAY     (0x002)       /*Draw overlay on output*/
#define OP_SHADOW0     (0x004)       /*Drop shadow depth*/
#define OP_SHADOW1     (0x008)
#define OP_APO_LIVE    (0x010)       /* APO is live*/
#define OP_CATCH_LABEL (0x020)       /* Draw catch names on output*/
#define OP_CATCH_ICONS (0x040)       /* Draw catch icons rather than regions*/
#define OP_TIME_UTC    (0x080)       /* Display time in UTC rather than local */
#define OP_TIME_NODEF  (0x100)       /* Do not Display time in default */
#define OP_SEPARATE (OP_LEGEND|OP_OVERLAY|OP_SHADOW0|OP_SHADOW1|OP_APO_LIVE|OP_CATCH_LABEL|OP_CATCH_ICONS)
#define OP_COMMON   (OP_TIME_UTC|OP_TIME_NODEF)

    uint8_t irangering;          /* range ring selection */
#define OP_RING_NONE   (0)           /* No ring */
#define RING_NONE_P    (0)
#define OP_RING_ONLY   (1)           /* Ring only no numbers */
#define RING_ONLY_P    (1)
#define OP_RING_NUMS   (2)           /* Ring with numbers */
#define RING_NUMS_P    (2)
#define OP_RING_LATLON (3)           /* Lat/lon overlay */
#define RING_LATLON_P  (3)

    uint8_t ilayer_mask_index;   /* Overlay layer control */
#define OP_LAYER_MASK_NONE (0xFF)
};
typedef struct output_options OUT_OPT;

struct device_update
{
    int32_t iDevice;
    /* Indicate QL window's mode */
#define DEVICE_MODE_AUTO_NOLOOP (0)
#define DEVICE_MODE_AUTO_LOOP   (1)
#define DEVICE_MODE_USER_NOLOOP (2)
#define DEVICE_MODE_USER_LOOP   (3) 
    uint32_t iMode;
    uint32_t iCurrentSiteNum;
    uint32_t iCurrentPType;
    char  sCurrentPName[16];
    struct ymds_time Time;
    char  sTrackPName[16];   /* Track product name, zero indicates not in track mode */
    int32_t iCrossSize[2];   /* Size of cross product output, zero means not in cross mode */
};

struct ForecastOptions
{
    int32_t  iDeviceIndex;       /* Not used in memory copy */
    char   sPName[16];           /* Product name to use */
    int32_t  iTime;              /* Forecast time in seconds */
    int32_t  iSpeed;             /* Speed in cm/hour */
    BIN4   iDirection;           /* Direction */
    uint32_t  iFlags;
#define OP_FCAST_ENABLED    (0x0001)
#define OP_FCAST_USEPRODUCT (0x0002)
};

struct common_options
{
    uint32_t  iunits;
    uint16_t  iComFlags;         /* output flags, common for each product */
    uint16_t  iRingSpacing;      /* Range ring spacing in km, 0=auto */
    char   sRingCenter[16];      /* Range center from home point list */
    struct ForecastOptions Forecast;
};

struct device_output_options
{
    struct output_options ptype[NUM_DEFINED_PRODUCTS];
    struct vad_specific_options  VadOptions;
    struct vvp_specific_options  VvpOptions;
    struct warn_specific_options WarnOptions; /* Used for WARN, TDWR, TRACK */
    struct wind_specific_options WindOptions; /* Used for wind, cappi, ndop, fcast */
    struct thick_specific_options ThickOptions; /* Used for THICK (echo thickness) */
    struct sws_specific_options   SwsOptions; /* Used for SWS (Surface Weather Stations) */
    
    struct server_color_scale_def  scales[SERVER_DTYPE_COUNT];
    struct device_update Update; /* Update state is not saved to disk! */
    struct common_options Common;/* Options common to all product types */
};

struct server_output_options
{
    uint32_t iptype;
    int32_t idevice_index;
    struct apo_spec apo[3];
    uint32_t irangering;
    uint32_t iout_flags;
#define OP_SET_LAYER_ONLY  (0x10000)
    uint32_t ilayer_mask_index;
    uint32_t iunits;
    uint32_t iRingSpacing;
    char  sRingCenter[16];       /* Range center from home point list */
};
typedef struct server_output_options SOUT_OPT;

/* =========================================================================
 * =============== Miscellaneous Definitions ===============================
 * =========================================================================
 *
 * The following header is written at the beginning of each "sweep block" in
 * the Raw Product files.  It is included primarily for error recovery
 * in the context of retrieving those files from tape.
 */

#define RAW_PROD_BHDR_SIZE  (12)

struct raw_prod_bhdr
{
    int16_t irec;                /*  Record # */
    int16_t isweep;              /*  Sweep # */
    int16_t iray_ptr;            /*  Byte offset (from BHdr) of first ray */
    int16_t iray_num;            /*  Ray number of above first ray */
    uint16_t iflags;             /*  Flags */
#define APB_NOGOOD    (0x0001)       /*    Block has invalid data */
    char     ipad10x2[2];
};

/* Blocks of sweep data in the Raw file look like the following */

#define RAW_PROD_SDATA_SIZE (TAPE_RECORD_LEN - RAW_PROD_BHDR_SIZE)

struct raw_prod_block
{
    struct raw_prod_bhdr hdr;
    uint8_t ibytes[ RAW_PROD_SDATA_SIZE ];
};

#define CATCH_MAX_HOURS_STORED (96)
#define CATCH_RESULTS_SIZE (100 + 2*CATCH_MAX_HOURS_STORED)
struct catch_results
{
    char  sName[16];       /* Name of catchment area, null terminated */
    uint32_t iNumber;      /* Number of catchment area */
    BIN4  iLabelLat;       /* Lat/Long of the label (where label is drawn) */
    BIN4  iLabelLon;
    int32_t iArea;         /* Area of catchment in 1/100 of square km */
    int32_t iPixelCount;   /* Number of pixels in the catchment */
    int32_t iCoverCount;   /* Min number of pixels in the catchment scanned by the radar */
#define CATCHRES_FLG_WARN_ON  (0x01)  /* Warnings enabled for the catchment */
#define CATCHRES_FLG_WARN     (0x02)  /* Warning triggered for the catchment */
    uint32_t iFlags;

    uint16_t iRain;        /* Average rain depth in the catchment area, DB_FLIQUID2 */
    uint16_t iRainThreshold; /* Rain depth threshold to trigger threshold DB_FLIQUID2 */
    /* Threshold filled in even if the warning is turned off in flag above */

    char ipad48x52[52];
    /* Hourly rain inputs, most recent first, missing slots with DV_NOSCAN2 */
    uint16_t iRainHourly[CATCH_MAX_HOURS_STORED];
} ;

struct server_catch_results
{
    char  sName[16];         /* Name of catchment area, null terminated */
    uint32_t iNumber;        /* Number of catchment area */
    BIN4  iLabelLat;         /* Lat/Long of the label (where label is drawn) */
    BIN4  iLabelLon;
    uint32_t iHoursAndFlags;  /* Number of hours in low 16-bits, flags in high 16-bits */
    uint32_t iSpan;           /* Span in seconds of each input */
    uint32_t iRain;           /* Average rain depth in the catchment area.
                               * If DISDRO and NORAIN set, then ZRConst in low, ZRExp in high */
    /* Hourly rain inputs, most recent first, missing slots with DV_NOSCAN2. */
    uint32_t iRainHourly[CATCH_MAX_HOURS_STORED];
} ;

#define GAGE_RESULTS_SIZE (40)
struct gage_results
{
    char  sName[16];             /* Name of gage, null terminated */
    BIN32_T iLabelLat;           /* Lat/Long of the sensor */
    BIN32_T iLabelLon;
    /* Average rainrate in DB_RAINRATE2 for the time span */
    uint16_t iGageRainRate;
    /* Correction factor in dB, DB_DBZ2 format, DV_THRESH0 if none */
    uint16_t iCorrection;
    uint8_t iDataQuality;        /* Data quality flag, range 0-10 */
#define GAGE_FLG_SKIP   (0x01) /* Skip using this sensor */
#define GAGE_FLG_DISDRO (0x02) /* Sensor has Z/R numbers (is a Disdrometer) */
#define GAGE_FLG_NORAIN (0x04) /* Sensor does not have Rainrate (is not a gauge) */
#define GAGE_FLG_RADAR_RATE (0x08) /* Radar rainrate is filled in */
    uint8_t iFlag;
    uint16_t iZrConst;           /* Z-R constant in 1/10 */
    uint16_t iZrExp;             /* Z-R exponent in 1/1000  */

    /* The radar average rain rate. 
     * DV_THRESH2 means there wes no rain.
     * DV_NOSCAN2 means we tried to do it, but the radar data was missing.
     */
    uint16_t iRadarRainRate;
    char  ipad36x4[4];
} ;

/* --------------------
 * The VAD product consists of an array of the following structures, one for
 * each azimuth for each elevation in the volume scan.  Order is starting
 * with the first elevation angle, going through all the azimuths in CW
 * order.  Not all elevation angles may have the same number of azimuths.
 */

struct vad_results
{
    BIN2     ielevation;         /* Elevation angle */
    BIN2     iazimuth;           /* Azimuth angle */
    int16_t  icount;             /* Number of data points used here */
    uint16_t ivelocity;          /* Velocity in DB_VEL2 units */
    uint16_t ivel_std;           /* Velocity standard deviation in cm/sec */
    uint16_t iel_index;          /* Elevation angle index, origin 0 */
    char ipad_end[8] ;
};

/* --------------------
 * The VVP product consists of an array of the following structures, one for
 * each height interval that was computed.  There are 32 possible int*2 values
 * and a 32-bit mask in the PSI structure telling which of them were actually
 * computed and filled in.
 */
#define VVP_RESULTS_SIZE  (20 + 2*32)

struct vvp_results
{
    int32_t iVCount;           /* Number of radial velocity data points used */
    int32_t iheight;           /* Center interval height (cm above reference) */
    int32_t iZCount;           /* Number of dBZ data points used */
    int32_t iRhoCount;         /* Number of RhoHV data points used */
    char ipad16x4[4] ;
    
#define VVP_UNFOLD     0x80000000 /* Use unfolding VVP algorithm */
#define VVP_HVEL       0x00000001 /* Horizontal Wind velocity and standard */
#define VVP_HVEL_STD   0x00000002 /*  deviation in cm/sec */
    int16_t ihvel, ihvel_std;
    
#define VVP_HDIR       0x00000004 /* Wind direction and standard deviation */
#define VVP_HDIR_STD   0x00000008 /*  in degrees*10 */
    int16_t ihdir, ihdir_std;
    
#define VVP_VVEL       0x00000010 /* Vertical speed and standard deviation */
#define VVP_VVEL_STD   0x00000020 /*  in cm/sec */
    int16_t ivvel, ivvel_std;
    
#define VVP_DIVERG     0x00000040 /* Horizontal divergence in 1E7/sec, and */
#define VVP_DIVERG_STD 0x00000080 /*  its standard deviation. */
    int16_t idiverg, idiverg_std;
    
#define VVP_RVEL_STD   0x00000100 /* Std deviation of radial velocity points*/
    int16_t irvel_std;            /*  in cm/sec */
    
#define VVP_LINDBZ     0x00000200 /* Reflectivity in standard 2-byte format */
#define VVP_LOGDBZ_STD 0x00000400
    uint16_t iLindBZ, iLogdBZ_std;
    
#define VVP_DEFORM     0x00000800 /* Deformation in 1E7/sec, and its */
#define VVP_DEFORM_STD 0x00001000 /*  standard deviation. */
    int16_t ideform, ideform_std;
    
#define VVP_AXDIL      0x00002000 /* Axis of dilation (0-180 degrees) */
#define VVP_AXDIL_STD  0x00004000 /*  in degrees*10. */
    int16_t iaxdil, iaxdil_std;

#define VVP_LOGDBZ     0x00008000 /* Reflectivity in standard 2-byte format */
#define VVP_LINDBZ_STD 0x00010000
    uint16_t iLogdBZ, iLindBZ_std;

#define VVP_RHOHV      0x00020000 /* RhoHV in standard 2-byte format */
#define VVP_RHOHV_STD  0x00040000
    uint16_t iRhoHV, iRhoHV_std;

    char ipad58x26[26] ;
};
#define VVP_MAXIMUM_BITMASK (0x00020000) /* Highest bit in the regular list above */
#define VVP_ALL_PARAMS (VVP_HVEL | VVP_HVEL_STD | VVP_HDIR   | VVP_HDIR_STD | \
                        VVP_VVEL | VVP_VVEL_STD | VVP_DIVERG | VVP_DIVERG_STD | \
                        VVP_RVEL_STD | VVP_LINDBZ | VVP_LINDBZ_STD |    \
                        VVP_LOGDBZ | VVP_LOGDBZ_STD | VVP_DEFORM | VVP_DEFORM_STD | \
                        VVP_AXDIL | VVP_AXDIL_STD | VVP_RHOHV | VVP_RHOHV_STD )

/* --------------------
 * The WIND product data section consists of:
 *
 * 1) A single VVP_RESULTS structure that holds the overall wind infor-
 *    mation for the entire volume.
 *
 * 2) An array of the following structures, organized in BSCAN format,
 *    i.e., all of the ranges for the first azimuth, followed by all of
 *    the ranges for the second azimuth, etc.
 */
#define WIND_RESULTS_SIZE (32)

struct wind_results
{
    int32_t igeom_count;         /* Number of possible hits by geometry */
    int32_t idata_count;         /* Number of data points used here */
    int32_t icenter_range;       /* Sector center range in cm */
    BIN2  icenter_az;            /* Sector center azimuth as binary angle */

    int16_t ixvel;               /* East-West Wind velocity and standard */
    int16_t ixvel_std;           /*  deviation in cm/sec */

    int16_t iyvel;               /* North-South Wind velocity and standard */
    int16_t iyvel_std;           /*  deviation in cm/sec */

    char ipad22x10[10] ;
} ;

/* ----------------------------------------------
 * Results structure used for NDOP and FCAST products.
 */
struct ndop_results
{
    uint16_t iXVel;         /* East-West Wind velocity, DB_VEL2 format */
    uint16_t iYVel;         /* North-South Wind velocity */
    uint16_t iChangeRate;   /* Rate of change in dB/minute DB_DBZ2 format */
    uint8_t iSqi;           /* Fit quality index */
    char ipad7x5[5] ;
} ;
/* ----------------------------------------------
 * Structures used for LLWAS input.
 */
#define LLWAS_HEADER_INPUT_SIZE (18)
struct llwas_header_input
{
    char  sSourceID[4];
    uint16_t iMessageID;
    char  sSystemID;
    uint8_t ipad7x1;
    uint16_t iMessageLength;
    char  sLlwasStatus;
    char  sCFDirection[3];
    char  sCFSpeed[2];
    char  sCFGustSpeed[2];
};
#define LLWAS_RUNWAY_INPUT_SIZE (19)
struct llwas_runway_input
{
    char sCorridor[4];
    char sAlertType[3];
    char sLossGain[3];
    char sLossGainSign;
    char sLocation[3];           /* Location number, not arena name */
    char sThresholdDirection[3];
    char sThresholdSpeed[2];
};
#define LLWAS_INPUT_MAX (16)  /* Maximum number of runways in LLWAS input */
#define LLWAS_INPUT_SIZE (LLWAS_HEADER_INPUT_SIZE + (LLWAS_INPUT_MAX*LLWAS_RUNWAY_INPUT_SIZE))
struct llwas_input
{
    struct llwas_header_input Header; /* Header size implies runway count below */
    struct llwas_runway_input Runway[LLWAS_INPUT_MAX]; /* Optional entry for each runway */
};

/* Results structure used for TDWR products. */
#define TDWR_RESULTS_SIZE (100)
#define TDWR_RUNWAY_MAX (16)  /* Maximum number of runways in IRIS TDWR product */
struct tdwr_results
{
    char  sCorridor[16];
    char  sArena[8];
    char  sAlertType[3];
    char  ipad27x1;
    char  sThresholdDirection[3];
    char  ipad31x1;
    char  sThresholdSpeed[2];
    char  ipad34x2[2];
    int32_t iLossGain;           /* Wind speed change in mm/sec, neg=loss */
    uint32_t iProtectMask;       /* Protected areas checked for this corridor */
    uint32_t iProtectHit;        /* Protected area hit for this corridor */
    char  ipad48x52[52];
};

#define SLINE_RESULTS_SIZE  (1000)
/* Shearline product: */
#define SLINE_FLG_FCST   (0x01)
#define SLINE_FLG_WINDS  (0x02)

struct sline_results
{
    int32_t icenter_east;        /* East coordinate of center point (cm) */
    int32_t icenter_north;       /* North coordinate of center point (cm) */
    BIN4  irotation;             /* Angle (-90 to 90) to XY axis of curve fit polynomial */
    int32_t ixleft;              /* X coordinate of left of curve (cm) */
    int32_t ixright;             /* X coordinate of right of curve (cm) */
    int32_t icoefs[6];           /* Six polynomial coefficients (cm) */
    int32_t ifit_std;            /* Standard deviation of fit (cm) */

    int32_t iprop_speed;         /* Propagation speed (mm/sec) */
    BIN4  iprop_direction;       /* Propagation direction (AZ) */

    int32_t iref_wind_speed;     /* Reference side wind speed (mm/sec) */
    BIN4  iref_wind_direction;   /* Reference side wind direction (AZ) */
    int32_t iother_wind_speed;   /* Other side wind speed (mm/sec) */
    BIN4  iother_wind_direction; /* Other side wind direction (AZ) */

    int32_t iprotect_etas[32];   /* ETA (seconds) to each prot area (-1 if none) */
    uint32_t iflags;
    char  ipad_end[796];

};

#define TRACK_RESULTS_SIZE  (300)
/* Track product: */
#define TRACK_FLG_FCST   (0x01)
#define TRACK_FLG_MANUAL (0x02)
#define TRACK_FLG_TEXT   (0x04)
#define TRACK_FLG_ICON   (0x08)

struct track_results
{
    /* Position of the center of the centroid */
    BIN4  ilat;
    BIN4  ilong;
    int32_t iheight;           /* Height (cm above reference) */

    uint32_t iflags;
    int32_t iarea;             /* Area in 1/100 of square km */
    int32_t iEllipseMajor;     /* Major axis of equal area ellipse (cm) */
    int32_t iEllipseMinor;     /* Minor axis of equal area ellipse (cm) */
    BIN4  iEllipseAngle;       /* Orientation angle of ellipse (azimuth) */

    uint32_t iprotect_mask;    /* Protected area mask of areas hit */
    int32_t imax_value ;       /* Maximum value of data within the area */
    char ipad_40x8[8] ;
    int32_t iaverage_value;    /* Average value of data within the area */
    char ipad_52x8[8] ;
    int32_t iscale;            /* Scale factor of input data (cm/pixel) */

    int32_t index;             /* Track index (for connecting points) */
    char  stext[32];           /* Text, NULL terminated, icon name if icon */

    struct ymds_time time;     /* Time of this centroid point */
    int32_t iprotect_etas[32]; /* ETA (seconds) to each prot area (-1 if none) */
    uint32_t idtype[3];        /* Data type of input data, only first slot used */
    int32_t iprop_speed;       /* Propagation speed (mm/sec) */
    BIN4  iprop_direction;     /* Propagation direction (AZ) */
    uint32_t iTextSize;
    uint32_t iColor;
    char  ipad_268x32[32];

};

/* --------------------
 * The Warning product consists of an array of the following structures, one for
 * each warning found.
 */
#define MAX_WARNINGS_STORED (600)
#define WARNING_RESULTS_SIZE  (300)

struct warning_results
{
    /* Position of the center of the warning area */
    BIN4  ilatitude; 
    BIN4  ilongitude;
    int32_t iheight;             /* Height (cm above reference) */

#define WARN_FLG_NOLABEL   (0x0001)
    uint32_t iWarnFlags;
    int32_t iarea;               /* Area in 1/100 of square km */
    int32_t iEllipseMajor;       /* Major axis of equal area ellipse (cm) */
    int32_t iEllipseMinor;       /* Minor axis of equal area ellipse (cm) */
    BIN4  iEllipseAngle;         /* Orientation angle of ellipse (azimuth) */

    uint32_t iprotect_mask;      /* Protected area mask of areas hit */
    int32_t imax_value[3];       /* Maximum value of data in area (1/100 of user units) */
    int32_t iaverage_value[3];   /* Average value of data in area (1/100 of user units) */
    int32_t iscale;              /* Scale factor of input data (cm/pixel) */
    char  ipad_64x4[4] ;
    char  stext[16];             /* Text, NULL terminated */
    char  ipad_84x156[156];
    uint32_t idtype[3];          /* Data type of input data */
    int32_t iprop_speed;         /* Propagation speed (mm/sec) */
    BIN4  iprop_direction;       /* Propagation direction (AZ) */
    char  ipad_260x40[40];
};


#define STATUS_ANTENNA_INFO_SIZE (100)
struct status_antenna_info
{
    /* Current antenna position, in binary angles */
    BIN4 iazpos;
    BIN4 ielpos;

    /* Current antenna velocity, in binary angles/second
     * multiply by 180/2**31 to go to deg/sec */
    BIN4 iazvel;
    BIN4 ielvel;

    /* Current antenna command bits */
    uint32_t icommand;
    uint32_t icommand_mask;

    /* Current antenna status bits */
    uint32_t istatus;
    uint32_t istatus_mask;

    /* Current Bite flag, nonzero if there is a fault */
    uint32_t ibite_flag;
    int32_t ibite_field;         /*Lowest field number generating the fault */

    /* Antenna status bits which can make a critical fault */
    uint32_t iStatusCritical;
    /* Mask showing the state of all reported bits from BITE */
    uint32_t iBiteMask[3];
    /* Mask showing all possible faults reported from BITE */
    uint32_t iBiteFaults[3];

    char ipad_end[32];
};

struct status_one_device
{
    uint32_t itype;
    int32_t iunit;
    uint32_t istatus;
    char     ipad12x4[4];
    uint32_t imode;
    char  sname[16];             /*null terminated*/
    char  ipad_end[4];
};

/* Contains information about all the devices */
#define STATUS_DEVICE_INFO_SIZE (800)
struct status_device_info
{
    struct status_one_device   dsp;
    struct status_one_device   antenna;
    struct status_one_device   output[18];
};

#define STATUS_MESSAGE_INFO_SIZE (200)
struct status_message_info
{
    int32_t index;             /*Error entry count since IRIS started */
    MESSAGE imessage;          /*Message number */
    int32_t irepeat_count;     /*# of successive occurrences */
    char  sprocess[16];        /*Process that got the error, null terminated */
    char  stext[80];           /*Error description text, null terminated */
    char  sname[32];           /*Name of the signal, null terminated */
    struct serv_ymds_time time; /*Time first one happened */
    uint32_t imsg_type;        /*Type of message */
    char ipad_end[36];
};

#define STATUS_MISC_INFO_SIZE (200)
struct status_misc_info
{
    char srst_name[16];          /*null terminated*/
    char stsc_name[16];          /*null terminated*/
    char spsc_name[16];          /*null terminated*/
    char spom_name[16];          /*null terminated*/
    char sactive_tname[16];      /*null terminated*/
    char sactive_pname[16];      /*null terminated*/
    uint32_t iris_style;
    int32_t inetwork_count;
    int32_t iclient_count;
    char ipad108x4[4];
    int32_t idevice_count;
    uint32_t iflags;
#define STAT_FLG_AMS_ENABLED (0x00000001)
#define STAT_FLG_FAULT       (0x00000002) /* Site has a normal fault */
#define STAT_FLG_CRITICAL    (0x00000004) /* Site has a Critical fault */
#define STAT_FLG_WARN_MSG    (0x00000008) /* Site has a Warning fault message */
#define STAT_FLG_CRIT_MSG    (0x00000010) /* Site has a Critical fault message*/
    char snst_fault_site[4];
    struct ymds_time ing_time;   /* Time of start of currently running task */
    char ipad_end[64];
};

struct status_one_process
{
    uint32_t icommand;
    uint32_t imode;
    char  ipad_end[12];
};

/* Contains information about all the processes */
#define STATUS_PROCESS_INFO_SIZE (400)
struct status_process_info
{
    struct status_one_process ingest;
    struct status_one_process ingfio;
    struct status_one_process pad; /* Unused, was rtdisp before 8.02 */
    struct status_one_process output_master;
    struct status_one_process product;
    struct status_one_process watchdog;
    struct status_one_process reingest;
    struct status_one_process network;
    struct status_one_process nordrad;
    struct status_one_process server;
    struct status_one_process ribbon;
    struct status_one_process input_master;
    char ipad_end[160];
};


/* This is the structure contained in the status product */
#define STATUS_RESULTS_SIZE (1700)
struct status_results
{
    struct status_misc_info    misc;
    struct status_process_info process;
    struct status_device_info  device;
    struct status_antenna_info antenna;
    struct status_message_info message;
};
#define STATUS_PROD_OK       (0)
#define STATUS_PROD_FAULT    (1)
#define STATUS_PROD_TIMEOUT  (2)
#define STATUS_PROD_PENDING  (3)
#define STATUS_PROD_CRITICAL (4)
#define STATUS_PROD_CHOICE_COUNT (5) /* Keep this one last */

#define STATUS_MAX_MESSAGES (8)
#define STATUS_ONE_MESSAGE_SIZE (320)
struct status_one_message
{
    char sText[STATUS_ONE_MESSAGE_SIZE];
};

/* TEXT product */
#define TEXT_RESULTS_SIZE  (512)
struct text_results
{
    char string[TEXT_RESULTS_SIZE];
};

/* -------------------- Product Directory Summary --------------------
 * The following structure is used to keep track of PRODUCT file directory
 * information.  IRIS maintains this structure itself, rather than relying
 * on system-level directory searches.  This makes the directory management
 * more independent of the processor being used.
 *
 * The directory is a linear list of one_product_file structures.
 * The list is sorted:
 *
 *        1) Numerically by product type
 *  then, 2) Alphabetically by product configuration file name
 *  then, 3) By time of INGEST data used to make the product
 *  then, 4) Numerically by site number
 *
 * Structure defining one file entry.  Many of these entries are the same as
 * the corresponding values in the product configuration structure, and the
 * associated parameters should be referenced from there.
 */
#define STRUCT_ONE_PRODUCT_FILE_DEFINED 1
struct one_product_file
{
    int32_t isize;               /*File size in bytes*/
    enum iris_product_type iptype; /*Product type code*/
    uint16_t ipcf_flags;         /*Flag bits, see product_config*/
    char spname[12];             /*Product configuration name (space padded)*/

//    union one_product_file_union u;
    char sfile_name[24];         /*File name, null terminated*/
    union product_specific_info psi;
    
    /* List of the current state of output of this product to various devices. */
    uint8_t iState[ MAX_OUT_DEVICES ]; 
#define OPO_NULL        (0)             /*Do not send */
#define OPO_SEND        (3)             /*Send this file*/
#define OPO_SENT        (4)             /*File has been sent successfully*/
#define OPO_ERROR       (5)             /*Error in sending file*/
#define OPO_SENDING     (6)             /*File is being sent*/
#define OPO_CANCEL      (7)             /*Cancel the output request*/
#define OPO_CANCELLED   (8)             /*Output request has been cancelled*/

    struct ymds_time oldest_ing_time; /* Time of the oldest input */
    struct ymds_time ing_time;   /* Date and Time of newest input */
    struct ymds_time file_time;  /* File system time of last modification */
    struct ymds_time epoch_time; /* Scheduling epoch */

    uint32_t isite_num;          /* Site number */
    uint32_t iEndSiteMask;       /* Mask of sites in composite */

    char stname[12];             /* Name of task used as input*/


    /* Information essentially copied from the task configuration: */

    int32_t ixscale, iyscale;    /* Scale factors*/
    int16_t ixsize, iysize, izsize; /* Geometric dimensions*/
    uint16_t idata_out;          /* Data type code*/

    int16_t inuse_count;         /* # of processes using this file*/
    int16_t iLocalWest;          /*TZ offset to local time of product */

};

#define MAX_HOME_POINTS (16)
struct home_point
{
    char sName[16];
    uint32_t iFlags;
    BIN4  iLat;
    BIN4  iLon;
    int32_t iHeight;             /* cm above reference */
};
struct home_inventory
{
    struct home_point home[MAX_HOME_POINTS];
};

struct dem_bounding_box
{
    double ll_lat;
    double ll_lon;
    double ur_lat;
    double ur_lon;
};

struct dem_point
{
    double lat;
    double lon;    
};


#define MAX_DEFINED_STRINGS (16)
struct string_inventory
{
    char string[32];
};

/* Product Directory Structure itself. */
#ifdef SIGMET_SETUP_H
#define STRUCT_PRODUCT_INVENTORY_DEFINED 1
struct product_inventory
{
    struct device_output_options device[MAX_OUT_DEVICES];
    struct device_output_options web_device;  /* Only part is used */
    struct overlay_mask_dir      overlay;
    struct home_inventory        HomeInv;
    struct string_inventory      StringInv[MAX_DEFINED_STRINGS];
    
    int32_t ioffset_to_OPF;
    char spom_file[12];          /* Space padded */
    char soverlay_list[SITE_LIST_SIZE][16]; /* NULL terminated */
    
    /* The following arrays hold information grouped by each product type.
     * The corresponding variable with "_tot" suffix represents the sum
     * of all elements in each array.
     */
    /* Total size of products */
    struct kilo_count prod_bytes[NUM_DEFINED_PRODUCTS];
    struct kilo_count prod_bytes_tot ;
    /* Total number of products */
    int32_t           iprod_count[NUM_DEFINED_PRODUCTS] ;
    int32_t           iprod_count_tot ;
    /* Total size of kept products */
    struct kilo_count keep_bytes[NUM_DEFINED_PRODUCTS] ;
    struct kilo_count keep_bytes_tot ;
    /* Total number of kept products */
    int32_t           ikeep_count[NUM_DEFINED_PRODUCTS] ;
    int32_t           ikeep_count_tot ;
    
    uint16_t ldelete;            /*Something has been marked for deletion*/
    char  ipad10x2[2];
    
    struct linear_list_header LHead;
    int32_t                iLList[ 1 ];
    /*  struct one_product_file  file[ * ]; */

};
#endif  /* #ifdef SIGMET_SETUP_H */

struct serv_product_header_only
{
    uint32_t    iHeadFlags;      /*See definitions in one_header_only above */
    uint32_t iOutputMask[SITE_LIST_WORDS]; /*See definitions in one_header_only above */
};

struct serv_product_file_only
{
    uint32_t isite_num;

    char stname[16];             /*Null terminated*/
    char spsi_text[28];          /*Null terminated*/
    uint32_t idata;              /*Data type of the product*/
    uint32_t ixsize, iysize, ixscale; /* Only filled in for POM FIND command */
    struct serv_ymds_time ing_time;

    uint32_t iState;       /*See definitions in one_product_file_only above */

};

union serv_product_union
{
    struct serv_product_header_only Head;
    struct serv_product_file_only   File;
};
/* Product header summary used for communication with the iris client
 * interface.
 */
struct serv_product_header_summary
{ 
    int32_t ibytes;              /*Number of bytes */
    char spname[16];             /*Null terminated*/

    uint32_t iptype;
    uint32_t iflags;             /*Flag bits */
    union serv_product_union u;
};

typedef struct serv_product_header_summary SPHD_SUM;


/* Header structure used just for the POM menu */
struct pom_list_header
{
    struct server_list_header lhdr;
    char sfile_name[16];         /* Name of file, null terminated */
    uint32_t ilayer_mask_indicies[MAX_OUT_DEVICES][NUM_DEFINED_PRODUCTS];
};

/* Data can be cast this way for client-server transfer */
struct pom_list
{
    struct pom_list_header hdr;
    struct serv_product_header_summary list[1];
};


/* Structures used to save send requests in the POM */
struct pom_save_sends_device
{
    uint32_t iOutputMask[SITE_LIST_WORDS];
    uint8_t  iHeadFlags;
};
struct pom_save_sends
{
    uint32_t iPType;
    char     sPName[16];
    struct pom_save_sends_device Device[MAX_OUT_DEVICES];
};

#define MAX_POM_SENDS_SAVED (400)
struct pom_save_sends_list
{
    struct pom_save_sends Sends[MAX_POM_SENDS_SAVED];
};


struct ServProductCursor
{
    BIN4  iLat;              /* Cursor location, only used for CATCH & GAGE */
    BIN4  iLon;
};

union ServProductOptions
{
    struct   ServProductCursor Cursor;
    uint32_t iOutputMask[SITE_LIST_WORDS];
    char spname[16];             /* Null terminated additional product name*/
};

/* Used for product loading in the window process, and POM menu
 */
struct ServProductLoad
{                 
    int32_t idevice;             /* Device number */
    uint32_t iptype;             /* Product type */
    char spname[16];             /* Null terminated*/
    /* Year to YEAR_MOST_RECENT means send most recent */
    struct serv_ymds_time ing_time;
    uint32_t isite_num;          /* Can be SITE_WILD */
    union ServProductOptions Options;
};

/** Used to load gage and radar avg. accum. to plot data per gage
 */ 
struct RainGageLoad
{
    int32_t idevice;             /* Device number */
    uint32_t iptype;             /* Product type */
    char spname[16];             /* Null terminated*/
    struct serv_ymds_time ing_time; /* Year to YEAR_MOST_RECENT means send most recent */
    uint32_t isite_num;          /* Can be SITE_WILD */
    char rain1_name[16]; /* Optional: null terminated name of the RAIN1 product */
    struct ServProductCursor Cursor;
};

/* Used to request the slide show info from the server */
struct  SlideShowList
{
    uint32_t iSiteNumber;    /* Site number, can be SITE_WILD */
    uint32_t iPType;         /* Product type */
    char  sPName[16];        /* Product name, null terminated */
    uint32_t iTimeLag;       /* Lag of product, 0=most recent, 1=next older, etc. */
    uint32_t iDwellTime;     /* How long to display the product, seconds */
};

/* Product List Structure */

#define PCF_LINKED_LIST_SIZE ( LINKED_LIST_HEADER_SIZE +                \
                               (LINKED_LIST_ITEM_SIZE * MAX_PSC_SLOTS) )
struct pcf_linked_list
{
    struct linked_list_header lhdr;
    struct linked_list_item   llst[ MAX_PSC_SLOTS ];
};

/* #define PSC_ENTRY_SIZE (PRODUCT_CONFIGURATION_SIZE + 4) */
enum psc_entry_flags{
    PSC_FLG_HIDDEN   = (0x00000001)  // Do not display in GUI
};
struct psc_entry
{
    struct product_configuration pcf;
    uint32_t isite_num;
    struct ymds_time generation_end_time;
    enum psc_entry_flags psc_flags;
};

/* Product schedule stored in shared memory. */

struct product_schedule
{
    struct   psc_entry entry[MAX_PSC_SLOTS];
    struct   pcf_linked_list pcf_l;
    char     spsc_file[12];
    uint32_t isite_group_mask[SITE_LIST_WORDS];
};
typedef struct product_schedule PSC;

/* product schedule summary structure used for server communication */

struct serv_product_schedule_summary
{
    uint32_t       iptype;       /*product type */
    char           spname[16];   /*product configuration name(null term.) */
    char           stname[16];   /*task configuration name(null terminated) */
    char           sDataOut[8];  /* product data generated */
    uint32_t       isch;         /* scheduling */
    struct serv_ymds_time epoch; /* beginning of period */
    int32_t        isch_skip;    /* # seconds between runs */
    uint32_t       iflags;       /* flags */
    uint32_t       iruns;        /* # of times has being run */
    uint32_t       isite_num;    /* Site number (includes special codes) */
    uint32_t       isite_mask[SITE_LIST_WORDS]; /* Mask of all sites in the inventory */
};

#define PSC_SITE_ALL     (0xFFFFFFFF)
#define PSC_SITE_MASTER  (0xFFFFFFFE)
#define PSC_SITE_GROUP   (0xFFFFFFFC)

typedef struct serv_product_schedule_summary SPSC_SUM;

/* Possible replys to server check request */
#define PSC_MISSING   (1)
#define PSC_IDLE      (2)
#define PSC_SCHEDULED (3)
#define PSC_RUNNING   (4)

struct lat_lon_bin4
{
    BIN4 iLatitude;
    BIN4 iLongitude;
};
struct projection_configuration
{
    uint32_t iprojection_type;
    struct lat_lon_bin4 Center;
    struct lat_lon_bin4 Reference;
    uint32_t ixsize;             /* Horizontal size in pixels */
    uint32_t ipad_24x4;
    /* Distance from center to East edge of the area in cm */
    uint32_t ideast;            
    /* Distance from center to North edge of the area in cm */
    uint32_t idnorth;
    /* Standard parallels used in Lambert Conformal Conic */
    BIN4  iStdParallel1;
    BIN4  iStdParallel2;
    uint32_t iEarthRadius;       /* Earth's equitorial radius in cm */
    uint32_t iFlattening;        /* 1/Flattening in 1/1000000 */
    char  ipad_end[48];
};

#ifdef SIGMET_SETUP_H
struct pom_scale
{
    char  sname[20];
    uint32_t iset_number;
    uint32_t icolcnt;
    uint32_t iFlags;
};

/* Structure used for pom options
 */
struct server_pom_scale_def
{
    int32_t    idevice_index;  /*Index and dtype not used in product configuration */
    uint32_t   idtype;

    uint32_t   iflags;
    int32_t    icolcnt;
    int32_t    istart;
    int32_t    istep;
    uint32_t   iset_number;      /* Origin 1 */
    uint32_t   iscale_number;    /* Custom scale number, Origin 0 */
    /* Information about each set */
    char       set_list[COLOR_SET_COUNT][20];
    /* information about each scale */
    struct pom_scale scales[COLOR_SCALE_COUNT];
    uint32_t ihighlight_red, ihighlight_green, ihighlight_blue;
    uint32_t ihighlight_cell;    /* Which color cell to highlight */
};

/* Structure used for pcf scales
 */
struct server_scales_setup
{
    struct pom_scale scale[SETUP_DTYPE_COUNT][COLOR_SCALE_COUNT];
};
#endif  /* #ifdef SIGMET_SETUP_H */


/* ============================================================
 * Output process layout control.
 */
struct layout_control
{
    /* The size of the final image: */
    int32_t ifinal_size[2];

    /* Base position for the legend in the final image.  Note that
     * only one axis is used here at a time.
     */
    int32_t ilegend_pos[2];

    /* Base position for the product image in the final image. */
    int32_t iproduct_pos[2];

    /* Size of the product image in the final image. */
    int32_t iproduct_size[2];

    /* Size on the main panel in the final image of the product image. */
    /* This is the same as the product_size, except for max products,
     * in which case it is the product_size minus the side panel size
     * in the final image.  The apo_image is drawn to this size. */
    int32_t iproduct_size_main[2];

    /* Size on the source product image in the file. */
    int32_t isrc_size[2];

    /* The variables below are used only for the merge operation to
     * copy the cartesian APO product into the display window.
     * Because the product size does not need to match, this operation
     * is more complicated.
     */
    /* Size of area in source product to copy from. */
    int32_t iapo_src_size[2];
    /* Offset within the source product image to copy from. */
    int32_t iapo_src_offset[2];
    /* Size of area in final image to copy to. */
    int32_t iapo_prod_size[2];
    /* Offset within the final image to copy to. */
    int32_t iapo_prod_offset[2];

#define LEGEND_ON         (0x01)
#define LEGEND_SMALL      (0x02)
#define LEGEND_MEDIUM     (0x04)
#define LEGEND_HORIZONTAL (0x08)
#define LEGEND_VERTICAL   (0x10)
    uint16_t iLegendFlags;
    /* Flag to indicate that the merge being done is for the APO.
     * This means that the APO variables control what to do.
     */
    uint16_t lapo_copy;

};

/* =========================================================================
 * ================== On Screen Pictures ===================================
 * =========================================================================
 *
 * The following structures are used internally to represent the contents of
 * a display screen, on which is drawn text and data of any sort.  These
 * structures are used by the Output and Window processes.
 *
 * An "On Screen Picture" is made up of rectangular
 * "Data Images", which represent the parameter(s) available for view.
 * Outside of these images there can appear text and annotations of any kind.
 * However, within the Image the pixels represent data in one of several
 * available projections and data types.
 *
 * The concept of images within the picture makes it possible to perform
 * pixel-level post processing of the display.  For example there is sufficient
 * information to place a user-selected overlay on top of any existing image.
 * Likewise it would be possible to report the range, height, bearing, and
 * data level in scientific units for any pixel chosen via, for example, a mouse
 * cursor.
 *
 * The following structure defines a Data Image within a larger picture.
 */

/* size can be freely changed */
struct data_image
{
    /* Coordinates of the image in pixles */
    double fwin_pos[2];
    double fwin_size[2];         /* size is from center to center of pixels. */

};

/* The on screen picture structure gives information about the full screen
 * and holds several data image records.
 */
#define PICTURE_MAX_IMAGES      (4)
/* Size can be freely changed */

#define GEOM_VOID      (0)  /* indicates no picture here */
#define GEOM_PPI       (1)  /* used for ppi */
#define GEOM_RHI       (2)  /* used for rhi */
#define GEOM_EARTH     (3)  /* used for tops, base, thick, rain1, rainn, vil, shear, etc */
#define GEOM_CROSS     (4)  /* used for cross */
#define GEOM_CAPPI     (5)  /* used for cappi */
#define GEOM_OTHER     (6)  /* used for vvp, raw, warn, track and vad */
#define GEOM_BEAM      (7)  /* used for beam */
#define GEOM_RTI       (8)  /* used for RTI */


#ifdef SIGMET_SETUP_H
#define STRUCT_PRODUCT_SCREEN_HEADER_DEFINED 1
struct product_screen_header
{
    struct product_hdr     pheader;
    struct colorset_setup  ColorSet;
    struct color_scale_def ColorScale;
    union level_control    Level;
    enum iris_data_type    DataTypeOfLegend;
};
#endif  /* #ifdef SIGMET_SETUP_H */

#ifdef SIGMET_SETUP_H
#ifdef SIGMET_PROJECTION_H
#ifdef STRUCT_PRODUCT_SCREEN_HEADER_DEFINED
#define STRUCT_ON_SCREEN_PICTURE8_DEFINED 1
struct on_screen_picture8
{
    struct mpj_projection8 projection;
    struct mpj_region8     region;

    /* First section contains things derived from the product inventory */
    int32_t ixsize;              /* x and y dimensions of the */
    int32_t iysize;              /*  full picture array */

    uint32_t isite_num;          /*  radar site number*/

    /* Type of geometry for the data.  note that this is required mainly to
     * support the user cursor.  For some data this does not apply.
     */
    uint32_t igeom;
  
    /* Header for the base product */
    struct product_screen_header PScreen;
    /* Headers for the possible APO products */
    struct product_screen_header ApoPScreen[3];
    struct latlon8 RadarLatLon;  /* Position of the radar in radians */
    double         fTower;       /* Height of radar (km above reference) */

    /* Information related to the method of display */
    char   soverlay[12];         /* overlay file name to use, based on site */
    uint32_t  ilayer_mask;       /* Overlay layer mask */
    struct latlon8 RingCenter;   /* Position of ring center in radians */
    struct output_options options; /* output options */
    union  product_specific_options2 PSO;
    struct common_options Common;

    /* Everything below here is not initialized until the product
     * file is actually loaded into memory.
     */

    /* Display scale in cm/pixel */
    int32_t ixscale;
    int32_t iyscale;

    int32_t image_count;         /* number of images defined */

    /*Image pixel location corresponding to the radar location for image 0.
     * Not applicable for some geometries.  
     * These are in 1/1000 of pixels, relative to the defined window.
     */
    int32_t ixrad, iyrad;

    struct data_image img[PICTURE_MAX_IMAGES];
    struct layout_control layout;
    char sPsiText1[60];          /* PSI legend text strings. Max 17 chars */
    char sPsiText2[60];
    char sPsiText3[60];
    char sPsiText4[60];
    char sPsiText5[60];
    char sPsiText6[60];

    int32_t iActFileSize;        /* Actual size of the product file on disk */

    /* Time and zone to use on the legend */
    struct ymds_time DisplayYmds;
    char  sDisplayTZName[TZNAME_SIZE];

    int16_t iDisplayOffset;      /* Display offset in minutes to default time */
    uint8_t bDataImageValid;     /* Data image is valid */
    char  ipad_end[5];
};
#endif  /* #ifdef STRUCT_PRODUCT_SCREEN_HEADER_DEFINED */
#endif  /* #ifdef SIGMET_PROJECTION_H */
#endif  /* #ifdef SIGMET_SETUP_H */

/* Structure used for some communication between the output and window processes
 * in shared memory.
 */
#ifdef SIGMET_SETUP_H
#ifdef SIGMET_PROJECTION_H
#ifdef INCLUDE_X11_PROTOTYPES
struct output_to_window_info8
{

    int32_t idevice;      /* Device number for the output process */
    int32_t ievent_flag;  /* Event flag number for the output process */
    uint32_t iwidth;      /* Width of the image */
    uint32_t iheight;     /* Height of the image */
    uint16_t lack_image;  /* Image is acknowledged by window process */
    uint16_t lready;      /* Window process is ready to go */
    char ipad20x76[76];

    XVisualInfo VisualInfo;
    struct window_device wDevice;
    struct special_colors Special;
    struct class_label_setup ClassLabels; /* Custom class labels */
    struct on_screen_picture8 onscreen;  /* Describes what is in the image*/
};
#endif  /* #ifdef INCLUDE_X11_PROTOTYPES */
#endif  /* #ifdef SIGMET_PROJECTION_H */
#endif  /* #ifdef SIGMET_SETUP_H */

/* Structure used for communication between the output and window processes
 * via pipes.
 */
#define OtoWNop      (0)
#define OtoWNewImage (1)

struct OtoWPipe
{
    uint32_t icommand;
    uint32_t ispare1;
    uint32_t iwidth;
    uint32_t iheight;
    uint32_t ispare2;
};

/* Used for saving state of quick look window.
** Ascii data saved in file /usr/sigmet/config/window.conf
*/
#define MAX_SLIDES_IN_SHOW 16
struct WindowSetup
{
    char sVersion[8];
    uint32_t  iSlidesInShow;
    struct SlideShowList slideShowList[MAX_SLIDES_IN_SHOW];
};


#define STRUCT_CARTESIAN_PRODUCT_DEFINED 1
struct cartesian_product
{
    struct product_hdr Header;
    uint8_t            Data[1];  /* Number and dimensions are variable! */
};

struct catch_product      /* For CATCH products */
{
    struct product_hdr Header;
    struct catch_results Results[1]; /* Number is variable! */
};

struct fcast_product      /* For FCAST and NDOP products */
{
    struct product_hdr Header;
    struct ndop_results Results[1];  /* Number is variable! */
};

struct gage_product      /* For GAGE products */
{
    struct product_hdr Header;
    struct gage_results Results[1];  /* Number is variable! */
};

#define STRUCT_SWS_PRODUCT_DEFINED 1
struct sws_product
{
    struct product_hdr Header;
    uint8_t            Data[1];  /* Number of bytes is variable! */
};

struct image_product
{
    struct product_hdr Header;
    uint8_t            Image[1];     /* size is variable! */
};

struct ndop_product      /* For FCAST and NDOP products */
{
    struct product_hdr Header;
    struct ndop_results Results[1];  /* Number is variable! */
};

#ifdef STRUCT_INGEST_HEADER_DEFINED
#ifdef SIGMET_SIG_DATA_TYPES_H
#define SIGMET_TAPE_RECORD_DEFINED 1
union  tape_record
{
    int16_t Data2[TAPE_RECORD_LEN/2];
    struct product_hdr   PHeader; /* Only for first record */
    struct ingest_header IHeader; /* Only for second record */
};
#endif  /* #ifdef SIGMET_SIG_DATA_TYPES_H */
#endif  /* #ifdef STRUCT_INGEST_HEADER_DEFINED */

#ifdef SIGMET_TAPE_RECORD_DEFINED
#define SIGMET_RAW_PRODUCT_DEFINED 1
struct raw_product
{
    union  tape_record   Record[3];  /* Number is variable! */
};
#endif  /* #ifdef SIGMET_TAPE_RECORD_DEFINED */

#ifdef SIGMET_SETUP_H
struct sline_product
{
    struct product_hdr   Header;
    struct protect_setup Protect;
    struct sline_results Results[1]; /* Number is variable! */
};
#endif  /* #ifdef SIGMET_SETUP_H */

struct stat_product
{
    struct product_hdr        Header;
    struct status_results     Result;
    struct status_one_message Messages[STATUS_MAX_MESSAGES]; /* Number is variable! */
};

#ifdef SIGMET_SETUP_H
struct tdwr_product
{
    struct product_hdr   Header;
    struct protect_setup Protect;
    struct tdwr_results  Results[TDWR_RUNWAY_MAX];  /* Number is variable! */
    /* Actually contains shearlines and llwas results also */
};
#endif  /* #ifdef SIGMET_SETUP_H */

#ifdef SIGMET_SETUP_H
struct track_product
{
    struct product_hdr   Header;
    struct protect_setup Protect;
    struct track_results Results[1]; /* Number is variable! */
};
#endif  /* #ifdef SIGMET_SETUP_H */

struct vad_product
{
    struct product_hdr   Header;
    struct vad_results   Results[1]; /* Number is variable! */
};

struct vvp_product
{
    struct product_hdr   Header;
    struct vvp_results   Results[1]; /* Number is variable! */
};

#ifdef SIGMET_SETUP_H
#define SIGMET_WARN_PRODUCT_DEFINED 1
struct warn_product
{
    struct product_hdr     Header;
    struct protect_setup   Protect;
    struct warning_results Results[MAX_WARNINGS_STORED];  /* Number is variable! */
};
#endif  /* #ifdef SIGMET_SETUP_H */

struct wind_product
{
    struct product_hdr    Header;
    struct vvp_results    Vvp;
    struct wind_results   Results[1];/* Number is variable! */
};

#ifdef SIGMET_WARN_PRODUCT_DEFINED
#ifdef SIGMET_RAW_PRODUCT_DEFINED
#define SIGMET_GENERIC_PRODUCT_DEFINED 1
union generic_product
{
    struct product_hdr       Header;
    struct cartesian_product Cartesian;
    struct catch_product     Catch;
    struct fcast_product     Fcast;
    struct gage_product      Gage;
    struct image_product     Image;
    struct ndop_product      Ndop; 
    struct raw_product       Raw;
    struct sline_product     Sline;
    struct stat_product      Stat;
    struct tdwr_product      Tdwr;
    struct track_product     Track;
    struct vad_product       Vad;
    struct vvp_product       Vvp;
    struct warn_product      Warn;
    struct wind_product      Wind;
    struct sws_product       Sws;
};
#endif  /* #ifdef SIGMET_RAW_PRODUCT_DEFINED */
#endif  /* #ifdef SIGMET_WARN_PRODUCT_DEFINED */


/* ============================================================ */
/* Structures related to making products.  Used internally 
 * within IRIS product generator only.
 */
#define GPPI_MOMENTS       (2)  /* Number of data types openable per sweep */
#define NUM_GPPI_SWEEPS   (40)  /* Max number of sweeps (must be mult of 4) */
struct gppi_psi_beam   /* Information about the beam product generation */
{
    FLT4  fel_low;
    FLT4  fel_high;
    uint32_t int_az_start;
    uint32_t int_az_end;
    int32_t int_az_cnt;  /* Azimuth count of internal array, could be larger than inrev */
};

struct gppi_psi_cappi
{
    double fcappi_height;        /* CAPPI height (km above reference) */
    uint16_t lcappi_filled;      /* Fill near and far ranges with best guess */
    char  ipad_end[2];
};

struct gppi_psi_mhg
{
    int16_t iNumFields;          /* How many data fields (data, certainty, quality..) */
};

struct gppi_psi_sri
{
    double fSurfaceHeight;       /* Height to correct surface to (km above reference) */
    double fMeltingHeight;       /* Melting height (km above MSL) */
    double fMeltingThickness;        
    double fMeltingIntensity;
    double fGradientAbove;
    double fGradientBelow;
    double fMaxHeight;
    const struct terrain_site_header *pTerrain;
    uint32_t iPsiFlags;          /* Flags copied from sri_psi_struct */
    int32_t iBinCount;           /* Total number of bins used */
    int32_t iDataCount;          /* Number of bins which had data */
    int32_t iCorrCount;          /* Number of data bins passing non-convective test */
    int32_t iConvectiveZ;        /* Convective Z Threshold in 8*Z 1-byte units */
    int     it_index;            // Location of T data
    int     iz_index;            // Location of Z data
    uint8_t iConvectiveHeight;   /* Convective height (rel to reference) in 1-byte units */
    uint8_t lApplyProfileCorrection;/* We will do the profile correction */
    char  ipad_end[2];
};

struct gppi_psi_shear
{
    uint8_t lExtraSweepForElShear; /* An extra sweep is open for elevation shear  */
    char  ipad_end[3];
};

/* Used for TOPS, BASE, HMAX, and THICK */

#ifdef __cplusplus
struct gppi_psi_tops
{
    int32_t iZThresh;            /* Z Threshold in 8 * Z Byte Units */
    int16_t iMomentIndex;        /* Which moment to make */
    bool    bAllowUnknown;
};
#endif

/* Used for VIL and LAYER */
#ifdef __cplusplus
struct gppi_psi_vil
{
    double fvil_bot, fvil_top;   /* VIL height limits, km above reference */
    double fvil_a, fvil_b;       /* ZW constants  Z = a R**b */
    bool   is_log_z_data_in;     /* Log Z is linear averaged */
    bool   is_log_z_data_out;    /* Log Z is logged after averaging */
    bool   is_log_vir_data_out;  /* Log Z-km output after averaging */
    bool   is_thresh_zero;       /* Treat threshold data as zeros */
};
#endif

#ifdef __cplusplus
union gppi_psi
{
    struct gppi_psi_beam  Beam;
    struct gppi_psi_cappi cappi;
    struct gppi_psi_mhg   mlhgt;
    struct gppi_psi_sri   Sri;
    struct gppi_psi_tops  tops;
    struct gppi_psi_vil   vil;
    struct gppi_psi_shear Shear;
};
#endif

/* The following structure holds information of general interest during the
 * making of generic PPI's.  It is collected into a single structure to make it
 * easier to pass around to routines.
 */
#ifdef __cplusplus
#ifdef SIGMET_SIG_DATA_TYPES_H
struct GPPI_Global8
{
    uint16_t iptype;             /* Needed for certain GPPI routines */
    int16_t isweeps;             /* # of /GPPI_Sweep/'s available */

    uint16_t iflags;             /* Processing flags */
#define GPF_UNSIGNED         (0x0001) /* Input data type is unsigned (not velocity)*/
#define GPF_GRADIENT         (0x0002) /* Use gradient extrapolation, else half-way */
#define GPF_MELTING_UNKNOWN  (0x0004) /* Melting height is unknown */
#define GPF_EXTRAPOLATE      (0x0008) /* Extrapolate if one elevation thresholded */
#define GPF_NO_INTERPOLATION (0x0010) /* Use half-way interpolation (for HClass) */

    int16_t inrev;               /* # angles in one full circle */
    int16_t isndx;               /* Starting index of sweep (0 - INREV-1) */
    int16_t irtotl;              /* Total # of rays in sweep */

    uint16_t iDataIn;            /* Input data type */
    uint16_t iDataOut;           /* Output Data type */
    int16_t ibins;               /* # of bins of cylindrical data */
    double fstart, fstep;        /* Start and Step in km of those bins */
    double fRZConst;             /* R-from-Z constant */
    double fRZExp;               /* R-from-Z exponent */
    double fRadarHeight;         /* Height of radar (km above MSL) */
    double fRadarOffset;         /* Height of radar (km above reference) */
    double fReferenceHeight;     /* Height of the zero reference (km above MSL) */
    double fTruncationHeight;    /* Height of truncation (km above radar) */
    double fZCalib;              /* Calibration reflectivity (dBZ at 1 km) */
    double fMeltingHeight;       /* Melting height (km above MSL) */
    double fVertBeamWidth;       /* Vertical beam width in radians */
    int16_t ilimits[2];          /* Actual useful data bin limits */

    struct data_convert Convert; /* Data convert structure */
    union gppi_psi gpsi;
};
#endif  /* #ifdef SIGMET_SIG_DATA_TYPES_H */
#endif  /* #ifdef __cplusplus */

/* The GPPI product types open all available Ingest sweeps of a given
 * parameter, and assembles them into an array of /GPPI_Sweep/ records.
 * There is sufficient information in the structure to allow a mixture
 * of hybrid PPI scans, i.e., from a sequence of scans that are not
 * exactly the same geometry.
 */
#ifdef STRUCT_INGEST_DATA_FILE_DEFINED
#define STRUCT_GPPI_MOMENT_DEFINED 1
struct gppi_moment
{
    struct ingest_data_file *pIngest; /* MAP info for Ingest data file */
    int32_t iSize, iChannel;          /*   (NULL if unused )           */
};
#endif  // #ifdef STRUCT_INGEST_DATA_FILE_DEFINED

#ifdef SIGMET_DATA_CONVERT_DEFINED
#ifdef LINUX_VECTOR_INCLUDED
#define SIGMET_GPPI_SWEEP_DEFINED 1
#define GPPI_SWEEP_SIZE (80)
struct GPPI_Sweep
{
    double fElv;                 /* Elevation angle of sweep in radians */
    std::vector<struct gppi_moment> Moments;
    double fstart, fstep, fmax;  /* Range start, step, and end in Km */
    int16_t ibinsmax;            /* Max number of bins / ray */
    int16_t itask;               /* task number (for hybrid cases) */
    int16_t isweep ;             /* Sweep number within the task */
    int16_t irtotl;              /* Total # of rays in sweep */
    int16_t iGppiIndex;          /* Origin zero sweep number within the GPPI open list */
    double fNyquist, fnyratio;   /* Nyquist velocity in m/sec, and ratio to 1st task vel. */
    struct data_convert Convert; /* Data convert structure */
};
#endif  /* #ifdef LINUX_VECTOR_INCLUDED */
#endif  /* #ifdef SIGMET_DATA_CONVERT_DEFINED */

/* Macro to perform byte interpolation between two values, given
 * a fractional 14-bit scale factor.  The scale tells what
 * fraction of the way to go from the first value to the second
 * value.  Either unsigned or signed (i.e., circular)
 * interpolation is performed.
 */
#define SINTERPOLATE1( mul, a, b )                                      \
    (a) + (( ((uint16_t)(mul)) * (int8_t)( (b) - (a)   ) ) >> 14 )

#define UINTERPOLATE1( mul, a, b )                                      \
    (a) + (( ((uint16_t)(mul)) * ( UFIX1(b) - UFIX1(a) ) ) >> 14 )

#define UINTERPOLATE2( mul, a, b )                                      \
    (a) + (( ((uint16_t)(mul)) * ( UFIX2(b) - UFIX2(a) ) ) >> 14 )


/* Macros to extend data without sign extending.
 */
#define UFIX1(w) ((int32_t)(uint32_t)(uint8_t)(w))
#define UFIX2(w) ((int32_t)(uint32_t)(uint16_t)(w))


#ifdef __cplusplus
}
#endif
#endif /* #ifndef SIGMET_PRODUCT_H */
