/** Read StationName strings */
 public java.util.Map<String, String> readStnNames(ucar.unidata.io.RandomAccessFile raf) {
   java.util.Map<String, String> hdrNames = new java.util.HashMap<String, String>();
   try {
     raf.seek(6288);
     String stnName = raf.readString(16); // System.out.println(" stnName="+stnName.trim());
     raf.seek(6306);
     String stnName_util = raf.readString(16);
     hdrNames.put("StationName", stnName.trim());
     hdrNames.put("StationName_SetupUtility", stnName_util.trim());
   } catch (Exception e) {
     System.out.println(e.toString());
     e.printStackTrace();
   }
   return hdrNames;
 }
  Level2VolumeScan(RandomAccessFile orgRaf, CancelTask cancelTask) throws IOException {
    this.raf = orgRaf;

    if (log.isDebugEnabled()) log.debug("Level2VolumeScan on " + raf.getLocation());

    raf.seek(0);
    raf.order(RandomAccessFile.BIG_ENDIAN);

    // volume scan header
    dataFormat = raf.readString(8);
    raf.skipBytes(1);
    String volumeNo = raf.readString(3);
    title_julianDay = raf.readInt(); // since 1/1/70
    title_msecs = raf.readInt();
    stationId = raf.readString(4).trim(); // only in AR2V0001
    if (log.isDebugEnabled()) log.debug(" dataFormat= " + dataFormat + " stationId= " + stationId);

    if (stationId.length() == 0) {
      // try to get it from the filename LOOK

      stationId = null;
    }

    // try to find the station
    if (stationId != null) {
      if (!stationId.startsWith("K") && stationId.length() == 4) {
        String _stationId = "K" + stationId;
        station = NexradStationDB.get(_stationId);
      } else station = NexradStationDB.get(stationId);
    }

    // see if we have to uncompress
    if (dataFormat.equals(AR2V0001)
        || dataFormat.equals(AR2V0003)
        || dataFormat.equals(AR2V0004)
        || dataFormat.equals(AR2V0006)) {
      raf.skipBytes(4);
      String BZ = raf.readString(2);
      if (BZ.equals("BZ")) {
        RandomAccessFile uraf;
        File uncompressedFile = DiskCache.getFileStandardPolicy(raf.getLocation() + ".uncompress");

        if (uncompressedFile.exists() && uncompressedFile.length() > 0) {
          // see if its locked - another thread is writing it
          FileInputStream fstream = null;
          FileLock lock = null;
          try {
            fstream = new FileInputStream(uncompressedFile);
            // lock = fstream.getChannel().lock(0, 1, true); // wait till its unlocked

            while (true) { // loop waiting for the lock
              try {
                lock = fstream.getChannel().lock(0, 1, true); // wait till its unlocked
                break;

              } catch (OverlappingFileLockException oe) { // not sure why lock() doesnt block
                try {
                  Thread.sleep(100); // msecs
                } catch (InterruptedException e1) {
                  break;
                }
              }
            }

          } finally {
            if (lock != null) lock.release();
            if (fstream != null) fstream.close();
          }
          uraf = new ucar.unidata.io.RandomAccessFile(uncompressedFile.getPath(), "r");

        } else {
          // nope, gotta uncompress it
          uraf = uncompress(raf, uncompressedFile.getPath());
          if (log.isDebugEnabled())
            log.debug("made uncompressed file= " + uncompressedFile.getPath());
        }

        // switch to uncompressed file
        raf.close();
        raf = uraf;
        raf.order(RandomAccessFile.BIG_ENDIAN);
      }

      raf.seek(Level2Record.FILE_HEADER_SIZE);
    }

    List<Level2Record> reflectivity = new ArrayList<Level2Record>();
    List<Level2Record> doppler = new ArrayList<Level2Record>();
    List<Level2Record> highReflectivity = new ArrayList<Level2Record>();
    List<Level2Record> highVelocity = new ArrayList<Level2Record>();
    List<Level2Record> highSpectrum = new ArrayList<Level2Record>();
    List<Level2Record> highDiffReflectivity = new ArrayList<Level2Record>();
    List<Level2Record> highDiffPhase = new ArrayList<Level2Record>();
    List<Level2Record> highCorreCoefficient = new ArrayList<Level2Record>();

    long message_offset31 = 0;
    int recno = 0;
    while (true) {

      Level2Record r = Level2Record.factory(raf, recno++, message_offset31);
      if (r == null) break;
      if (showData) r.dump2(System.out);
      // skip non-data messages
      if (r.message_type == 31) {
        message_offset31 = message_offset31 + (r.message_size * 2 + 12 - 2432);
      }

      if (r.message_type != 1 && r.message_type != 31) {
        if (showMessages) r.dumpMessage(System.out);
        continue;
      }

      //  if (showData) r.dump2(System.out);

      /* skip bad
      if (!r.checkOk()) {
        r.dump(System.out);
        continue;
      }   */

      // some global params
      if (vcp == 0) vcp = r.vcp;
      if (first == null) first = r;
      last = r;

      if (runCheck && !r.checkOk()) {
        continue;
      }

      if (r.hasReflectData) reflectivity.add(r);
      if (r.hasDopplerData) doppler.add(r);

      if (r.message_type == 31) {
        if (r.hasHighResREFData) highReflectivity.add(r);
        if (r.hasHighResVELData) highVelocity.add(r);
        if (r.hasHighResSWData) highSpectrum.add(r);
        if (r.hasHighResZDRData) highDiffReflectivity.add(r);
        if (r.hasHighResPHIData) highDiffPhase.add(r);
        if (r.hasHighResRHOData) highCorreCoefficient.add(r);
      }

      if ((cancelTask != null) && cancelTask.isCancel()) return;
    }
    if (debugRadials)
      System.out.println(" reflect ok= " + reflectivity.size() + " doppler ok= " + doppler.size());
    if (highReflectivity.size() == 0) {
      reflectivityGroups = sortScans("reflect", reflectivity, 600);
      dopplerGroups = sortScans("doppler", doppler, 600);
    }
    if (highReflectivity.size() > 0)
      reflectivityHighResGroups = sortScans("reflect_HR", highReflectivity, 720);
    if (highVelocity.size() > 0)
      velocityHighResGroups = sortScans("velocity_HR", highVelocity, 720);
    if (highSpectrum.size() > 0)
      spectrumHighResGroups = sortScans("spectrum_HR", highSpectrum, 720);
    if (highDiffReflectivity.size() > 0)
      diffReflectHighResGroups = sortScans("diffReflect_HR", highDiffReflectivity, 720);
    if (highDiffPhase.size() > 0)
      diffPhaseHighResGroups = sortScans("diffPhase_HR", highDiffPhase, 720);
    if (highCorreCoefficient.size() > 0)
      coefficientHighResGroups = sortScans("coefficient_HR", highCorreCoefficient, 720);
  }
  /**
   * Initialize this reader. Get the Grid specific info
   *
   * @param fullCheck for a full check reading grids
   * @return true if successful
   * @throws IOException problem reading the data
   */
  protected boolean init(boolean fullCheck) throws IOException {
    if (rf == null) {
      logError("File is null");
      return false;
    }
    gridIndex = new GridIndex(rf.getLocation());

    rf.order(RandomAccessFile.BIG_ENDIAN);
    int numEntries = Math.abs(readInt(10));
    if (numEntries > 1000000) {
      needToSwap = true;
      numEntries = Math.abs(McIDASUtil.swbyt4(numEntries));
    }
    if (numEntries > MAX_GRIDS) {
      return false;
    }
    // System.out.println("need to Swap = " + needToSwap);
    // System.out.println("number entries="+numEntries);

    // go back to the beginning
    rf.seek(0);
    // read the fileheader
    String label = rf.readString(32);
    // GEMPAK too closely like McIDAS
    if (label.indexOf("GEMPAK DATA MANAGEMENT FILE") >= 0) {
      logError("label indicates this is a GEMPAK grid");
      return false;
    } else { // check that they are all printable ASCII chars
      for (int i = 0; i < label.length(); i++) {
        String s0 = label.substring(i, i + 1);
        if (!(0 <= s0.compareTo(" ") && s0.compareTo("~") <= 0)) {
          logError("bad label, not a McIDAS grid");
          return false;
        }
      }
    }

    // System.out.println("label = " + label);

    int project = readInt(8);
    // System.out.println("Project = " + project);

    int date = readInt(9);
    // dates are supposed to be yyyddd, but account for ccyyddd up to year 4000
    if ((date < 10000) || (date > 400000)) {
      logError("date wrong, not a McIDAS grid");
      return false;
    }
    // System.out.println("date = " + date);

    int[] entries = new int[numEntries];
    for (int i = 0; i < numEntries; i++) {
      entries[i] = readInt(i + 11);
      // sanity check that this is indeed a McIDAS Grid file
      if (entries[i] < -1) {
        logError("bad grid offset " + i + ": " + entries[i]);
        return false;
      }
    }
    if (!fullCheck) {
      return true;
    }

    // Don't swap:
    rf.order(RandomAccessFile.BIG_ENDIAN);
    for (int i = 0; i < numEntries; i++) {
      if (entries[i] == -1) {
        continue;
      }
      int[] header = new int[64];
      rf.seek(entries[i] * 4);
      rf.readInt(header, 0, 64);
      if (needToSwap) {
        swapGridHeader(header);
      }
      try {

        McIDASGridRecord gr = new McIDASGridRecord(entries[i], header);
        // if (gr.getGridDefRecordId().equals("CONF X:93 Y:65")) {
        // if (gr.getGridDefRecordId().equals("CONF X:54 Y:47")) {
        // figure out how to handle Mercator projections
        // if ( !(gr.getGridDefRecordId().startsWith("MERC"))) {
        gridIndex.addGridRecord(gr);
        if (gdsMap.get(gr.getGridDefRecordId()) == null) {
          McGridDefRecord mcdef = gr.getGridDefRecord();
          // System.out.println("new nav " + mcdef.toString());
          gdsMap.put(mcdef.toString(), mcdef);
          gridIndex.addHorizCoordSys(mcdef);
        }
        // }
      } catch (McIDASException me) {
        logError("problem creating grid dir");
        return false;
      }
    }
    // check to see if there are any grids that we can handle
    if (gridIndex.getGridRecords().isEmpty()) {
      logError("no grids found");
      return false;
    }
    return true;
  }