cdm/src/main/java/ucar/nc2/iosp/nids/Nidsheader.java
Pinfo read_proddesc(  ByteBuffer buf, int offset ){
        byte[] b2 = new byte[2];
        byte[] b4 = new byte[4];
        int off = offset;
        Short tShort;
        Integer tInt;
        //Double tDouble = null;

        /* thredds global att */
        ncfile.addAttribute(null, new Attribute("title", "Nexrad Level 3 Data"));
        ncfile.addAttribute(null, new Attribute("keywords", "WSR-88D; NIDS"));
        ncfile.addAttribute(null, new Attribute("creator_name", "NOAA/NWS"));
        ncfile.addAttribute(null, new Attribute("creator_url", "http://www.ncdc.noaa.gov/oa/radar/radarproducts.html"));
        ncfile.addAttribute(null, new Attribute("naming_authority", "NOAA/NCDC"));


        //      ncfile.addAttribute(null, new Attribute("keywords_vocabulary", cname));
        //out.println( "offset of buffer is " + off);
        buf.position(offset);
        buf.get(b2, 0, 2);
        tShort = (Short)convert(b2, DataType.SHORT, -1);
        divider  =  tShort.shortValue();
        ncfile.addAttribute(null, new Attribute("Divider", tShort));

        buf.get(b4, 0, 4);
        tInt = (Integer)convert(b4, DataType.INT, -1);
        latitude = tInt.intValue()/ 1000.0;
        buf.get(b4, 0, 4);
        tInt = (Integer)convert(b4, DataType.INT, -1);
        longitude = tInt.intValue()/ 1000.0;
        buf.get(b2, 0, 2);
        height = getInt(b2, 2)*0.3048; // LOOK now in units of meters


        if (useStationDB) { // override by station table for more accuracy
        try {
          NexradStationDB.init(); // make sure database is initialized
          NexradStationDB.Station station = NexradStationDB.get("K"+stationId);
          if (station != null) {
            latitude = station.lat;
            longitude = station.lon;
            height = station.elev;
            stationName = station.name;
          }
        } catch (IOException ioe) {
          log.error("NexradStationDB.init "+raf.getLocation(), ioe);
        }
        }

        ncfile.addAttribute(null, new Attribute("RadarLatitude", new Double(latitude)));
        ncfile.addAttribute(null, new Attribute("RadarLongitude", new Double(longitude)));
        ncfile.addAttribute(null, new Attribute("RadarAltitude", new Double(height)));

        buf.get(b2, 0, 2);
        pcode = (short)getInt(b2, 2);
        if (stationId != null) ncfile.addAttribute(null, new Attribute("ProductStation", stationId));
        if (stationName != null) ncfile.addAttribute(null, new Attribute("ProductStationName", stationName));
        buf.get(b2, 0, 2);
        opmode = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("OperationalMode", new Short(opmode)));
        buf.get(b2, 0, 2);
        volumnScanPattern = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("VolumeCoveragePatternName", new Short(volumnScanPattern)));
        buf.get(b2, 0, 2);
        sequenceNumber = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("SequenceNumber", new Short(sequenceNumber)));
        buf.get(b2, 0, 2);
        volumeScanNumber = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("VolumeScanNumber", new Short(volumeScanNumber)));
        buf.get(b2, 0, 2);
        volumeScanDate = (short)getUInt(b2, 2);
        buf.get(b4, 0, 4);
        volumeScanTime = getUInt(b4, 4);
        buf.get(b2, 0, 2);
        productDate = (short)getUInt(b2, 2);
        buf.get(b4, 0, 4);
        productTime = getUInt(b4, 4);
        java.util.Date pDate = getDate( productDate, productTime*1000);
        String dstring = formatter.toDateTimeStringISO(pDate);
        ncfile.addAttribute(null, new Attribute("DateCreated", dstring));
        buf.get(b2, 0, 2);
        p1 = (short)getInt(b2, 2);
        buf.get(b2, 0, 2);
        p2 = (short)getInt(b2, 2);
        buf.get(b2, 0, 2);
        elevationNumber = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("ElevationNumber",new Short(elevationNumber)));
        buf.get(b2, 0, 2);
        p3 = (short)getInt(b2, 2);
        off += 40;
        if(pcode == 182 || pcode == 186 || pcode == 32
                || pcode == 94 || pcode == 99) {
          for(int i = 0; i< 16; i++) {
            buf.get(b2, 0, 2);
            threshold[i] = (short)bytesToInt(b2[0], b2[1], false);
          }
        } else if(pcode == 159 || pcode == 161 || pcode == 163
                || pcode == 170 || pcode == 172 || pcode == 173
                || pcode == 174 || pcode == 175 ) {
            // Scale hw 31 32
            buf.get(b4, 0, 4);
            byte[] b44 = {b4[3], b4[2], b4[1], b4[0]};
            threshold[0] = (short)(java.nio.ByteBuffer.wrap(b44).order(java.nio.ByteOrder.LITTLE_ENDIAN).getFloat()*100);
            // offset  hw 33 34
            buf.get(b4, 0, 4);
            byte[] b45 = {b4[3], b4[2], b4[1], b4[0]};
            threshold[1] = (short)(java.nio.ByteBuffer.wrap(b45).order(java.nio.ByteOrder.LITTLE_ENDIAN).getFloat()*100);
            //  hw 35 reserve
            buf.get(b2, 0, 2);
            threshold[2] = 0;
            // hw 36, 37, 38
            for(int i = 3; i< 6; i++) {
                buf.get(b2, 0, 2);
                threshold[i] = (short)bytesToInt(b2[0], b2[1], false);
            }
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
        } else if(pcode == 176) {
            // Scale hw 31 32
            buf.get(b4, 0, 4);
            byte[] b44 = {b4[3], b4[2], b4[1], b4[0]};
            threshold[0] = (short)(java.nio.ByteBuffer.wrap(b44).order(java.nio.ByteOrder.LITTLE_ENDIAN).getFloat());
            // offset  hw 33 34
            buf.get(b4, 0, 4);
            byte[] b45 = {b4[3], b4[2], b4[1], b4[0]};
            threshold[1] = (short)(java.nio.ByteBuffer.wrap(b45).order(java.nio.ByteOrder.LITTLE_ENDIAN).getFloat());
            //  hw 35 reserve
            buf.get(b2, 0, 2);
            threshold[2] = 0;
            // hw 36, 37, 38
            for(int i = 3; i< 6; i++) {
                buf.get(b2, 0, 2);
                threshold[i] = (short)bytesToInt(b2[0], b2[1], false);
            }
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
        }
        else {
          for(int i = 0; i< 16; i++) {
            buf.get(b2, 0, 2);
            threshold[i] = (short)getInt(b2, 2);
          }
        }
        off += 32;
        buf.get(b2, 0, 2);
        p4 = (short)getInt(b2, 2);
        //int t1 = getUInt(b2, 2);
        buf.get(b2, 0, 2);
        p5 = (short)getInt(b2, 2);
        //t1 = getUInt(b2, 2);
        buf.get(b2, 0, 2);
        p6 = (short)getInt(b2, 2);
        //t1 = getUInt(b2, 2);
        buf.get(b2, 0, 2);
        p7 = (short)getInt(b2, 2);
        buf.get(b2, 0, 2);
        p8 = (short)getInt(b2, 2);
        buf.get(b2, 0, 2);
        p9 = (short)getInt(b2, 2);
        buf.get(b2, 0, 2);
        p10 = (short)getUInt(b2, 2) ; //bytesToInt(b2[0], b2[1], true); //       getInt(b2, 2); //
        off += 14;

        buf.get(b2, 0, 2);
        numberOfMaps = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("NumberOfMaps",new Short(numberOfMaps)));
        off += 2;
        buf.get(b4, 0, 4);
        //tInt = (Integer)convert(b4, DataType.INT, -1);
        offsetToSymbologyBlock = getInt(b4, 4);
        //ncfile.addAttribute(null, new Attribute("offset_symbology_block",new Integer(offsetToSymbologyBlock)));
        off += 4;
        buf.get(b4, 0, 4);
        //tInt = (Integer)convert(b4, DataType.INT, -1);
        offsetToGraphicBlock = getInt(b4, 4);
        //ncfile.addAttribute(null, new Attribute("offset_graphic_block",new Integer(offsetToGraphicBlock)));
        off += 4;
        buf.get(b4, 0, 4);
        //tInt = (Integer)convert(b4, DataType.INT, -1);
        offsetToTabularBlock = getInt(b4, 4);
        //ncfile.addAttribute(null, new Attribute("offset_tabular_block",new Integer(offsetToTabularBlock)));
        off += 4;

        return  new Pinfo (divider, latitude, longitude, height, pcode, opmode, threshold,
                           sequenceNumber, volumeScanNumber, volumeScanDate, volumeScanTime,
                            productDate, productTime, p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,
                            elevationNumber, numberOfMaps, offsetToSymbologyBlock,
                            offsetToGraphicBlock, offsetToTabularBlock);

        //return pinfo;

    }
