/* **********************************************************************
 * *                                                                    *
 * *                     Structures for INGEST                          *
 * *                                                                    *
 * ********************************************************************** 
 * File: include/ingest.h
 *
 *     COPYRIGHT (c) 1988, 1989, 1991, 1992, 1996, 1997, 1998, 1999,
 *                     2001, 2002, 2003, 2004  BY
 *         SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A. 
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED. 
 *
 * Include Requirements: sigtypes.h
 *                       headers.h
 *                       task.h
 */
#ifndef SIGMET_INGEST_H
#define SIGMET_INGEST_H 1

#ifdef __cplusplus
extern "C" {
#endif

/* -------------------- Device Status Structure --------------------
 *
 * Status of the various devices is recorded here.
 *
 * Structure for each individual test, i.e. each unit within any
 * catagory of Devices.
 */

struct one_device
{
  UINT4 istat;
#define DEV_NULL         (0)   /*NORMAL: Not applicable*/
#define DEV_OK           (1)   /*NORMAL: OK*/
#define DEV_CRITICAL     (2)   /*RED:    Critical fault has occured*/
  /* #define DEV_ERROR        (2) */
#define DEV_FAULT        (3)   /*YELLOW: Fault has occured*/
  /* #define DEV_ERROR_YELLOW (3) */
/* The following are only valid for network devices */
#define DEV_UNAVAIL      (5)   /*RED:    Remote computer unavailable*/
#define DEV_NOIRIS       (6)   /*RED:    Remote IRIS unavailable*/
         
  /* Node name or user name */
  /* For antenna device is either "N/A", Computer, IRIS, local, maintenance, or shutdown. */
  char sname[16];

  struct one_process_info OPI;  /* Only used for inputs for now */
};

/*
 * Structure for full summary of results
 * Lock DEVICE_SEM before checking/modifying this table.
 */

struct device_status
{
  struct one_device dsp;
  struct one_device output[MAX_OUT_DEVICES];

  struct one_device Inputs[MAX_INPUT_DEVICES];
  /* This array holds a flag for each output device.  It is used for the RGB
   * login workstations.  They check this table to see if a device is available
   * or not.
   */
  UINT4 ldevice_claimed[MAX_OUT_DEVICES];
  UINT2 lnetchild_claimed[MAX_NETWORK_LINKS];
};


struct server_one_device
{
  UINT4 istat;
         
  char sname[16];  /* Node name or user name, null terminated */

  UINT4 iMode;     /* Mode copied from process_info structure */
};

struct server_device_status
{
  struct server_one_device dsp;
  struct server_one_device antenna;
  SINT4 iOutputCount;
  struct server_one_device output[MAX_OUT_DEVICES];
  SINT4 iInputCount;
  struct server_one_device Inputs[MAX_INPUT_DEVICES];
};
typedef struct server_device_status SDEV_STAT;

/*
 * -------------------- 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 */
  char ipad118x6[6];
  char siris_version[8];             /* Null terminated */
  char sHardwareName[16];            /* Ingest hardware name */
  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];
  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.
   */
  UINT2 inrev;                       /* Number of rays in one revolution. */
  UINT2 isndx;                       /* Implies angle of first pointer */
  UINT2 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 */

  SINT2 iMeltingHeight;                /* Melting height (cm above MSL), msb complemented */
  char ipad222x2[2] ;
  char sLocalTZName[8];                /* Null terminated local Timezone name */
  char ipad232x248[248] ;
};
typedef struct ingest_configuration ICF;

/* -------------------- INGEST Header --------------------
 *
 * This structure is provided mainly as a means of collecting together the 
 * various structures and buffers that comprise it.  In general, the "working 
 * versions" of the headers's components will be elsewhere, but are 
 * copied here for I/O purposes.
 */
#ifdef SIGMET_DSP_H

#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 ihd;
  struct task_configuration tcf;
  char ipad_3104x732[732];

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

/* -------------------- 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] ;
} ;

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, and Extended Header Ray ---
 */
#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, and Extended Header Ray ---
 */
#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 ;
} ;

/*
 * -------------------- 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.
 */

/* Three byte time series, characteristic of PPP and RVP-5 */
struct  ppp_time_series 
{
  UINT1 iits;
  UINT1 iqts;
  UINT1 ilts;
  UINT1 izero;   /* (with one zero byte) */
};

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;
};

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


/* -------------------- INGEST Directory Summary --------------------
 * The following structure is used to keep track of INGEST 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 structure is a doubly-linked list of references to INGEST header files,
 * and also contains a small amount of information about the file and associated
 * data files.  The linked list permits adding and deleting files easily.  There
 * is sufficient information in the structure to decide when files are ready for
 * making products, when to delete files, etc.  The list is maintained in
 * order of increasing time.
 *
 * Structure defining one file entry
 */
struct one_ingest_file
{
  struct ymds_time VolumeYmds;          /* Time that volume scan was started */
  struct ymds_time file_time;           /* Time that file was last revised */

