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

/** @file
 *
 * Structures for base Ingest
 * Include Requirements: sigtypes.h
 *                       headers.h
 *                       iris_task.h
 *
 * $URL: https://subversion.vaisala.com/svn/repos/sigmet/wr_iris_rda/branches/release8.13.5/base/include/ingest.h $
 *
 * $Id: ingest.h 30022 2014-05-27 20:42:51Z rke $
 *
 */

#ifndef SIGMET_INGEST_H
#define SIGMET_INGEST_H 1

#ifdef __cplusplus
extern "C" {
#endif

/*
 * -------------------- Ingest Header File Concepts --------------------
 *
 * An INGEST header file is written for each volume scan, and is updated each
 * time a sweep is finished.  This allows product generators to get data as each
 * sweep completes, without having to wait for the full volume scan.
 *
 * The file contains the ingest_header structure, which consists of:
 *
 *     * Site Configuration Structure
 *     * Task Configuration Structure
 *     * 732 bytes spare
 *     * GPARM from DSP#1
 *     * GPARM from DSP#2
 *
 * Note that the INGEST header file is also the Volume Header Record for INGEST
 * data that are archived onto tape.
 *
 * INGEST header file names have the form  YYMMDDSSSSS. where
 *     YYMMDD  are year, month, and day in decimal.  The year is the last two
 *             decimal digits of a value between 1950 and 2049.
 *     SSSSS   is # seconds into the day in decimal.
 *
 * The data file names associated with a header file are YYMMDDSSSSS.WWP where
 *     WW    is the sweep number in decimal.
 *     P     is the parameter number recorded in the file, where the numbers
 *           correspond to bits in Task_DSP_Info.IDATA.  P takes on values
 *           0,1,2...9,A,B,...U,V.
 *
 * On machines that limit file name length to 14 characters, the dot can be
 * eliminated from the file name.
 */
#define INGEST_CONFIGURATION_SIZE  (480)    /* Size of Site Information */

struct ingest_configuration
{
  char sfile[80];                       /* Name of File on disk */

  /* IDFNUM indicates the current number of data files that are associated with 
   * this summary file.  As sweeps are performed and more data files are added
   * to the INGEST directory, IDFNUM is bumped accordingly.  Likewise, IDFSIZE
   * tallies up the total size in bytes of those data files.
   */
  SINT2 idfnum;                      /* # of associated data files extant */
  SINT2 isweeps_done ;		     /* # of sweeps that have been completed */
  SINT4 idfsize;                     /* Total size of those files */

  /* Date and time that the Volume Scan was started.  This is not necessarilly
   * equal to the starting time of the first sweep, but is always .LE. to it.
   */
  struct ymds_time VolumeYmds;
  char ipad100x12[12];

  /* Sizes of various things
   */
  SINT2 ib_rayhed;                   /* # bytes in ray headers */
  SINT2 ib_xhdr;                     /* # bytes in Extended Header */
  SINT2 ib_task;                     /* # bytes in task config table */
  SINT2 iPlaybackVersion;            /* Playback version number */
  char ipad120x4[4];
  char siris_version[8];             /* Null terminated */
  char sHardwareName[16];            /* Ingest hardware name, space padded */
  SINT2 iLocalWest;                  /* # minutes local standard time is west of GMT */

  /* 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. 
   */
    char  sSitename[16];               /* IRIS Radar sitename, space padded */
  SINT2 iMinutesWest;                /* # minutes recorded standard time is west of GMT */
  BIN4  ilat, ilon;                  /* Latitude and Longitude */
  SINT2 ignd_hgt;                    /* Ground height (m above sea level) */
  SINT2 irad_hgt;                    /* Radar height (m above ground) */

  /* Information about the organization of the ray pointers in the data files
   * for this summary file.  The ray pointers at the beginning of each INGEST
   * data file point to IRTOTL rays whose nominal angles are taken from the set
   * of INREV equally spaced angles around the circle starting from zero degrees.
   * ISNDX is an index in the range [0 - INREV-1] that specifies the nominal angle
   * of the first ray.  For some types of scans the pointer table is not sorted
   * by angle, but rather by order of arrival of the rays.  In these cases INREV
   * and ISNDX will be zero.
   */
  SINT2 inrev;                       /* Number of rays in one revolution. */
  SINT2 isndx;                       /* Implies angle of first pointer */
  SINT2 irtotl;                      /* Total number of rays */

  SINT2 ib_gparm;                    /* # bytes in each GPARM */
  SINT4 ialtitude;                   /* Altitude of radar (cm above sea level) */
  SINT4 inu_vel[3];

  /* The offset between the INU and the radar pedestal on moving
   * platform system.
   */
  SINT4 inu_offset[3];

  /* System fault status at the time the task was started
   */
  UINT4 iFaultBits ;
#define ICFB_BITE_FAULT      (0x00000001) /* Normal BITE fault */
#define ICFB_BITE_CRITICAL   (0x00000002) /* Critical BITE fault */
#define ICFB_RCP_FAULT       (0x00000004) /* Normal RCP fault */
#define ICFB_RCP_CRITICAL    (0x00000008) /* Critical RCP fault */
#define ICFB_SYS_CRITICAL    (0x00000010) /* Critical system fault */
#define ICFB_PRODUCT_FAULT   (0x00000020) /* Product generator faulted */
#define ICFB_OUTPUT_FAULT    (0x00000040) /* Output master faulted */
#define ICFB_SYS_FAULT       (0x00000080) /* Normal system fault */

  SINT2 iMeltingHeight;                /* Ref. melting height (m MSL), msb complemented, from setup */
  char ipad222x2[2] ;
  char sLocalTZName[8];                /* Null terminated local Timezone name */
  UINT4 iIcfFlags;
#define ICF_FLG_ANGLE_EDGE   (0x00000001) /* First ray not centered on zero */
#define ICF_DPOLAPP_CONFIG_NAME_SIZE (16)
  char sDpolappConfigName[ICF_DPOLAPP_CONFIG_NAME_SIZE]; /* Null terminated configuration name */

  char ipad_end[228] ;
};
typedef struct ingest_configuration ICF;

/* -------------------- Ingest Header --------------------
 *
 * Contents of the ingest header file.  Sometimes also called the ingest
 * summary file.
 */
#ifdef SIGMET_GPARM_DEFINED
#ifdef SIGMET_TASK_CONFIGURATION_DEFINED

#define STRUCT_INGEST_HEADER_DEFINED 1
#define SIGMET_INGEST_HEADER_DEFINED 1

#define INGEST_HEADER_SIZE ( STRUCT_HEADER_SIZE + \
    INGEST_CONFIGURATION_SIZE + TASK_CONFIG_SIZE + 732 + DSP_GPARM_SIZE + 920 )

