/**C*
 *
 * Vaisala software source code file
 *
 * Copyright (c) Vaisala Oyj 2001, 2002, 2006, 2007, 2009, 2010, 2013.
 * All rights reserved.
 *
 **C*/

/** @file
 *
 * NEXRAD format definition file
 *
 * $URL: https://subversion.vaisala.com/svn/repos/sigmet/wr_iris_rda/branches/release8.13.5/base/include/nexrad.h $
 *
 * $Id: nexrad.h 29326 2013-04-23 15:13:06Z jho $
 *
 */

/* This is the format used by NEXRAD.  It is sometimes called WSR88D level 2
 * format.  Also called archive 2 format.
 */

#define NR_NO_DATA   (0x00)
#define NR_OVERLAID  (0x01)
#define NR_MAX_PACKET_LENGTH (2432)
#define NR_MAX_RECORD_LENGTH (NR_MAX_PACKET_LENGTH*13)

/* Tape filename,        page 3-4 of 2620010  */
/* Volume Header Record, Figure 1, page 7-3 of 2620010B & C */
/* Volume Header Record, Figure 1, page 7-2 of 2620010D */
/* Volume Header Record, Figure 1, page 7-2 of 2620010E */
struct nr_volume_header
{
    char     sFileName[9];  
    /* Filename options:
     * "ARCHIVE2."  --  1998 build 10.0
     * "AR2V0001."  --  2005 build  7.0 Adds Radar ID
     */
    char     sFileExt[3];   /* Increments starting with "000", reset each time date changes */
    /* File creation date, in GMT */
    uint32_t iFileDate;    /* Number of days since 1/1/70, origin 1 */
    uint32_t iFileTime;    /* Number of milliseconds since midnight, origin 0 */
    char     sRadarId[4];
};

/* Message Header, Figure 2, page 7-6 of 2620010B & C */
/* Message Header, Table II, page 3-10 of 2620002D */
/* Message Header, Table II, page 3-11 of 2620002F */
/* Message Header, Table II, page 3-7 of 2620002H */
struct nr_message_header
{
    uint16_t  CTM[6];    /* Channel Terminal Manager (CTM) info not used */
  
    /* halfword 7 : message header information */
    uint16_t  iMsgSize;    /* # halfwords from here to end of record? */
    uint16_t  iChannelAndMsg;
#define NR_EXTRACT_MSG_TYPE(_BOTH) (0x00ff&(_BOTH))
#define NR_EXTRACT_CHANNEL(_BOTH) (0x00ff&((_BOTH)>>8))
#define NR_MERGE_CHANNEL_MSG(_CHANNEL,_MSG_TYPE) ((((uint16_t)(_CHANNEL))<<8)|(0x00ff&_MSG_TYPE))
    /* uint8_t  iRdaChannel; */ /* Channel number*/
    /* uint8_t  iMsgType; */   /* Digital Radar Data.  This message may contain
                                * a combination of either reflectivity,
                                * aliased velocity, or spectrum width.
                                */
/* Data Message Types, Table I, page 3-6 of 2620002D */
/* Data Message Types, Table I, page 3-7 of 2620002F */
/* Data Message Types, Table I, page 3-3 of 2620002H */
#define NR_MSG_TYPE_DIGITAL_RADAR         (1)
#define NR_MSG_TYPE_RDA_STATUS            (2)
#define NR_MSG_TYPE_PERFORMANCE           (3)
#define NR_MSG_TYPE_CONSOLE_MSG_TO_RPG    (4)
#define NR_MSG_TYPE_MAINTENANCE_LOG       (5)
#define NR_MSG_TYPE_RDA_CONTROL           (6)
#define NR_MSG_TYPE_VOLUME_COVERAGE       (7)
#define NR_MSG_TYPE_CLUTTER_SENSOR        (8)
#define NR_MSG_TYPE_REQUEST_DATA          (9)
#define NR_MSG_TYPE_CONSOLE_MSG_TO_RDA    (10)
#define NR_MSG_TYPE_LOOPBACK_TO_RPG       (11)
#define NR_MSG_TYPE_LOOPBACK_TO_RDA       (12)
#define NR_MSG_TYPE_CLUTTER_BYPASS        (13)
#define NR_MSG_TYPE_EDITED_CLUTTER        (14)
#define NR_MSG_TYPE_NOTCHWIDTH_MAP        (15)
#define NR_MSG_TYPE_RDA_ADAPTATION        (18)
#define NR_MSG_TYPE_DIGITAL_RADAR_GENERIC (31) /* Added in F */

    uint16_t  iIDSequence;    /* I.d. Seq = 0 to 7FFF, then roll over to 0 */
    /* This time is the same as ray time on an IRIS system. */
    uint16_t  iMsgDate;       /* modified Julian date from 1/1/70 */
    uint32_t  iMsgTime;       /* packet generation time in ms past midnite */
    uint16_t  iSegmentCount;  /* Origin 1, always set to 1 */
    uint16_t  iSegmentNumber; /* Origin 1, always set to 1 */
};