  SINT4 ibytes;                         /* # bytes for summary & data files */
  SINT4 ibytes_phantom;		        /* # bytes for phantom data files */
  struct dsp_data_mask DataMask;        /* Data parameters*/
  SINT4 ibin_last;                      /* Range of last bin */
  UINT4 isite_num;
  UINT4 inuse ;				/* Process usage bits */

  SINT2 idfnum;                         /* # of associated data files */
  SINT2 idfnum_phantom;			/* # of associated phantom data files */
  UINT2 iscan;                          /* Scan geometry*/
  SINT2 isweeps;                        /* Number of sweeps expected */
  SINT2 isweeps_done;                   /* Number of sweeps finished */
  SINT2 ihybrid_count;                  /* Number of tasks in the hybrid set */
  BIN2  iang_lst[MAX_SWEEPS];           /* List of angles */

  UINT2 iswp_starts[MAX_SWEEPS] ;       /* Offset times of starts of sweeps */
#define SWP_START_UNDEFINED (0xFFFF)    /* Code indicating undefined table entry */

  UINT2 iflags;
#define ISD_DONE      (0x0001)		/* Volume scan is complete */
#define ISD_DONE_P    (0x0001)
#define ISD_PARTIAL   (0x0002)		/* Volume scan was halted prematurely */
#define ISD_PARTIAL_P (0x0002)
#define ISD_DELETE    (0x0040)		/* File is tagged for delete */
#define ISD_DELE_P    (0x0040)
#define ISD_KEEP      (0x0080)		/* Do not remove file */
#define ISD_KEEP_P    (0x0080)
#define ISD_CLUTMAP   (0x0100)		/* File tagged as a clutter map */
#define ISD_CLUTMAP_P (0x0100)

  char stname[12];                      /* Task name */
  char ipad230x2[2] ;
};
/*
 * Ingest Inventory Structure itself.
 */
struct ingest_inventory
{
  SINT4 ifnum;                    /* Total number of all files (summary + data + phantom) */
  struct kilo_count TotalBytes;   /* Total size of all files (summary + data + phantom) */
  struct kilo_count KeepBytes;    /* Total size of kept files (summary + data + phantom) */

  UINT2 ldelete;                  /* non-zero if something has been marked for deletion */
  char  ipad14x2[2];

  struct linked_list_header lhdr;
  struct linked_list_item  llst[ MAX_INGEST_FILES ];

  struct one_ingest_file file[ MAX_INGEST_FILES ];
};


/* Ingest header summary structure used for communication with
 * the iris client interface.
 */

struct serv_ingest_header_summary
{
  SINT4 ibytes;
  char  stname[16];   /* Null terminated */
  UINT4 iscan;
  /*  UINT4 idata; */
  struct dsp_data_mask DataMask;
  SINT4 ibin_last;
  SINT4 isweeps;
  SINT4 isweeps_done;

  UINT4 iflags;
#define SISD_INUSE (0x00010000)		/* Server inuse summary flag */

  struct serv_ymds_time ing_time;
  UINT4 isite_num;
};
typedef struct serv_ingest_header_summary SIHD_SUM;


/* Flags to put in the ibytes field for requests */
#define FIND_EXACT (0x0001)  /*ISM FIND command needs exact match, otherwise 1 hour */

/* Ingest header long structure used for communication with
 * the iris client interface.  
 */
struct ingest_header_long
{
  char  stname[16];   /* Null terminated */
  struct dsp_data_mask DataMask;
  UINT4 iscan;
  SINT4 ibin_last;
  SINT4 isweeps;
  UINT4 iflags;
  struct serv_ymds_time VolumeYmds;
  UINT4 isite_num;
  BIN4  iangle_lst[MAX_SWEEPS]; /* Only valid for PPI, CON, RHI scans */
  /* SINT4 ibin_out_num; */             /* Number of output bins */
};

typedef struct ingest_header_long IHD_LNG;

  /* -------------------------- INGFIO Variables --------------------------
   *
   * The INGEST File I/O Process is woken by INGEST for the purpose of writing
   * data files to disk.  The following variables are passed to INGFIO to define
   * what needs to be done.  Note that the summary file is written by the INGEST
   * process itself.  These variables should only be altered by INGEST when the
   * INGFIO_W_ef_p event flag is set, indicating that INGFIO is not busy. */

struct ingfio_control
{
  /* The data are written to files one sweep at a time.  Each sweep will generally
   * hold several parameters.  All data are passed in a global section having the
   * following name.
   * */

  /* Name of global section holding the sweep data. */
  char sweep_glo_name[16];
  SINT2 isweep_glo_len; /*Length of name. */

  /* Indicates that this is the last sweep to be written for the task. */
  UINT2 sweep_last;

  /* Indicates that the volume scan has been halted prematurely */
  UINT2 lpartial ;

  char ipad22x2[2] ;

  /* Name of the summary file that owns the data files */
  char sing_sumfile_name[20];

  /* # params and their starting addresses (origin 1). */
  SINT4 ipnum, ipadrs[MAX_MOMENTS];

};

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