struct ingest_header
{
  struct structure_header hdr;
  struct ingest_configuration icf;
  struct task_configuration tcf;
  char ipad_3104x732[732];

  struct gparm GParm;  /* Read from the RVP just after configuration */
  char ipad_end[920];
  
};
#endif  /* #ifdef SIGMET_TASK_CONFIGURATION_DEFINED 1 */
typedef struct ingest_header IHD;
#endif  /* #ifdef SIGMET_GPARM_DEFINED */

/* -------------------- Ingest Data File Header --------------------
 *
 * The Ingest data files consist of:
 *
 *   * The Following header
 *   * Array of IRTOTL int*4 pointers to the start of rays.  The pointers are
 *     origin one relative to the start of the ray area.  A pointer value of
 *     zero indicates that there is no ray for that pointer slot.
 *   * Array of IRTOTL (possibly variable length) /Data_Ray/ records.
 *
 * The pointer table is ordered according to the type of scan performed:
 *   PPI Sector      - From start to end AZ  \
 *   RHI Sector      - From start to end EL   >  See comments in ingest_configuration
 *   NEXSCAN         - From 0 degrees AZ     /        for INREV and ISNDX.
 *   FILE and MANUAL - In order that data were acquired
 */

#define INGEST_DATA_HEADER_SIZE (STRUCT_HEADER_SIZE + 64)

struct ingest_data_header {

  struct structure_header hdr ;

  struct ymds_time time ;	/* Date and time that sweep was started */
            