/* Digital Radar Data (Message Type 1), page 4-5  of 2620002A */
/* Digital Radar Data (Message Type 1), Table III, page 3-11 of 2620002D */
/* Digital Radar Data (Message Type 1), Table III, page 3-13 of 2620002F */
/* Digital Radar Data (Message Type 1), Table III, page 3-8 of 2620002H */
struct nr_radar_data_t1_header
{
    /* halfword 15 : data header information */
    uint32_t iDataTime;      /* collection time for this ray in ms, origin 0 */
    uint16_t iDataDate;      /* modified Julian date for this ray, origin 1 */
    uint16_t iUnambRange;    /* unambiguous range, in 1/10 of km, ignore possible range unfolding */
    BIN2     iAzimuth;       /* azimuth angle, binary angle */
    uint16_t iRayNumber;     /* ray no. within elevation scan, origin 1 */
    uint16_t iRayStatus;     /* ray status flag */
#define NR_RAY_STATUS_START_SWEEP  (0)
#define NR_RAY_STATUS_MIDDLE       (1)
#define NR_RAY_STATUS_END_SWEEP    (2)
#define NR_RAY_STATUS_START_VOLUME (3)
#define NR_RAY_STATUS_END_VOLUME   (4)
    BIN2     iElevation;     /* elevation angle, binary angle */
    uint16_t iSweepNumber;   /* elevation no. within volume scan, origin 1 */
  
    /* halfword 24 : gate/bin information*/
    int16_t  iBinStartRef;   /* range to first gate of refl data, meters */
    int16_t  iBinStartDop;   /* range to first gate of doppler data, meters */
    uint16_t iBinStepRef;    /* refl data gate size, meters */
    uint16_t iBinStepDop;    /* doppler data gate size, meters */
    uint16_t iBinNumberRef;  /* no. of reflectivity gates */
    uint16_t iBinNumberDop;  /* no. of doppler gates */
  
    /* halfword 30 */
    uint16_t iSectorNumber;  /* sector no. within cut, purpose unknown, set to 1 */
    float    fSystemCal;     /* gain calibration constant, set to 0 */
  
    /* halfword 33 : data parameters */
    uint16_t iRefPointer;    /* reflectivity data ptr */ 
    uint16_t iVelPointer;    /* velocity data ptr */
    uint16_t iWidPointer;    /* spectrum width ptr */
    uint16_t iVelocityRes;   /* Doppler velocity resolution (2=0.5m/s, 4=1.0m/s)*/
    uint16_t iVolumePattern; /* volume coverage pattern */
    uint16_t unused1[4];
  
    /* halfword 42 : data pointers for Archive II playback */
    uint16_t ref_ptrp;       /* These 3 words are unused, and set to zero */
    uint16_t vel_ptrp;
    uint16_t spc_ptrp;
  
    /* halfword 45 */
    uint16_t iNyquistVel;    /* Nyquist velocity in 1/100 of a m/s */
    int16_t  iAttenuation;   /* Negative of atmospheric attenuation in 1/1000 of a dB/km */
    uint16_t min_dif;        /* Unused, and set to zero */
  
    /* halfwords 48 to 64 */
    uint16_t unused2[17];    /* Set to zero */
  
};
/* RDA Adaptation Data, Table XV, page 3-55 of 2620002D */
/* RDA Adaptation Data, Table XV, page 3-60 of 2620002F */
/* RDA Adaptation Data, Table XV, page 3-52 of 2620002H */
struct nr_rda_adaptation
{
    char     ipad0x1092[644];
    float    fpath_losses[71];  /* (644)  Path loss array, unused */
    char     ipad928x164[164];
    uint32_t itfreq_mhz;        /* (1092) Transmitter frequency in MHz */
    char     ipad1096x36[36];
    float    fbeam_width;       /* (1132) Antenna beamwidth in degrees */
    char     ipad1136x152[152];
    float    fLatSec;           /* (1288) Latitude seconds */
    float    fLonSec;           /* (1292) Longitude seconds */
    char     ipad1296x4[4];
    uint32_t iLatDeg;           /* (1300) Latitude degrees */
    uint32_t iLatMin;           /* (1304) Latitude minutes */
    uint32_t iLonDeg;           /* (1308) Longitude degrees */
    uint32_t iLonMin;           /* (1312) Longitude minutes */
    char     sLatDir[4];        /* (1316) N or S */
    char     sLonDir[4];        /* (1320) E or W */
    char     ipad1324x7074[7064];
    int      ignd_hgt;          /* (8388) Ground height in meters */
    int      irad_hgt;          /* (8392) Radar height above ground in meters */
    char     ipad_8396x1072[1072];  /* overall size=9468 bytes */
};

