Exemple #1
0
  // convert to shared dimensions
  private void setSharedDimensions(
      Variable v, List<Element> values, List<Dimension> unknownDims, String location) {
    if (values.size() == 0) return;

    // remove the "scalar" dumbension
    Iterator<Element> iter = values.iterator();
    while (iter.hasNext()) {
      Element value = iter.next();
      String dimName = value.getText().trim();
      if (dimName.equalsIgnoreCase("scalar")) iter.remove();
    }

    // gotta have same number of dimensions
    List<Dimension> oldDims = v.getDimensions();
    if (oldDims.size() != values.size()) {
      log.error("Different number of dimensions for {} {}", v, location);
      return;
    }

    List<Dimension> newDims = new ArrayList<>();
    Group group = v.getParentGroup();

    for (int i = 0; i < values.size(); i++) {
      Element value = values.get(i);
      String dimName = value.getText().trim();
      dimName = NetcdfFile.makeValidCdmObjectName(dimName);

      Dimension dim = group.findDimension(dimName);
      Dimension oldDim = oldDims.get(i);
      if (dim == null) dim = checkUnknownDims(dimName, unknownDims, oldDim, location);

      if (dim == null) {
        log.error(
            "Unknown Dimension= {} for variable = {} {} ", dimName, v.getFullName(), location);
        return;
      }
      if (dim.getLength() != oldDim.getLength()) {
        log.error(
            "Shared dimension ("
                + dim.getShortName()
                + ") has different length than data dimension ("
                + oldDim.getShortName()
                + ") shared="
                + dim.getLength()
                + " org="
                + oldDim.getLength()
                + " for "
                + v
                + " "
                + location);
        return;
      }
      newDims.add(dim);
    }
    v.setDimensions(newDims);
    if (showWork) System.out.printf(" set shared dimensions for %s %n", v.getNameAndDimensions());
  }