  SINT2 isweep ;		/* Sweep number, origin 1 */

/* The following three variables are copies of variables of the same name from
 * the ingest_configuration structure.  There are included here for convenience when
 * processing data files.
 */
  SINT2 inrev ;			/* Number of rays in one revolution. */
  SINT2 isndx ;			/* Implies angle of first pointer */
  SINT2 irtotl ;		/* Total number of rays */

/* IWRITN gives the number of rays actually written in this file, i.e., the
 * number of non-zero ray pointers.  It is possible that not all of the pointers
 * are actually filled in, e.g., if the antenna scan speed was too fast, some
 * angles might have been missed.
 */
  SINT2 iwritn ;		/* # rays written [0 - IRTOTL] */
  BIN2 iangle ;		        /* Fixed angle for this sweep */
  SINT2 ibits_bin ;		/* bits/bin for these data */
  UINT2 idata ;			/* Data code (See Task_DSP_Info.IDATA) */

  char ipad40x36[36] ;
} ;

#define STRUCT_INGEST_DATA_FILE_DEFINED 1
struct ingest_data_file
{
  struct ingest_data_header IDhdr;
  UINT4  iPointers[2];         /* Actual size varies */
  /* data follows */
};

/* -------------------- Ray Headers --------------------
 *
 * All radar rays are prefixed with the following short header.  The idea is
 * that this is sufficient for most products, and thus takes up the least amount
 * of space.  Products which require additional ray information must arrange to
 * have the "Extended Header" recorded along with the rest of the data.  Note
 * that even the "Extended Header" has this ray header attached.
 */
#define RAY_HSIZE (12)

struct ray_header {

/* Antenna positions at the start and end of the ray are stored as 16-bit binary
 * angles.
 */
  BIN2 iaz_start, iel_start ;	/* AZ and EL at start of ray */
  BIN2 iaz_end  , iel_end   ;	/* AZ and EL at end of ray */

  SINT2 ibincount ;		/* Actual number of bins */
  UINT2 itime ;			/* Time offset in seconds, unsigned */

} ;

/* -------------------- Extended Header Format --------------------
 *
 * The "Extended Header" type can be selected just like any other radar data
 * type, and has one of the following formats.  Note that AZ and EL are not
 * included in the Extended Header, because they are already in the ray header
 * that accompanies it.  The reason for supporting several formats is to allow
 * a hook for a potentially large amount of additional information per ray.
 *
 * Extended Header rays are unlike Radar Data rays in that there is no range
 * index on the information, i.e., there is just one set of words regardless
 * of the amount of other data being collected per ray.  As a consequence, the
 * size of the structure is known at compile time.
 */

/* --- Version 0 Extended Header ---
 */
#define EXT_RHED_V0_SIZE (20)
struct extended_header_v0 {

/* The exact time that the ray was acquired is stored to the nearest 
 * millisecond.  The time is relative to the sweep starting time given 
 * in the Ingest_Data_Header.
 */
  SINT4 itimems ;		/* Time ray was initiated */
  SINT2 icallevel ;		/* Calibration signal level */
  char ipad6x14[14] ;
} ;

/* --- Version 1 Extended Header ---
 */
#define EXT_RHED_V1_SIZE (54)
struct extended_header_v1 {

/* 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.  All heights are in meters; all
 * velocities are in cm/sec; all angles are binary angles, all angular
 * velocities are in binary angles/second.
 */

/* The exact time that the ray was acquired is stored to the nearest 
 * millisecond.  The time is relative to the sweep starting time given 
 * in the Ingest_Data_Header.
 */
  SINT4 itimems ;		/* Time ray was initiated */
  SINT2 icallevel ;		/* Calibration signal level */

  BIN2 iaz, iel ;
  BIN2 itrain, ielor ;
  BIN2 ipitch ;
  BIN2 iroll ;
  BIN2 iheading;

  BIN2 ivel_az ;
  BIN2 ivel_el ;
  BIN2 ivel_pitch ;
  BIN2 ivel_roll ;
         
  BIN4 ilatitude, ilongitude ;	/* Latitude and Longitude */
  BIN2 ivel_heading ;