Pinfo read_proddesc(  ByteBuffer buf, int offset ){
        byte[] b2 = new byte[2];
        byte[] b4 = new byte[4];
        int off = offset;
        Short tShort;
        Integer tInt;
        //Double tDouble = null;

        /* thredds global att */
        ncfile.addAttribute(null, new Attribute("title", "Nexrad Level 3 Data"));
        ncfile.addAttribute(null, new Attribute("keywords", "WSR-88D; NIDS"));
        ncfile.addAttribute(null, new Attribute("creator_name", "NOAA/NWS"));
        ncfile.addAttribute(null, new Attribute("creator_url", "http://www.ncdc.noaa.gov/oa/radar/radarproducts.html"));
        ncfile.addAttribute(null, new Attribute("naming_authority", "NOAA/NCDC"));


        //      ncfile.addAttribute(null, new Attribute("keywords_vocabulary", cname));
        //out.println( "offset of buffer is " + off);
        buf.position(offset);
        buf.get(b2, 0, 2);
        tShort = (Short)convert(b2, DataType.SHORT, -1);
        divider  =  tShort.shortValue();
        ncfile.addAttribute(null, new Attribute("Divider", tShort));

        buf.get(b4, 0, 4);
        tInt = (Integer)convert(b4, DataType.INT, -1);
        latitude = tInt.intValue()/ 1000.0;
        buf.get(b4, 0, 4);
        tInt = (Integer)convert(b4, DataType.INT, -1);
        longitude = tInt.intValue()/ 1000.0;
        buf.get(b2, 0, 2);
        height = getInt(b2, 2)*0.3048; // LOOK now in units of meters


        if (useStationDB) { // override by station table for more accuracy
        try {
          NexradStationDB.init(); // make sure database is initialized
          NexradStationDB.Station station = NexradStationDB.get("K"+stationId);
          if (station != null) {
            latitude = station.lat;
            longitude = station.lon;
            height = station.elev;
            stationName = station.name;
          }
        } catch (IOException ioe) {
          log.error("NexradStationDB.init "+raf.getLocation(), ioe);
        }
        }

        ncfile.addAttribute(null, new Attribute("RadarLatitude", new Double(latitude)));
        ncfile.addAttribute(null, new Attribute("RadarLongitude", new Double(longitude)));
        ncfile.addAttribute(null, new Attribute("RadarAltitude", new Double(height)));

        buf.get(b2, 0, 2);
        pcode = (short)getInt(b2, 2);
        if (stationId != null) ncfile.addAttribute(null, new Attribute("ProductStation", stationId));
        if (stationName != null) ncfile.addAttribute(null, new Attribute("ProductStationName", stationName));
        buf.get(b2, 0, 2);
        opmode = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("OperationalMode", new Short(opmode)));
        buf.get(b2, 0, 2);
        volumnScanPattern = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("VolumeCoveragePatternName", new Short(volumnScanPattern)));
        buf.get(b2, 0, 2);
        sequenceNumber = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("SequenceNumber", new Short(sequenceNumber)));
        buf.get(b2, 0, 2);
        volumeScanNumber = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("VolumeScanNumber", new Short(volumeScanNumber)));
        buf.get(b2, 0, 2);
        volumeScanDate = (short)getUInt(b2, 2);
        buf.get(b4, 0, 4);
        volumeScanTime = getUInt(b4, 4);
        buf.get(b2, 0, 2);
        productDate = (short)getUInt(b2, 2);
        buf.get(b4, 0, 4);
        productTime = getUInt(b4, 4);
        java.util.Date pDate = getDate( productDate, productTime*1000);
        String dstring = formatter.toDateTimeStringISO(pDate);
        ncfile.addAttribute(null, new Attribute("DateCreated", dstring));
        buf.get(b2, 0, 2);
        p1 = (short)getInt(b2, 2);
        buf.get(b2, 0, 2);
        p2 = (short)getInt(b2, 2);
        buf.get(b2, 0, 2);
        elevationNumber = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("ElevationNumber",new Short(elevationNumber)));
        buf.get(b2, 0, 2);
        p3 = (short)getInt(b2, 2);
        off += 40;
        if(pcode == 182 || pcode == 186 || pcode == 32
                || pcode == 94 || pcode == 99) {
          for(int i = 0; i< 16; i++) {
            buf.get(b2, 0, 2);
            threshold[i] = (short)bytesToInt(b2[0], b2[1], false);
          }
        } else if(pcode == 159 || pcode == 161 || pcode == 163
                || pcode == 170 || pcode == 172 || pcode == 173
                || pcode == 174 || pcode == 175 ) {
            // Scale hw 31 32
            buf.get(b4, 0, 4);
            byte[] b44 = {b4[3], b4[2], b4[1], b4[0]};
            threshold[0] = (short)(java.nio.ByteBuffer.wrap(b44).order(java.nio.ByteOrder.LITTLE_ENDIAN).getFloat()*100);
            // offset  hw 33 34
            buf.get(b4, 0, 4);
            byte[] b45 = {b4[3], b4[2], b4[1], b4[0]};
            threshold[1] = (short)(java.nio.ByteBuffer.wrap(b45).order(java.nio.ByteOrder.LITTLE_ENDIAN).getFloat()*100);
            //  hw 35 reserve
            buf.get(b2, 0, 2);
            threshold[2] = 0;
            // hw 36, 37, 38
            for(int i = 3; i< 6; i++) {
                buf.get(b2, 0, 2);
                threshold[i] = (short)bytesToInt(b2[0], b2[1], false);
            }
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
        } else if(pcode == 176) {
            // Scale hw 31 32
            buf.get(b4, 0, 4);
            byte[] b44 = {b4[3], b4[2], b4[1], b4[0]};
            threshold[0] = (short)(java.nio.ByteBuffer.wrap(b44).order(java.nio.ByteOrder.LITTLE_ENDIAN).getFloat());
            // offset  hw 33 34
            buf.get(b4, 0, 4);
            byte[] b45 = {b4[3], b4[2], b4[1], b4[0]};
            threshold[1] = (short)(java.nio.ByteBuffer.wrap(b45).order(java.nio.ByteOrder.LITTLE_ENDIAN).getFloat());
            //  hw 35 reserve
            buf.get(b2, 0, 2);
            threshold[2] = 0;
            // hw 36, 37, 38
            for(int i = 3; i< 6; i++) {
                buf.get(b2, 0, 2);
                threshold[i] = (short)bytesToInt(b2[0], b2[1], false);
            }
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
            buf.get(b4, 0, 4);
        }
        else {
          for(int i = 0; i< 16; i++) {
            buf.get(b2, 0, 2);
            threshold[i] = (short)getInt(b2, 2);
          }
        }
        off += 32;
        buf.get(b2, 0, 2);
        p4 = (short)getInt(b2, 2);
        //int t1 = getUInt(b2, 2);
        buf.get(b2, 0, 2);
        p5 = (short)getInt(b2, 2);
        //t1 = getUInt(b2, 2);
        buf.get(b2, 0, 2);
        p6 = (short)getInt(b2, 2);
        //t1 = getUInt(b2, 2);
        buf.get(b2, 0, 2);
        p7 = (short)getInt(b2, 2);
        buf.get(b2, 0, 2);
        p8 = (short)getInt(b2, 2);
        buf.get(b2, 0, 2);
        p9 = (short)getInt(b2, 2);
        buf.get(b2, 0, 2);
        p10 = (short)getUInt(b2, 2) ; //bytesToInt(b2[0], b2[1], true); //       getInt(b2, 2); //
        off += 14;

        buf.get(b2, 0, 2);
        numberOfMaps = (short)getInt(b2, 2);
        ncfile.addAttribute(null, new Attribute("NumberOfMaps",new Short(numberOfMaps)));
        off += 2;
        buf.get(b4, 0, 4);
        //tInt = (Integer)convert(b4, DataType.INT, -1);
        offsetToSymbologyBlock = getInt(b4, 4);
        //ncfile.addAttribute(null, new Attribute("offset_symbology_block",new Integer(offsetToSymbologyBlock)));
        off += 4;
        buf.get(b4, 0, 4);
        //tInt = (Integer)convert(b4, DataType.INT, -1);
        offsetToGraphicBlock = getInt(b4, 4);
        //ncfile.addAttribute(null, new Attribute("offset_graphic_block",new Integer(offsetToGraphicBlock)));
        off += 4;
        buf.get(b4, 0, 4);
        //tInt = (Integer)convert(b4, DataType.INT, -1);
        offsetToTabularBlock = getInt(b4, 4);
        //ncfile.addAttribute(null, new Attribute("offset_tabular_block",new Integer(offsetToTabularBlock)));
        off += 4;

        return  new Pinfo (divider, latitude, longitude, height, pcode, opmode, threshold,
                           sequenceNumber, volumeScanNumber, volumeScanDate, volumeScanTime,
                            productDate, productTime, p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,
                            elevationNumber, numberOfMaps, offsetToSymbologyBlock,
                            offsetToGraphicBlock, offsetToTabularBlock);

        //return pinfo;

    }
/*
* Name:       read_proddesc
*
* Purpose:    Read product description header from NEXRAD Level III product
*
*