Example usage for java.lang Float isNaN

List of usage examples for java.lang Float isNaN

Introduction

In this page you can find the example usage for java.lang Float isNaN.

Prototype

public static boolean isNaN(float v) 

Source Link

Document

Returns true if the specified number is a Not-a-Number (NaN) value, false otherwise.

Usage

From source file:gov.noaa.pfel.coastwatch.Projects.java

/**
 * Processes one CalCOFI2012 tsv file into a .nc file.
 * //from  w w  w.  j  a  v a2 s  .c  o  m
 * <p>The var sequence of latitude, latitudeMinutes, latitudeLocation
 * will be converted to 1 latitude column (decimal degrees).
 * Similar with longitude.
 *
 * <p>If units are yyMM, var will be converted to yyyyMM and units="".
 *
 * <p>If units are yyMMdd, var will be converted to yyyyMMdd, then
 * to "seconds since 1970-01-01T00:00:00Z" (assuming Pacific time zone) 
 * and sets attribute: time_precision=1970-01-01.
 *
 * <p>If units of variable after yyMMdd are HHmm, the date and time will
 * be combined into one "seconds since 1970-01-01T00:00:00Z" variable.
 *
 * <p>If variableName="timeZone", this checks to see if arriveDate value 
 * timeZone offset is as expected.
 *
 * @param dir
 * @param tableName  e.g., CC_TOWS
 * @param info  with 4 strings (name, type, units, long_name) for each variable 
 * @param towTypesDescription will be added as description=[towTypesDescrption]
 *   when variableName=towTypeCode.
 * @return the table, as saved in the .nc file.
 */