/* Digital Radar Data (Message Type 31), Table XVII, page 3-85 of 2620002H */
struct nr_radar_data_t31_header
{
    /* halfword 15 : data header information */
    char     sIcaoRadarId[4];
    uint32_t iDataTime;       /* Collection time for this ray in ms, origin 0 */
    uint16_t iDataDate;       /* Modified Julian date for this ray, origin 1 */
    uint16_t iRayNumber;      /* Ray no. within elevation scan, origin 1 */
    float    fAzimuth;        /* Azimuth angle, degrees */
    uint16_t iCompressAndSpare; /* Compression indicator */
#define NR_DATA31_COMPRESSION_NONE   (0)
#define NR_DATA31_COMPRESSION_BZIP2  (1)
#define NR_DATA31_COMPRESSION_ZLIB   (2)
#define NR_DATA31_COMPRESSION_FUTURE (3)

    uint16_t iRayLength;     /* Uncompressed length of radial in bytes */
    uint16_t iAzimuthSpacing; /* Azimuthal spacing between rays */

    /* STRUCTURE NOT COMPLETE, WORK IN PROGRESS... */
};

/* Overall structure for a Nexrad packet.  For radar data these packets 
 * are always a fixed 2432 bytes long.
 */
struct nr_radar_packet
{
    struct nr_message_header       MessageHeader;
    struct nr_radar_data_t1_header DataHeader;
    uint8_t  iData[460+920+920];
    uint16_t CTM_end[2];    /* Channel Terminal Manager (CTM) info not used */
};

struct nr_generic_packet
{
    struct nr_message_header    MessageHeader;
    uint8_t  iData[2400];
    uint16_t CTM_end[2];    /* Channel Terminal Manager (CTM) info not used */
};

union nr_packet
{
    struct nr_message_header    MessageHeader;
    struct nr_radar_packet      RadarData;
    struct nr_generic_packet    Generic;
};

/* Structures below here used for nexrad level 3 data */

/* Message Header, page 3-37 of 2620001A */
struct l3_message_header2
{
    uint16_t iMessageCode;
    uint16_t iMsgDate;
    uint32_t iMsgTime;
    uint32_t iMsgLength;
    uint16_t iSourceID;
    uint16_t iDestID;
    uint16_t iNumberBlocks;
};

/* Product descriptor block, page 3-54 of 26200001A */
struct l3_product_description
{
    int16_t  iBlockDivider;
    int32_t  iLatitude;
    int32_t  iLongitude;
    int16_t  iHeight;
#define L3_REFLECTIVITY_1KM_8   (16)
#define L3_REFLECTIVITY_2KM_8   (17)
#define L3_REFLECTIVITY_4KM_8   (18)
#define L3_REFLECTIVITY_1KM_16  (19)
#define L3_REFLECTIVITY_2KM_16  (20)
#define L3_REFLECTIVITY_4KM_16  (21)
#define L3_VELOCITY_250M_8      (22)
#define L3_VELOCITY_500M_8      (23)
#define L3_VELOCITY_1KM_8       (24)
#define L3_VELOCITY_250M_16     (25)
#define L3_VELOCITY_500M_16     (26)
#define L3_VELOCITY_1KM_16      (27)
#define L3_WIDTH_250M_8         (28)
#define L3_WIDTH_500M_8         (29)
#define L3_WIDTH_1KM_8          (30)
    int16_t  iProductCode;      /* HW 16 */
    uint16_t iOperationalMode;
    uint16_t iVolumeCoverage;
    int16_t  iSequenceNumber;
    uint16_t iVolumeNumber;     /* HW 20 Volume scan number, range 1 - 80 cyclic */
    uint16_t iVolumeDate;
    uint32_t iVolumeTime;
    uint16_t iProductData;
    uint32_t iProductTime;      /* HW 25&26 */
    int16_t  iHW27;
    int16_t  iHW28;
    uint16_t iElevationNumber;  /* HW 29 Origin zero */
    int16_t  iElevationAngle;   /* HW 30 Angle in 1/10 of degrees */
    uint16_t iHW31;
    uint16_t iHW32;
    uint16_t iHW33;
    uint16_t iHW34;
    uint16_t iHW35;
    uint16_t iHW36;
    uint16_t iHW37;
    uint16_t iHW38;
    uint16_t iHW39;
    uint16_t iHW40;
    uint16_t iHW41;
    uint16_t iHW42;
    uint16_t iHW43;
    uint16_t iHW44;
    uint16_t iHW45;
    uint16_t iHW46;
    uint16_t iMaxDataValue;     /* HW 47 */
    uint16_t iMaxPosVel;        /* HW 48 */
    uint16_t iHW49;
    uint16_t iHW50;
    float    fCalConstant;      /* HW 51&52 */
    uint16_t iHW53;
};
