ucar.nc2.iosp.mcidas.McIDASGridReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netcdf Show documentation
Show all versions of netcdf Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
/*
*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package ucar.nc2.iosp.mcidas;
import edu.wisc.ssec.mcidas.*;
import ucar.grid.GridIndex;
import ucar.nc2.iosp.grid.*;
import ucar.unidata.io.RandomAccessFile;
import java.io.IOException;
import java.util.*;
/**
* Read grid(s) from a McIDAS grid file
*/
public class McIDASGridReader {
/** The file */
protected RandomAccessFile rf;
/** An error message */
private String errorMessage;
/** Grid index */
private GridIndex gridIndex;
/** swap flag */
protected boolean needToSwap = false;
/** hashMap of GridDefRecords */
private HashMap gdsMap = new HashMap();
/** maximum number of grids in a file */
// is this the right number?
private static final int MAX_GRIDS = 999999;
/**
* Bean ctor
*/
public McIDASGridReader() {}
/**
* Create a McIDASGrid Reader from the file
*
* @param filename filename
*
* @throws IOException problem reading file
*/
public McIDASGridReader(String filename) throws IOException {
this(new RandomAccessFile(filename, "r", 2048));
}
/**
* Create a McIDASGrid Reader from the file
*
* @param raf RandomAccessFile
*
* @throws IOException problem reading file
*/
public McIDASGridReader(RandomAccessFile raf) throws IOException {
init(raf);
}
/**
* Initialize the file, read in all the metadata (ala DM_OPEN)
*
* @param raf RandomAccessFile to read.
*
* @throws IOException problem reading file
*/
public final void init(RandomAccessFile raf) throws IOException {
init(raf, true);
}
/**
* Initialize the file, read in all the metadata (ala DM_OPEN)
*
* @param fullCheck for a full check reading grids
* @param raf RandomAccessFile to read.
*
* @throws IOException problem reading file
*/
public final void init(RandomAccessFile raf, boolean fullCheck)
throws IOException {
rf = raf;
raf.order(RandomAccessFile.BIG_ENDIAN);
boolean ok = init(fullCheck);
if ( !ok) {
throw new IOException("Unable to open McIDAS Grid file: "
+ errorMessage);
}
}
/**
* Initialize this reader. Get the Grid specific info
*
* @return true if successful
*
* @throws IOException problem reading the data
*/
protected boolean init() throws IOException {
return init(true);
}
/**
* 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 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;
}
/**
* Swap the grid header, avoiding strings
*
* @param gh grid header to swap
*/
private void swapGridHeader(int[] gh) {
McIDASUtil.flip(gh, 0, 5);
McIDASUtil.flip(gh, 7, 7);
McIDASUtil.flip(gh, 9, 10);
McIDASUtil.flip(gh, 12, 14);
McIDASUtil.flip(gh, 32, 51);
}
/**
* Read the grid
*
* @param gr the grid record
*
* @return the data
*/
public float[] readGrid(McIDASGridRecord gr) {
float[] data = null;
try {
int te = (gr.getOffsetToHeader() + 64) * 4;
int rows = gr.getRows();
int cols = gr.getColumns();
rf.seek(te);
float scale = (float) gr.getParamScale();
data = new float[rows * cols];
rf.order(needToSwap
? rf.LITTLE_ENDIAN
: rf.BIG_ENDIAN);
int n = 0;
// store such that 0,0 is in lower left corner...
for (int nc = 0; nc < cols; nc++) {
for (int nr = 0; nr < rows; nr++) {
int temp = rf.readInt(); // check for missing value
data[(rows - nr - 1) * cols + nc] = (temp
== McIDASUtil.MCMISSING)
? Float.NaN
: ((float) temp) / scale;
}
}
rf.order(rf.BIG_ENDIAN);
} catch (Exception esc) {
System.out.println(esc);
}
return data;
}
/**
* to get the grid header corresponding to the last grid read
*
* @return McIDASGridDirectory of the last grid read
*/
public GridIndex getGridIndex() {
return gridIndex;
}
/**
* Read an integer
* @param word word in file (0 based) to read
*
* @return int read
*
* @throws IOException problem reading file
*/
public int readInt(int word) throws IOException {
if (rf == null) {
throw new IOException("no file to read from");
}
rf.seek(word * 4);
// set the order
if (needToSwap) {
rf.order(RandomAccessFile.LITTLE_ENDIAN); // swap
} else {
rf.order(RandomAccessFile.BIG_ENDIAN);
}
int idata = rf.readInt();
rf.order(RandomAccessFile.BIG_ENDIAN);
return idata;
}
/**
* Log an error
*
* @param errMsg message to log
*/
private void logError(String errMsg) {
errorMessage = errMsg;
}
/**
* for testing purposes
*
* @param args file name
*
* @throws IOException problem reading file
*/
public static void main(String[] args) throws IOException {
String file = "GRID2001";
if (args.length > 0) {
file = args[0];
}
McIDASGridReader mg = new McIDASGridReader(file);
GridIndex gridIndex = mg.getGridIndex();
List grids = gridIndex.getGridRecords();
System.out.println("found " + grids.size() + " grids");
int num = Math.min(grids.size(), 10);
for (int i = 0; i < num; i++) {
System.out.println(grids.get(i));
}
}
}