Exemple #2
0
  private FeatureType amendGrid(
      Element gridElem, NetcdfFile ncfile, Group parent, String location) {
    List<Dimension> unknownDims = new ArrayList<>();

    // always has x and y dimension
    String xdimSizeS = gridElem.getChild("XDim").getText().trim();
    String ydimSizeS = gridElem.getChild("YDim").getText().trim();
    int xdimSize = Integer.parseInt(xdimSizeS);
    int ydimSize = Integer.parseInt(ydimSizeS);
    parent.addDimensionIfNotExists(new Dimension("XDim", xdimSize));
    parent.addDimensionIfNotExists(new Dimension("YDim", ydimSize));

    /* see HdfEosModisConvention
    UpperLeftPointMtrs=(-20015109.354000,1111950.519667)
    		LowerRightMtrs=(-18903158.834333,-0.000000)
    		Projection=GCTP_SNSOID
    		ProjParams=(6371007.181000,0,0,0,0,0,0,0,0,0,0,0,0)
    		SphereCode=-1
     */
    Element proj = gridElem.getChild("Projection");
    if (proj != null) {
      Variable crs = new Variable(ncfile, parent, null, HDFEOS_CRS);
      crs.setDataType(DataType.SHORT);
      crs.setDimensions(""); // scalar
      crs.setCachedData(Array.makeArray(DataType.SHORT, 1, 0, 0)); // fake data
      parent.addVariable(crs);

      addAttributeIfExists(gridElem, HDFEOS_CRS_Projection, crs, false);
      addAttributeIfExists(gridElem, HDFEOS_CRS_UpperLeft, crs, true);
      addAttributeIfExists(gridElem, HDFEOS_CRS_LowerRight, crs, true);
      addAttributeIfExists(gridElem, HDFEOS_CRS_ProjParams, crs, true);
      addAttributeIfExists(gridElem, HDFEOS_CRS_SphereCode, crs, false);
    }

    // global Dimensions
    Element d = gridElem.getChild("Dimension");
    List<Element> dims = d.getChildren();
    for (Element elem : dims) {
      String name = elem.getChild("DimensionName").getText().trim();
      name = NetcdfFile.makeValidCdmObjectName(name);
      if (name.equalsIgnoreCase("scalar")) continue;

      String sizeS = elem.getChild("Size").getText().trim();
      int length = Integer.parseInt(sizeS);
      Dimension old = parent.findDimension(name);
      if ((old == null) || (old.getLength() != length)) {
        if (length > 0) {
          Dimension dim = new Dimension(name, length);
          if (parent.addDimensionIfNotExists(dim) && showWork)
            System.out.printf(" Add dimension %s %n", dim);
        } else {
          log.warn("Dimension {} has size {} {} ", sizeS, name, location);
          Dimension udim = new Dimension(name, 1);
          udim.setGroup(parent);
          unknownDims.add(udim);
          if (showWork) System.out.printf(" Add dimension %s %n", udim);
        }
      }
    }

    // Geolocation Variables
    Group geoFieldsG = parent.findGroup(GEOLOC_FIELDS);
    if (geoFieldsG == null) geoFieldsG = parent.findGroup(GEOLOC_FIELDS2);

    if (geoFieldsG != null) {
      Element floc = gridElem.getChild("GeoField");
      List<Element> varsLoc = floc.getChildren();
      for (Element elem : varsLoc) {
        String varname = elem.getChild("GeoFieldName").getText().trim();
        Variable v = geoFieldsG.findVariable(varname);
        // if (v == null)
        //  v = geoFieldsG.findVariable( H4header.createValidObjectName(varname));
        assert v != null : varname;

        Element dimList = elem.getChild("DimList");
        List<Element> values = dimList.getChildren("value");
        setSharedDimensions(v, values, unknownDims, location);
      }
    }

    // Data Variables
    Group dataG = parent.findGroup(DATA_FIELDS);
    if (dataG == null)
      dataG =
          parent.findGroup(
              DATA_FIELDS2); // eg C:\data\formats\hdf4\eos\mopitt\MOP03M-200501-L3V81.0.1.hdf

    if (dataG != null) {
      Element f = gridElem.getChild("DataField");
      List<Element> vars = f.getChildren();
      for (Element elem : vars) {
        String varname = elem.getChild("DataFieldName").getText().trim();
        varname = NetcdfFile.makeValidCdmObjectName(varname);
        Variable v = dataG.findVariable(varname);
        // if (v == null)
        //  v = dataG.findVariable( H4header.createValidObjectName(varname));
        assert v != null : varname;

        Element dimList = elem.getChild("DimList");
        List<Element> values = dimList.getChildren("value");
        setSharedDimensions(v, values, unknownDims, location);
      }

      // get projection
      String projS = null;
      Element projElem = gridElem.getChild("Projection");
      if (projElem != null) projS = projElem.getText().trim();
      boolean isLatLon = "GCTP_GEO".equals(projS);

      // look for XDim, YDim coordinate variables
      if (isLatLon) {
        for (Variable v : dataG.getVariables()) {
          if (v.isCoordinateVariable()) {
            if (v.getShortName().equals("YDim")) {
              v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lat.toString()));
              v.addAttribute(new Attribute(CDM.UNITS, CDM.LAT_UNITS));
            }
            if (v.getShortName().equals("XDim"))
              v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lon.toString()));
          }
        }
      }
    }
    return FeatureType.GRID;
  }
  /**
   * Add this coord as a variable in the netCDF file
   *
   * @param ncfile netCDF file to add to
   * @param g group in file
   */
  void addToNetcdfFile(NetcdfFile ncfile, Group g) {
    if (dontUseVertical) {
      typicalRecord = null;
      return;
    }

    if (g == null) {
      g = ncfile.getRootGroup();
    }

    // coordinate axis
    Variable v = new Variable(ncfile, g, null, getVariableName());
    v.setDataType(DataType.DOUBLE);

    String desc = lookup.getLevelDescription(typicalRecord);
    if (lookup instanceof Grib2GridTableLookup && usesBounds) {
      desc = "Layer between " + desc;
    }

    v.addAttribute(new Attribute("long_name", desc));
    v.addAttribute(new Attribute("units", lookup.getLevelUnit(typicalRecord)));

    // positive attribute needed for CF-1 Height and Pressure
    if (positive != null) {
      v.addAttribute(new Attribute("positive", positive));
    }

    if (units != null) {
      AxisType axisType;
      if (SimpleUnit.isCompatible("millibar", units)) {
        axisType = AxisType.Pressure;
      } else if (SimpleUnit.isCompatible("m", units)) {
        axisType = AxisType.Height;
      } else {
        axisType = AxisType.GeoZ;
      }

      if (lookup instanceof Grib2GridTableLookup || lookup instanceof Grib1GridTableLookup) {
        v.addAttribute(
            new Attribute("GRIB_level_type", Integer.toString(typicalRecord.getLevelType1())));
      } else {
        v.addAttribute(
            new Attribute("level_type", Integer.toString(typicalRecord.getLevelType1())));
      }
      v.addAttribute(new Attribute(_Coordinate.AxisType, axisType.toString()));
    }

    if (coordValues == null) {
      coordValues = new double[levels.size()];
      for (int i = 0; i < levels.size(); i++) {
        LevelCoord lc = (LevelCoord) levels.get(i);
        coordValues[i] = lc.mid;
      }
    }
    Array dataArray = Array.factory(DataType.DOUBLE, new int[] {coordValues.length}, coordValues);

    v.setDimensions(getVariableName());
    v.setCachedData(dataArray, true);

    ncfile.addVariable(g, v);

    if (usesBounds) {
      String boundsDimName = "bounds_dim";
      if (g.findDimension(boundsDimName) == null) {
        ncfile.addDimension(g, new Dimension(boundsDimName, 2, true));
      }

      String bname = getVariableName() + "_bounds";
      v.addAttribute(new Attribute("bounds", bname));
      v.addAttribute(new Attribute(_Coordinate.ZisLayer, "true"));

      Variable b = new Variable(ncfile, g, null, bname);
      b.setDataType(DataType.DOUBLE);
      b.setDimensions(getVariableName() + " " + boundsDimName);
      b.addAttribute(new Attribute("long_name", "bounds for " + v.getName()));
      b.addAttribute(new Attribute("units", lookup.getLevelUnit(typicalRecord)));

      Array boundsArray = Array.factory(DataType.DOUBLE, new int[] {coordValues.length, 2});
      ucar.ma2.Index ima = boundsArray.getIndex();
      for (int i = 0; i < coordValues.length; i++) {
        LevelCoord lc = (LevelCoord) levels.get(i);
        boundsArray.setDouble(ima.set(i, 0), lc.value1);
        boundsArray.setDouble(ima.set(i, 1), lc.value2);
      }
      b.setCachedData(boundsArray, true);

      ncfile.addVariable(g, b);
    }

    if (factors != null) {
      // check if already created
      if (g == null) {
        g = ncfile.getRootGroup();
      }
      if (g.findVariable("hybrida") != null) return;
      v.addAttribute(new Attribute("standard_name", "atmosphere_hybrid_sigma_pressure_coordinate"));
      v.addAttribute(new Attribute("formula_terms", "ap: hybrida b: hybridb ps: Pressure"));
      // create  hybrid factor variables
      // add hybrida variable
      Variable ha = new Variable(ncfile, g, null, "hybrida");
      ha.setDataType(DataType.DOUBLE);
      ha.addAttribute(new Attribute("long_name", "level_a_factor"));
      ha.addAttribute(new Attribute("units", ""));
      ha.setDimensions(getVariableName());
      // add data
      int middle = factors.length / 2;
      double[] adata;
      double[] bdata;
      if (levels.size() < middle) { // only partial data wanted
        adata = new double[levels.size()];
        bdata = new double[levels.size()];
      } else {
        adata = new double[middle];
        bdata = new double[middle];
      }
      for (int i = 0; i < middle && i < levels.size(); i++) adata[i] = factors[i];
      Array haArray = Array.factory(DataType.DOUBLE, new int[] {adata.length}, adata);
      ha.setCachedData(haArray, true);
      ncfile.addVariable(g, ha);

      // add hybridb variable
      Variable hb = new Variable(ncfile, g, null, "hybridb");
      hb.setDataType(DataType.DOUBLE);
      hb.addAttribute(new Attribute("long_name", "level_b_factor"));
      hb.addAttribute(new Attribute("units", ""));
      hb.setDimensions(getVariableName());
      // add data
      for (int i = 0; i < middle && i < levels.size(); i++) bdata[i] = factors[i + middle];
      Array hbArray = Array.factory(DataType.DOUBLE, new int[] {bdata.length}, bdata);
      hb.setCachedData(hbArray, true);
      ncfile.addVariable(g, hb);

      /*  // TODO: delete next time modifying code
      double[] adata = new double[ middle ];
      for( int i = 0; i < middle; i++ )
        adata[ i ] = factors[ i ];
      Array haArray = Array.factory(DataType.DOUBLE, new int[]{adata.length}, adata);
      ha.setCachedData(haArray, true);
      ncfile.addVariable(g, ha);

      // add hybridb variable
      Variable hb = new Variable(ncfile, g, null, "hybridb");
      hb.setDataType(DataType.DOUBLE);
      hb.addAttribute(new Attribute("long_name",  "level_b_factor" ));
      //hb.addAttribute(new Attribute("standard_name", "atmosphere_hybrid_sigma_pressure_coordinate" ));
      hb.addAttribute(new Attribute("units", ""));
      hb.setDimensions(getVariableName());
      // add data
      double[] bdata = new double[ middle ];
      for( int i = 0; i < middle; i++ )
        bdata[ i ] = factors[ i + middle ];
      Array hbArray = Array.factory(DataType.DOUBLE, new int[]{bdata.length}, bdata);
      hb.setCachedData(hbArray, true);
      ncfile.addVariable(g, hb);
      */
    }
  }