  SINT2 ialtitude ;		/* Radar height (m above MSL) */
  SINT2 ivel_east ;		/* Radar Velocity East */
  SINT2 ivel_north ;		/* Radar Velocity North */
  SINT4 iupdate_age ;
  SINT2 ivel_up ;		/* Radar Velocity Up */

  UINT2 iflag ;
  SINT2 ivel_correction ;
} ;

/* --- Version 2 Extended Header ---
 */

#define EXT_RHED_V2_CUSTOM_MAX (1016)
#define EXT_RHED_V2_PREFIX_SIZE (8)
struct extended_header_v2 {

/* The exact time that the ray was acquired is stored to the nearest 
 * millisecond.  The time is relative to the sweep starting time given 
 * in the Ingest_Data_Header.
 */
  SINT4 itimems ;		/* Time ray was initiated */
  SINT2 icallevel ;		/* Calibration signal level */
  int16_t iSize ;               /* Bytes in this extended header */
  uint32_t iCustom[EXT_RHED_V2_CUSTOM_MAX/4] ;  /* Custom contents */
} ;

/*
 * -------------------- Generic Ray Format --------------------
 *
 * Data rays of all types are accessable through this structure.  "Data_Ray"
 * is one of the few structures whose length is not known at compile-time.  For
 * this reason the data references in the structure are dimensioned to the max-
 * imum size in order not to generate bounds check errors.  The structure should
 * never be used to allocate storage, but rather, should become rooted at the
 * first byte of a ray in order to get at the ray's components.  This rooting can
 * be done, e.g., by passing the ray's beginning address to a routine that
 * declares its formal parameter to be a Data_Ray record.
 *
 * All data types that are not simple byte or word arrays must first be given
 * a structure definition so that the data can be indexed by range.
 */

union ray_data
{
  /* Generic byte data array */
  UINT1 iData1[MAX_BINS];
  UINT2 iData2[MAX_BINS];
  /* extended header version 0 */
  struct extended_header_v0 xh0;
  /* Extended Header Version 1 */
  struct extended_header_v1 xh1;

  struct extended_header_v2 xh2;
};

/* Finally, the Data Ray structure itself...
 */
#define STRUCT_DATA_RAY_DEFINED 1
struct data_ray
{
  struct ray_header hdr;           /* Header goes on all data types */
  union  ray_data   data;
};

/* ============================================================
 * Each data parameter will have an area allocated to store its
 * Ingest_Data_Header, Ray Pointers, and Data.  The following
 * variables hold information about each parameter being
 * recorded.
 */
struct ingest_moment_info
{
  UINT2 idtypes;  /* Data type being recorded. */
  
  SINT2 isubr;    /* Subroutine to call to move this moment
		   * from DSP buffer to sweep buffer. */
#define SUBR_NOP              (0)        /* No Operation */
#define SUBR_MB_2_TO_1        (2)        /* Move Bytes 2 to 1 */
#define SUBR_XHDR             (4)        /* Generate Extended Header */
#define SUBR_NEGB_2_TO_1      (6)        /* Negate Bytes 2 to 1 */
#define SUBR_MW               (8)        /* Move Words */
#define SUBR_NEGW             (9)        /* Negate Words */
#define SUBR_DEFER8          (10)        /* Defered computation of  8-bit param */
#define SUBR_DEFER16         (11)        /* Defered computation of 16-bit param */

  UINT1 lApplyVelocityCorrection;        /* Apply velocity correction */
  UINT1 iPad5x3[3];
  
  SINT4 idalloc;	/* Max # bytes needed for data storage */
  SINT4 idused ;	/* # data bytes actually used */
  
  SINT4 iInRayOffset;	/* Offset from the start of the data to this moment in the
			 * DSP buffer (origin 0) */
  
  SINT4 iOutBufStart;	/* Address of start of storage areas in sweep buffer *
			 * for this moment (origin 0) */
  
  SINT4 ibits_bin; /* # bits/bin for this parameter. */
  
  /* As rays are acquired, IRAYST gives the starting sweep buffer
   * address for each parameter of the most recently inserted ray.
   */
  SINT4 irayst;
};

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