public static Table processOneCalcofi2012(String dir, String tableName, String info[],
        String towTypesDescription) throws Exception {

    String rowName = "row";
    int cutoffYear = 20; // fourDigitYear += twoDigitYear < cutoffYear? 2000 : 1900;

    /*  make tsv into ERDDAP-style .json table
    //{
    //  "table": {
    //    "columnNames": ["longitude", "latitude", "time", "sea_surface_temperature"],
    //    "columnTypes": ["float", "float", "String", "float"],
    //    "columnUnits": ["degrees_east", "degrees_north", "UTC", "degree_C"],
    //    "rows": [
    //      [180.099, 0.032, "2007-10-04T12:00:00Z", 27.66],
    //      [180.099, 0.032, null, null],
    //      [189.971, -7.98, "2007-10-04T12:00:00Z", 29.08]
    //    ]
    //}
    */
    String inFile = dir + tableName + ".txt";
    String2.log("\n* processOneCalcofi2012 " + inFile);
    StringArray names = new StringArray();
    StringArray types = new StringArray();
    StringArray units = new StringArray();
    StringArray lNames = new StringArray();
    Test.ensureEqual(info.length % 4, 0, "info.length=" + info.length);
    int nVars = info.length / 4;
    int n = 0;
    for (int v = 0; v < nVars; v++) {
        names.add(info[n++]);
        types.add(info[n++]);
        units.add(info[n++]);
        lNames.add(info[n++]);
    }

    String fromFile[] = String2.readFromFile(inFile);
    if (fromFile[0].length() > 0)
        throw new RuntimeException(fromFile[0]);
    String lines = String2.replaceAll(fromFile[1], "\t", ",");
    lines = String2.replaceAll(lines, "\n", "],\n[");
    lines = "{\n" + "  \"table\": {\n" + "    \"columnNames\": [" + names.toJsonCsvString() + "],\n"
            + "    \"columnTypes\": [" + types.toJsonCsvString() + "],\n" + "    \"columnUnits\": ["
            + units.toJsonCsvString() + "],\n" + "    \"rows\": [\n" + "["
            + lines.substring(0, lines.length() - 3) + "\n" + "]\n" + "}\n";
    String2.log(lines.substring(0, Math.min(lines.length(), 1500)));
    Table table = new Table();
    table.readJson(inFile, lines);
    String2.log("Before adjustments:\n" + String2.annotatedString(table.dataToString(5)));
    int nRows = table.nRows();
    int nErrors = 0;

    //things where nColumns won't change
    for (int v = 0; v < table.nColumns(); v++) {
        PrimitiveArray pa = table.getColumn(v);
        String vName = table.getColumnName(v);
        Attributes atts = table.columnAttributes(v);

        //longNames
        atts.add("long_name", lNames.get(v)); //relies on original var lists

        //timeZone
        nErrors = 0;
        if ("timeZone".equals(vName)) {
            PrimitiveArray arrivePA = table.getColumn("arriveDate"); //still yyMMdd
            GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles"));
            Calendar2.clearSmallerFields(gc, Calendar2.DATE);
            for (int row = 0; row < nRows; row++) {
                String val = arrivePA.getString(row);
                if (val.matches("[0-9]{6}")) {
                    int year = String2.parseInt(val.substring(0, 2));
                    gc.set(Calendar2.YEAR, year < cutoffYear ? 2000 : 1900);
                    gc.set(Calendar2.MONTH, String2.parseInt(val.substring(2, 4)) - 1); //0..
                    gc.set(Calendar2.DATE, String2.parseInt(val.substring(4, 6)));
                    int fileHas = pa.getInt(row);
                    int calculated = -gc.get(Calendar.ZONE_OFFSET) / (60 * 60 * 1000) + //in hours
                            -gc.get(Calendar.DST_OFFSET) / (60 * 60 * 1000); //in hours
                    if (fileHas != calculated) {
                        nErrors++;
                        if (nErrors <= 5)
                            String2.log("ERROR: col=" + vName + " row=" + row + " timeZone=" + fileHas
                                    + " != calculated(" + val + ")=" + calculated);
                    }
                }
            }
            if (nErrors > 0)
                String2.pressEnterToContinue("Bob: check US daylight savings time rules. On/near these dates?\n"
                        + "https://en.wikipedia.org/wiki/History_of_time_in_the_United_States\n" + "nErrors="
                        + nErrors);
        }

    }

    //things where nColumns may change
    for (int v = 0; v < table.nColumns(); v++) {
        PrimitiveArray pa = table.getColumn(v);
        String vName = table.getColumnName(v);
        Attributes atts = table.columnAttributes(v);
        String vUnits = atts.getString("units");
        Attributes nextAtts = v < table.nColumns() - 1 ? table.columnAttributes(v + 1) : new Attributes();

        //towTypeCode
        if ("towTypeCode".equals(vName))
            atts.add("description", towTypesDescription);

        //latitude
        nErrors = 0;
        if ("latitude".equals(vName) && "latitudeMinutes".equals(table.getColumnName(v + 1))
                && "latitudeLocation".equals(table.getColumnName(v + 2))) {
            FloatArray fa = new FloatArray(nRows, false); //float avoids, e.g., xx.33333333333333
            PrimitiveArray pa1 = table.getColumn(v + 1);
            PrimitiveArray pa2 = table.getColumn(v + 2);
            for (int row = 0; row < nRows; row++) {
                String loc = pa2.getString(row);
                String combo = pa.getString(row) + " " + pa1.getString(row) + " " + loc;
                float f = //will be NaN if trouble
                        (pa.getFloat(row) + (pa1.getFloat(row) / 60))
                                * (loc.equals("N") ? 1 : loc.equals("S") ? -1 : Float.NaN);
                fa.atInsert(row, f);
                if (combo.length() > 2 && //2 spaces
                        (f < -90 || f > 90 || Float.isNaN(f))) {
                    nErrors++;
                    if (nErrors <= 5)
                        String2.log("ERROR: col=" + vName + " row=" + row + " lat=" + combo + " -> " + f);
                }
            }
            table.setColumn(v, fa);
            table.removeColumn(v + 2);
            table.removeColumn(v + 1);
        }
        if (nErrors > 0)
            String2.pressEnterToContinue("nErrors=" + nErrors);

        //longitude
        nErrors = 0;
        if ("longitude".equals(vName) && "longitudeMinutes".equals(table.getColumnName(v + 1))
                && "longitudeLocation".equals(table.getColumnName(v + 2))) {
            FloatArray fa = new FloatArray(nRows, false); //float avoids, e.g., xx.33333333333333
            PrimitiveArray pa1 = table.getColumn(v + 1);
            PrimitiveArray pa2 = table.getColumn(v + 2);
            for (int row = 0; row < nRows; row++) {
                String loc = pa2.getString(row);
                String combo = pa.getString(row) + " " + pa1.getString(row) + " " + loc;
                float f = //will be NaN if trouble
                        (pa.getFloat(row) + (pa1.getFloat(row) / 60))
                                * (loc.equals("E") ? 1 : loc.equals("W") ? -1 : Float.NaN);
                fa.atInsert(row, f);
                if (combo.length() > 2 && //2 spaces
                        (f < -180 || f > 180 || Float.isNaN(f))) {
                    nErrors++;
                    if (nErrors <= 5)
                        String2.log("ERROR: col=" + vName + " row=" + row + " lat=" + combo + " -> " + f);
                }
            }
            table.setColumn(v, fa);
            table.removeColumn(v + 2);
            table.removeColumn(v + 1);
        }
        if (nErrors > 0)
            String2.pressEnterToContinue("nErrors=" + nErrors);

        //yyMM  add century to cruiseYYMM
        nErrors = 0;
        if ("yyMM".equals(vUnits)) {
            for (int row = 0; row < nRows; row++) {
                String val = pa.getString(row);
                if (val.matches("[0-9]{4}")) {
                    int year = String2.parseInt(val.substring(0, 2));
                    pa.setString(row, (year < cutoffYear ? "20" : "19") + val);
                } else {
                    if (val.length() != 0) {
                        nErrors++;
                        if (nErrors <= 5)
                            String2.log("ERROR: col=" + vName + " row=" + row + " yyMM=" + val);
                    }
                    pa.setString(row, ""); //set to MV
                }
            }
            atts.set("units", ""); //leave it as a String identifier
        }
        if (nErrors > 0)
            String2.pressEnterToContinue("nErrors=" + nErrors);

        //yyMMdd
        nErrors = 0;
        if ("yyMMdd".equals(vUnits)) {
            String nextUnits = nextAtts.getString("units");
            boolean nextHasMinutes = "HHmm".equals(nextUnits);
            if (nextHasMinutes)
                String2.log("combining yyMMdd and next column (HHmm)");
            String nextVName = nextHasMinutes ? table.getColumnName(v + 1) : "";
            DoubleArray datePA = new DoubleArray(nRows, false);
            PrimitiveArray minutesPA = nextHasMinutes ? table.getColumn(v + 1) : (PrimitiveArray) null;
            //??!! Use Zulu or local, or time_zone data (in one table only)?
            GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles"));
            Calendar2.clearSmallerFields(gc, Calendar2.DATE);
            for (int row = 0; row < nRows; row++) {
                String val = pa.getString(row);
                if (val.matches("[0-9]{6}")) {
                    int year = String2.parseInt(val.substring(0, 2));
                    gc.set(Calendar2.YEAR, year < cutoffYear ? 2000 : 1900);
                    gc.set(Calendar2.MONTH, String2.parseInt(val.substring(2, 4)) - 1); //0..
                    gc.set(Calendar2.DATE, String2.parseInt(val.substring(4, 6)));
                    if (nextHasMinutes) {
                        Calendar2.clearSmallerFields(gc, Calendar2.DATE);
                        int HHmm = minutesPA.getInt(row);
                        if (HHmm < 0 || HHmm > 2359) {
                            nErrors++;
                            if (nErrors <= 5)
                                String2.log("ERROR: col=" + nextVName + " row=" + row + " HHmm="
                                        + minutesPA.getString(row));
                        } else {
                            gc.set(Calendar2.HOUR_OF_DAY, HHmm / 100);
                            gc.set(Calendar2.MINUTE, HHmm % 100);
                        }
                    }
                    datePA.add(Calendar2.gcToEpochSeconds(gc));
                } else {
                    if (val.length() != 0) {
                        nErrors++;
                        if (nErrors <= 5)
                            String2.log("ERROR: col=" + vName + " row=" + row + " yyMMdd=" + val);
                    }
                    datePA.add(Double.NaN);
                }
            }
            table.setColumn(v, datePA);
            atts.set("units", Calendar2.SECONDS_SINCE_1970);
            atts.set("time_precision", //AKA EDV.TIME_PRECISION 
                    nextHasMinutes ? "1970-01-01T00:00" : "1970-01-01");
            if (nextHasMinutes)
                table.removeColumn(v + 1);
        }
        if (nErrors > 0)
            String2.pressEnterToContinue("nErrors=" + nErrors);

    }

    //save as .nc
    String2.log("After adjustments:\n" + String2.annotatedString(table.dataToString(5)));
    table.saveAsFlatNc(dir + tableName + ".nc", rowName, false);
    return table;
}