|
From: <rob...@us...> - 2010-07-08 02:05:49
|
Revision: 67
http://netcdftools.svn.sourceforge.net/netcdftools/?rev=67&view=rev
Author: robertbridle
Date: 2010-07-08 02:05:42 +0000 (Thu, 08 Jul 2010)
Log Message:
-----------
ANDSWRON-703 - Created a program to convert netCDF files (split by latitude) into csv files.
Added Paths:
-----------
trunk/launch/NetCDF2CSVConverter.launch
trunk/src/main/java/au/csiro/netcdf/wron/MdbsyNetCDF2CSVConverter.java
trunk/src/test/java/au/csiro/netcdf/wron/TestMdbsyNetCDF2CSVConverter.java
Added: trunk/launch/NetCDF2CSVConverter.launch
===================================================================
--- trunk/launch/NetCDF2CSVConverter.launch (rev 0)
+++ trunk/launch/NetCDF2CSVConverter.launch 2010-07-08 02:05:42 UTC (rev 67)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/netcdf-tools/src/main/java/au/csiro/netcdf/wron/MdbsyNetCDF2CSVConverter.java"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="1"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.maven.ide.eclipse.launchconfig.classpathProvider"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="au.csiro.netcdf.wron.MdbsyNetCDF2CSVConverter"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--inputDir "C:\test\netcdf\\" -outputDir "C:\test\csv\\""/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="netcdf-tools"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.maven.ide.eclipse.launchconfig.sourcepathProvider"/>
+</launchConfiguration>
Added: trunk/src/main/java/au/csiro/netcdf/wron/MdbsyNetCDF2CSVConverter.java
===================================================================
--- trunk/src/main/java/au/csiro/netcdf/wron/MdbsyNetCDF2CSVConverter.java (rev 0)
+++ trunk/src/main/java/au/csiro/netcdf/wron/MdbsyNetCDF2CSVConverter.java 2010-07-08 02:05:42 UTC (rev 67)
@@ -0,0 +1,693 @@
+package au.csiro.netcdf.wron;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.MissingOptionException;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.log4j.Logger;
+
+import ucar.ma2.Array;
+import ucar.ma2.InvalidRangeException;
+import ucar.nc2.NetcdfFile;
+import ucar.nc2.Variable;
+import ucar.nc2.units.DateFormatter;
+import au.csiro.netcdf.cli.CommandLineOptionsComparator;
+import au.csiro.netcdf.util.CSVTokenizer;
+import au.csiro.netcdf.util.Util;
+
+/**
+ * The class is a converter control class to convert Murray Darling Basin Sustainable Yields netCDF files into CSV
+ * files.
+ *
+ * Copyright 2010, CSIRO Australia
+ *
+ * @author Robert Bridle on 07/07/2010
+ * @version $Revision: {revision} $ $Date: 2008-10-31 11:24:49 +1100 (Fri, 31 Oct 2008) $
+ */
+public class MdbsyNetCDF2CSVConverter
+{
+ private static final String EPOC = "1895-01-01";
+
+ /**
+ * Constant that defines the logger to be used.
+ */
+ private static final Logger LOG = Logger
+ .getLogger(MdbsyNetCDF2CSVConverter.class.getName());
+
+ /**
+ * The latitude variable name used in the netCDF files.
+ */
+ private static final String LATITUDE_VARIABLE_NAME = "lat";
+
+ /**
+ * The longitude variable name used in the netCDF files.
+ */
+ private static final String LONGITUDE_VARIABLE_NAME = "long";
+
+ /**
+ * The time variable name used in the netCDF files.
+ */
+ private static final String TIME_VARIABLE_NAME = "time";
+
+ /**
+ * The number of milliseconds in a 24 hours.
+ */
+ private static final Long MILLISECONDS_IN_A_DAY = new Long("86400000"); // milliseconds in a day.
+
+ /**
+ * The date column text that is found in all csv files.
+ */
+ // private static final String DATE_COLUMN_TEXT = writeOutDateColumn();
+
+ /**
+ * The name of the command line option used for specifying the input directory containing the netCDF files.
+ */
+ public static final String INPUT_DIR = "inputDir";
+
+ /**
+ * The name of the command line option used for specifying the directory to create the csv files in.
+ */
+ public static final String OUTPUT_DIR = "outputDir";
+
+ /**
+ * The pattern for accepted file names where multiple files are accepted.
+ */
+ public static final String FILENAME_PATTERN = "pattern";
+
+ /**
+ * The column that the variable name is stored in the csv file.
+ */
+ private static final int VARIABLE_COLUMN = 0;
+
+ /**
+ * The only variables that we are interested in writing out to csv files are those that are in three dimensions
+ * (i.e. rank=3)
+ */
+ private static final int RANK_THREE = 3;
+
+ /**
+ * NetCDf file extension.
+ */
+ private static final Object CSV_FILE_EXTENSION = ".csv";
+
+ /**
+ * CSV file extension.
+ */
+ private static final Object NETCDF_FILE_EXTENSION = ".nc";
+
+ /**
+ * A string containing the date column text to be written out as the first column in all the csv files.
+ */
+ private static String DATE_COLUMN_TEXT = null;
+
+ /**
+ * @param args
+ */
+ @SuppressWarnings("static-access")
+ public static void main(String[] args) throws ParseException, IOException,
+ InvalidRangeException, java.text.ParseException
+ {
+ Options options = new Options();
+ try
+ {
+ Option inputDirectoryName = OptionBuilder
+ .withArgName("dir")
+ .hasArg()
+ .withDescription(
+ "1. the directory path containing the netCDF files to be converted.")
+ .isRequired(true).withLongOpt(INPUT_DIR).create("i");
+
+ Option outputDirectoryName = OptionBuilder
+ .withArgName("dir")
+ .hasArg()
+ .withDescription(
+ "2: the directory path to place the new csv files.")
+ .isRequired(true).withLongOpt(OUTPUT_DIR).create("o");
+
+ Option pattern = OptionBuilder
+ .withArgName("filename pattern")
+ .hasArg()
+ .withDescription(
+ "3: OPTIONAL, a pattern to match multiple existing files, where multiple files should be "
+ + "processed. If this option is present the outputFilename is expected to be a directory "
+ + "containing the files to be processed. The wildcard characters * and ? are supported but "
+ + "may need to be escaped by a \\ to avoid processing by the shell. e.g. \\*.nc ")
+ .isRequired(false).withLongOpt(FILENAME_PATTERN)
+ .create("p");
+
+ options.addOption(inputDirectoryName);
+ options.addOption(outputDirectoryName);
+ options.addOption(pattern);
+
+ // parse the command line arguments
+ CommandLine parsedCommandLine = new GnuParser()
+ .parse(options, args);
+
+ String inputDir = parsedCommandLine.getOptionValue(INPUT_DIR);
+ String outputDir = parsedCommandLine.getOptionValue(OUTPUT_DIR);
+
+ MdbsyNetCDF2CSVConverter converter = new MdbsyNetCDF2CSVConverter();
+
+ long start = System.currentTimeMillis();
+ converter.execute(inputDir, outputDir);
+ long end = System.currentTimeMillis() - start;
+ LOG.warn("Successfully converted all netcdf files to csv files in: " + end + " ms.");
+ }
+ catch (MissingOptionException moe)
+ {
+ LOG.error(moe.getMessage());
+
+ // generate the help/usage statement
+ String header = "Recreate ";
+ String footer = "\nExample: netcdf2csv -inputDirPath \"C:\\input\" -outputDirPath \"C:\\output\" \n"
+ + "Will convert the netCDF files in the input directory to csv file in the output directory.";
+ StringWriter sw = new StringWriter();
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.setOptionComparator(new CommandLineOptionsComparator());
+ formatter.printHelp(new PrintWriter(sw), 80, "-", header, options,
+ 0, 1, footer);
+ System.out.println(sw.toString());
+ }
+ }
+
+ /**
+ * Performs the conversion.
+ *
+ * @param inputDir
+ * the directory containing the Scenario A or C netCDF files.
+ * @param outputDir
+ * the directory in which the csv file will be placed.
+ * @throws InvalidRangeException
+ * thrown if an invalid range is attempted to be read from a netCDf variable.
+ * @throws IOException
+ */
+ public void execute(String inputDir, String outputDir) throws IOException,
+ InvalidRangeException
+ {
+ // perform an initial conversion from netCDF to csv, the csv file will look like this:
+ // Date, 1985-01-01, 1895-01-02, 1985-01-03, ...
+ // APET, 0.1, 0.3, 0.0, ....
+ // rainfall,0.0, 0.4, 0.1, ...
+ writeCSVFiles(inputDir, outputDir);
+
+ // transpose the csv files so the will look like this:
+ // Date, APET, rainfall
+ // 1895-01-01, 0.1, 0.0
+ // 1895-01-02, 0.3, 0.4
+ // 1895-01-03, 0.0, 0.1
+ transposeCSVFiles(outputDir);
+ }
+
+ /**
+ * For each netCDF file in the input directory:
+ * <p>
+ * Create a csv file for every latitude and longitude position.
+ * <p>
+ * Write out the value of a variable at every time interval, at a specific latitude and longitude position.
+ *
+ * @param inputDir
+ * the directory containing the Scenario A or C netCDF files.
+ * @param outputDir
+ * the directory in which the csv file will be placed.
+ * @throws InvalidRangeException
+ * thrown if an invalid range is attempted to be read from a netCDf variable.
+ * @throws IOException
+ */
+ private void writeCSVFiles(String inputDir, String outputDir)
+ throws IOException, InvalidRangeException
+ {
+ File dir = new File(inputDir);
+ File[] files = dir.listFiles();
+ if(files == null)
+ {
+ System.out.println("The input directory does not exist: " + inputDir);
+ LOG.error("The input directory does not exist: " + inputDir);
+ return;
+ }
+
+ for (int fileIndex = 0; fileIndex < files.length; fileIndex++)
+ {
+ if (files[fileIndex].isFile() && NETCDF_FILE_EXTENSION.equals(Util.getFileExtension(files[fileIndex].getName())))
+ {
+ NetcdfFile nc = null;
+ try
+ {
+ nc = NetcdfFile.open(files[fileIndex].getAbsolutePath());
+
+ Array latitudes = getLatitudeValues(nc);
+ Array longitudes = getLongitudeValues(nc);
+
+ LOG.info("latitude coordinate variable size: "
+ + latitudes.getSize());
+ LOG.info("longitude coordinate variable size: "
+ + longitudes.getSize());
+
+ for (int latIndex = 0; latIndex < latitudes.getSize(); latIndex++)
+ {
+ for (int longIndex = 0; longIndex < longitudes
+ .getSize(); longIndex++)
+ {
+ String fileName = createFileNameBasedOnLatLong(nc,
+ latIndex, longIndex);
+ String filePath = outputDir
+ + System.getProperty("file.separator")
+ + fileName + ".csv";
+
+ // if the csv file already exists, then append the next variable.
+ if (Util.fileExists(filePath))
+ {
+ File file = new File(filePath);
+ PrintWriter out = new PrintWriter(
+ new BufferedWriter(new FileWriter(file,
+ true /* append mode */)));
+
+ List<String> variablesAlreadyWrittenOut = getVariablesAlreadyWrittenOut(file);
+ List<String> variablesThatCanBeWrittenOut = getVariablesThatCanBeWrittenOut(nc);
+
+ variablesThatCanBeWrittenOut
+ .removeAll(variablesAlreadyWrittenOut);
+
+ try
+ {
+ writeOutVariable(nc, out,
+ variablesThatCanBeWrittenOut,
+ latIndex, longIndex);
+ }
+ finally
+ {
+ if (out != null)
+ out.close();
+ }
+ }
+ else
+ // if the csv file does not exist, create a new csv file and write all available variables.
+ {
+ PrintWriter out = new PrintWriter(new BufferedWriter(
+ new FileWriter(new File(filePath),
+ false /* append mode */)));
+
+ List<String> variablesThatCanBeWrittenOut = getVariablesThatCanBeWrittenOut(nc);
+
+ try
+ {
+ out.println(writeOutDateColumn(nc));
+
+ writeOutVariable(nc, out,
+ variablesThatCanBeWrittenOut,
+ latIndex, longIndex);
+ }
+ finally
+ {
+ if (out != null)
+ out.close();
+ }
+ }
+ }
+ }
+ }
+ catch (java.io.FileNotFoundException fnfe)
+ {
+ System.out.println("file not found= " + files[fileIndex]);
+ LOG.error(fnfe);
+ }
+ finally
+ {
+ if (nc != null)
+ nc.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * Writes out the value of a variable at every time interval, at a specific latitude and longitude position.
+ *
+ * @throws InvalidRangeException
+ * @throws IOException
+ *
+ */
+ private void writeOutVariable(NetcdfFile nc, PrintWriter out,
+ List<String> variablesThatCanBeWrittenOut, int latIndex,
+ int longIndex) throws IOException, InvalidRangeException
+ {
+ for (String variableName : variablesThatCanBeWrittenOut)
+ {
+ Array subsection = getVariableAcrossTime(nc, variableName,
+ latIndex, longIndex);
+ out.println(variableName + ","
+ + subsection.toString().replaceAll(" ", ","));
+ }
+ }
+
+ /**
+ * Transpose the csv files so that columns represent a variable's value over time.
+ *
+ * @param outputDir
+ * the directory in which the csv file will be placed.
+ * @throws IOException
+ */
+ private void transposeCSVFiles(String outputDir) throws IOException
+ {
+ File dir = new File(outputDir);
+ File[] files = dir.listFiles();
+ if(files == null)
+ {
+ System.out.println("The output directory does not exist: " + outputDir);
+ LOG.error("The output directory does not exist: " + outputDir);
+ return;
+ }
+
+ for (int fileIndex = 0; fileIndex < files.length; fileIndex++)
+ {
+ if (files[fileIndex].isFile() && CSV_FILE_EXTENSION.equals(Util.getFileExtension(files[fileIndex].getName())))
+ {
+ String[][] matrix = readLookupFile(files[fileIndex]);
+
+ // write over-the-top of the csv file.
+ PrintWriter out = new PrintWriter(
+ new BufferedWriter(new FileWriter(files[fileIndex],
+ false /* append mode */)));
+
+ // transpose String[][] matrix and write back out to csv
+ String[][] transposed = transpose(matrix);
+
+ try
+ {
+ for (int row = 0; row < transposed.length; row++)
+ {
+ for (int col = 0; col < transposed[0].length; col++)
+ {
+ out.print(transposed[row][col]);
+ if(col < (transposed[0].length-1))
+ {
+ out.print(", ");
+ }
+ }
+ out.println();
+ }
+ }
+ finally
+ {
+ if (out != null)
+ out.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the names of the variables in the netCDF file that we need to write out for a given latitude x longitude
+ * position.
+ *
+ * @param nc
+ * a netCDF file {@link NetcdfFile}
+ * @return the names of the variables in the netCDF file that we need to write out for a given latitude x longitude
+ * position.
+ */
+ private List<String> getVariablesThatCanBeWrittenOut(NetcdfFile nc)
+ {
+ List<String> variablesThatCanBeWrittenOut = new ArrayList<String>();
+
+ for (Variable variable : nc.getVariables())
+ {
+ if (variable.getRank() == RANK_THREE)
+ {
+ variablesThatCanBeWrittenOut.add(variable.getName().trim());
+ }
+ }
+
+ return variablesThatCanBeWrittenOut;
+ }
+
+ /**
+ * Returns the name of the variables that have already be written out to a csv file.
+ *
+ * @param file
+ * the csv file being written out too.
+ * @return the name of the variables that have already be written out to a csv file.
+ * @throws IOException
+ */
+ private List<String> getVariablesAlreadyWrittenOut(File file)
+ throws IOException
+ {
+ List<String> variablesAlreadyWrittenOut = new ArrayList<String>();
+
+ String[][] matrix = readLookupFile(file);
+ for (int rows = 0; rows < matrix.length; rows++)
+ {
+ variablesAlreadyWrittenOut.add(matrix[rows][VARIABLE_COLUMN].trim());
+ }
+
+ return variablesAlreadyWrittenOut;
+ }
+
+ /**
+ * Creates a file name based on a given latitude and longitude.
+ *
+ * @param nc
+ * a netCDF file {@link NetcdfFile}
+ * @param latIndex
+ * the latitude index.
+ * @param longIndex
+ * the longitude index.
+ * @return a file name based on latitude and longitude position.
+ * @throws InvalidRangeException
+ * @throws IOException
+ */
+ private String createFileNameBasedOnLatLong(NetcdfFile nc, int latIndex,
+ int longIndex) throws IOException, InvalidRangeException
+ {
+ return "region_"
+ + nc.readSection("lat(" + latIndex + ":" + latIndex + ")")
+ .toString().trim()
+ + "_"
+ + nc.readSection("long(" + longIndex + ":" + longIndex + ")")
+ .toString().trim();
+ }
+
+ /**
+ * Parses a csv file into an row-by-column string matrix.
+ *
+ * @param file
+ * a csv file.
+ * @return row-by-column string matrix of the csv file.
+ * @throws IOException
+ */
+ public static String[][] readLookupFile(File file) throws IOException
+ {
+ RandomAccessFile raf = new RandomAccessFile(file, "r");
+ List<String[]> lineList = new ArrayList<String[]>();
+
+ try
+ {
+ String line = raf.readLine();
+ while (line != null)
+ {
+ String[] cols = new CSVTokenizer(line).getAllColumns();
+ lineList.add(cols);
+ line = raf.readLine();
+ }
+ }
+ finally
+ {
+ raf.close();
+ }
+
+ String[][] lineCols = lineList.toArray(new String[][] {});
+ return lineCols;
+ }
+
+ /**
+ * Transpose a matrix, e.g. [a][b] -> [b][a]
+ *
+ * @param values a String[][] matrix.
+ */
+ private String[][] transpose(String[][] values)
+ {
+ if(values.length == 0)
+ {
+ return new String[0][0];
+ }
+
+ String[][] transposed = new String[values[0].length][values.length];
+ for (int row = 0; row < values.length; row++)
+ {
+ for (int col = 0; col < values[0].length; col++)
+ {
+ transposed[col][row] = values[row][col];
+ }
+ }
+ return transposed;
+ }
+
+ /**
+ * Returns the value of a variable at every time interval, at a specific latitude and longitude position.
+ *
+ * @param nc
+ * a netCDF file {@link NetcdfFile}
+ * @param variableName
+ * the variable whose values are to be read.
+ * @param latIndex
+ * the latitude index.
+ * @param longIndex
+ * the longitude index.
+ * @return the value of a variable at every time interval, at a specific latitude and longitude position.
+ * @throws IOException
+ * @throws InvalidRangeException
+ */
+ private Array getVariableAcrossTime(NetcdfFile nc, String variableName,
+ int latIndex, int longIndex) throws IOException,
+ InvalidRangeException
+ {
+ try
+ {
+ return nc.readSection(variableName + "(" + latIndex + ":"
+ + latIndex + "," + longIndex + ":" + longIndex + ",:)");
+ }
+ catch (InvalidRangeException ire)
+ {
+ ire.printStackTrace();
+ LOG.error("Could not read section: " + variableName + "("
+ + latIndex + ":" + latIndex + "," + longIndex + ":"
+ + longIndex + ",:)", ire);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the longitude coordinate variable values.
+ *
+ * @param nc
+ * a netCDF file {@link NetcdfFile}
+ * @return the longitude coordinate variable values.
+ * @throws IOException
+ * @throws IllegalArgumentException
+ */
+ private Array getLongitudeValues(NetcdfFile nc) throws IOException,
+ IllegalArgumentException
+ {
+ for (Variable v : nc.getVariables())
+ {
+ if (v.isCoordinateVariable()
+ && LONGITUDE_VARIABLE_NAME.equals(v.getName()))
+ {
+ return v.read();
+ }
+ }
+ LOG.error("Could not find coordinate variable: "
+ + LONGITUDE_VARIABLE_NAME);
+ throw new IllegalStateException("Could not find coordinate variable: "
+ + LONGITUDE_VARIABLE_NAME);
+ }
+
+ /**
+ * Returns the latitude coordinate variable values.
+ *
+ * @param nc
+ * a netCDF file {@link NetcdfFile}
+ * @return the latitude coordinate variable values.
+ * @throws IOException
+ * @throws IllegalArgumentException
+ */
+ private Array getLatitudeValues(NetcdfFile nc) throws IOException,
+ IllegalArgumentException
+ {
+ for (Variable v : nc.getVariables())
+ {
+ if (v.isCoordinateVariable()
+ && LATITUDE_VARIABLE_NAME.equals(v.getName()))
+ {
+ return v.read();
+ }
+ }
+ LOG.error("Could not find coordinate variable: "
+ + LATITUDE_VARIABLE_NAME);
+ throw new IllegalStateException("Could not find coordinate variable: "
+ + LATITUDE_VARIABLE_NAME);
+ }
+
+ /**
+ * Returns the time variable.
+ *
+ * @param nc
+ * a netCDF file {@link NetcdfFile}
+ * @return the time variable.
+ * @throws IllegalArgumentException
+ */
+ private static Variable getTimeVariable(NetcdfFile nc)
+ throws IllegalArgumentException
+ {
+ for (Variable v : nc.getVariables())
+ {
+ if (v.isCoordinateVariable()
+ && TIME_VARIABLE_NAME.equals(v.getName()))
+ {
+ return v;
+ }
+ }
+ LOG.error("Could not find coordinate variable: " + TIME_VARIABLE_NAME);
+ throw new IllegalStateException("Could not find coordinate variable: "
+ + TIME_VARIABLE_NAME);
+ }
+
+ /**
+ * Converts a "days since" time coordinate variable into a list of formatted dates.
+ *
+ * @param nc
+ * a netCDF file {@link NetcdfFile}
+ * @return a list of formatted dates.
+ */
+ private static String writeOutDateColumn(NetcdfFile nc)
+ {
+ // we only need to create the date column text once, it is the same for all csv files.
+ if (DATE_COLUMN_TEXT == null)
+ {
+ StringBuffer strBuf = new StringBuffer();
+
+ DateFormatter dateFormatter = new DateFormatter();
+ Date epoc;
+ try
+ {
+ epoc = dateFormatter.dateOnlyFormat(EPOC);
+ strBuf.append("Date,");
+
+ long timeVariableSize = getTimeVariable(nc).getSize();
+ for (int i = 0; i < timeVariableSize; i++)
+ {
+ strBuf.append(dateFormatter.toDateOnlyString(new Date(epoc
+ .getTime()
+ + (i * MILLISECONDS_IN_A_DAY))).trim());
+
+ if(i < (timeVariableSize-1))
+ {
+ strBuf.append(",");
+ }
+ }
+
+ DATE_COLUMN_TEXT = strBuf.toString();
+ }
+ catch (java.text.ParseException pe)
+ {
+ pe.printStackTrace();
+ LOG.error("Error parsing date", pe);
+ }
+
+ }
+ return DATE_COLUMN_TEXT;
+ }
+}
Added: trunk/src/test/java/au/csiro/netcdf/wron/TestMdbsyNetCDF2CSVConverter.java
===================================================================
--- trunk/src/test/java/au/csiro/netcdf/wron/TestMdbsyNetCDF2CSVConverter.java (rev 0)
+++ trunk/src/test/java/au/csiro/netcdf/wron/TestMdbsyNetCDF2CSVConverter.java 2010-07-08 02:05:42 UTC (rev 67)
@@ -0,0 +1,227 @@
+package au.csiro.netcdf.wron;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+
+import au.csiro.netcdf.NcWriteVariable;
+import au.csiro.netcdf.util.Util;
+
+import ucar.ma2.DataType;
+import ucar.nc2.Dimension;
+import ucar.nc2.NCdumpW;
+import ucar.nc2.NetcdfFile;
+import ucar.nc2.NetcdfFileWriteable;
+import ucar.nc2.Variable;
+import junit.framework.TestCase;
+
+/**
+ * This class is a unit test suite to verify that the {@link MdbsyNetCDF2CSVConverter} operates correctly.
+ *
+ * Copyright 2010, CSIRO Australia
+ *
+ * @author Robert Bridle on 08/07/2010
+ * @version $Revision: {revision} $ $Date: 2008-10-31 11:24:49 +1100 (Fri, 31 Oct 2008) $
+ */
+public class TestMdbsyNetCDF2CSVConverter extends TestCase
+{
+ /**
+ * The testing value for the latitude coordinate dimension.
+ */
+ private static final String DIM_LATITUDE = "lat";
+ private static final String VAR_LATITUDE = DIM_LATITUDE;
+ private static final String VAR_LATITUDE_VALUE = "-24.25";
+
+ /**
+ * The testing value for the longitude coordinate dimension.
+ */
+ private static final String DIM_LONGITUDE = "long";
+ private static final String VAR_LONGITUDE = DIM_LONGITUDE;
+ private static final String VAR_LONGITUDE_VALUE = "138.10";
+
+ /**
+ * The expected name of the converted csv file.
+ */
+ private static final String CONVERTED_CSV_FILE_NAME = System.getProperty("user.dir") + "\\region_-24.25_138.1.csv";
+
+ /**
+ * The testing value for the time coordinate dimension.
+ */
+ private static final String DIM_TIME = "time";
+ private static final String VAR_TIME = DIM_TIME;
+ private static final String VAR_TIME_VALUES = "0" + System.getProperty("line.separator") + "1"
+ + System.getProperty("line.separator") + "2" + System.getProperty("line.separator") + "3"
+ + System.getProperty("line.separator") + "4" + System.getProperty("line.separator") + "5"
+ + System.getProperty("line.separator") + "6" + System.getProperty("line.separator") + "7"
+ + System.getProperty("line.separator") + "8" + System.getProperty("line.separator") + "9";
+
+ /**
+ * The testing value for a variable defined over three coordinate dimensions (lat, long, time).
+ */
+ private static final String VAR_APET = "APET";
+ private static final String VAR_APET_VALUES = "0.000" + System.getProperty("line.separator") + "0.111"
+ + System.getProperty("line.separator") + "0.222" + System.getProperty("line.separator") + "0.333"
+ + System.getProperty("line.separator") + "0.444" + System.getProperty("line.separator") + "0.555"
+ + System.getProperty("line.separator") + "0.666" + System.getProperty("line.separator") + "0.777"
+ + System.getProperty("line.separator") + "0.888" + System.getProperty("line.separator") + "0.999";
+
+
+ /**
+ * The expected output converted csv structure.
+ */
+ private static String[] EXPECTED_CSV_FILE = { "Date, APET",
+ "1895-01-01, 0.0",
+ "1895-01-02, 0.111",
+ "1895-01-03, 0.222",
+ "1895-01-04, 0.333",
+ "1895-01-05, 0.444",
+ "1895-01-06, 0.555",
+ "1895-01-07, 0.666",
+ "1895-01-08, 0.777",
+ "1895-01-09, 0.888",
+ "1895-01-10, 0.999" };
+
+ /**
+ * The testing value for the dimension sizes.
+ */
+ private static final int LAT_DIM_SIZE = 1;
+ private static final int LONG_DIM_SIZE = 1;
+ private static final int TIME_DIM_SIZE = 10;
+
+ /**
+ * The testing value for the netCDF file to write to.
+ */
+ private static final String NC_FILE_NAME = System.getProperty("user.dir") + "\\ABC.nc";
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ // create dummy netCDF file with content.
+ createDummyNCFile(NC_FILE_NAME);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see junit.framework.TestCase#tearDown()
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ System.setOut(null);
+
+ // delete dummy netCDF file
+ File ncFile = new File(NC_FILE_NAME);
+ if (ncFile.exists())
+ {
+ NetcdfFile netcdfFile = NetcdfFile.open(NC_FILE_NAME);
+ netcdfFile.close();
+ ncFile.delete();
+ }
+
+ // delete converted csv file
+ File csvFile = new File(CONVERTED_CSV_FILE_NAME);
+ if (csvFile.exists())
+ {
+ csvFile.delete();
+ }
+ }
+
+ /**
+ * Test execute a valid NcWriteVariable command using Double datatype
+ */
+ public final void testNetCDF2CSVConversion() throws Exception
+ {
+ MdbsyNetCDF2CSVConverter.main(new String[] { "-i", System.getProperty("user.dir"), "-o",
+ System.getProperty("user.dir") });
+
+ // check that the converted csv file was created.
+ assertTrue("The expected converted csv file does not exist: " + CONVERTED_CSV_FILE_NAME, Util
+ .fileExists(CONVERTED_CSV_FILE_NAME));
+
+ String[][] csvMatrix = MdbsyNetCDF2CSVConverter.readLookupFile(new File(CONVERTED_CSV_FILE_NAME));
+
+ for (int row = 0; row < csvMatrix.length; row++)
+ {
+ StringBuffer line = new StringBuffer();
+ for (int col = 0; col < csvMatrix[0].length; col++)
+ {
+ line.append(csvMatrix[row][col]);
+ if(col < (csvMatrix[0].length-1))
+ {
+ line.append(", ");
+ }
+ }
+
+ assertEquals("The expected csv output is not correct.", EXPECTED_CSV_FILE[row], line.toString());
+ }
+ }
+
+ /**
+ * Makes a dummy netCDF file with known contents.
+ */
+ private void createDummyNCFile(String outputFilename) throws IOException
+ {
+ NetcdfFileWriteable ncFile = null;
+
+ ncFile = NetcdfFileWriteable.createNew(outputFilename, true);
+ try
+ {
+ Dimension dimension = new Dimension(DIM_LATITUDE, LAT_DIM_SIZE, true /* isShared */,
+ false /* isUnlimited */, false /* isVariableLength */);
+ ncFile.addDimension(null, dimension);
+
+ dimension = new Dimension(DIM_LONGITUDE, LONG_DIM_SIZE, true /* isShared */, false /* isUnlimited */, false /* isVariableLength */);
+ ncFile.addDimension(null, dimension);
+
+ dimension = new Dimension(DIM_TIME, TIME_DIM_SIZE, true /* isShared */, false /* isUnlimited */, false /* isVariableLength */);
+ ncFile.addDimension(null, dimension);
+
+ // define coordinate variables.
+ ncFile.addVariable(VAR_LATITUDE, DataType.FLOAT, DIM_LATITUDE);
+ ncFile.addVariable(VAR_LONGITUDE, DataType.FLOAT, DIM_LONGITUDE);
+ ncFile.addVariable(VAR_TIME, DataType.INT, DIM_TIME);
+
+ // variable is defined over three coordinates dimensions.
+ ncFile.addVariable(VAR_APET, DataType.FLOAT, DIM_LATITUDE + " " + DIM_LONGITUDE + " " + DIM_TIME);
+ ncFile.create();
+ }
+ finally
+ {
+ ncFile.close();
+ }
+
+ // populate the coordinate variables with string of int values.
+ NcWriteVariable command = new NcWriteVariable();
+ command.execute(new File(outputFilename), VAR_LATITUDE, "0-" + String.valueOf(LAT_DIM_SIZE - 1),
+ new ByteArrayInputStream(VAR_LATITUDE_VALUE.getBytes("UTF-8")), false);
+ command.execute(new File(outputFilename), VAR_LONGITUDE, "0-" + String.valueOf(LONG_DIM_SIZE - 1),
+ new ByteArrayInputStream(VAR_LONGITUDE_VALUE.getBytes("UTF-8")), false);
+ command.execute(new File(outputFilename), VAR_TIME, "0-" + String.valueOf(TIME_DIM_SIZE - 1),
+ new ByteArrayInputStream(VAR_TIME_VALUES.getBytes("UTF-8")), false);
+
+ try
+ {
+ command.execute(new File(outputFilename), VAR_APET, "0-" + String.valueOf(LAT_DIM_SIZE - 1) + ", 0-"
+ + String.valueOf(LONG_DIM_SIZE - 1) + ", 0-" + String.valueOf(TIME_DIM_SIZE - 1),
+ new ByteArrayInputStream(VAR_APET_VALUES.getBytes("UTF-8")), false);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ iae.printStackTrace();
+ fail("could not create file: " + outputFilename + " to being testing of netCDF 2 CSV converter");
+ }
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|