Java Code Examples for ucar.nc2.Dimension#getLength()

The following examples show how to use ucar.nc2.Dimension#getLength() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AggDatasetOuter.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 7 votes vote down vote up
/**
 * Get number of coordinates in this Dataset.
 * If not already set, open the file and get it from the aggregation dimension.
 *
 * @param cancelTask allow cancellation
 * @return number of coordinates in this Dataset.
 * @throws IOException if io error
 */
public int getNcoords(CancelTask cancelTask) throws IOException {
  if (ncoord <= 0) {
    try (NetcdfFile ncd = acquireFile(cancelTask)) {
      if ((cancelTask != null) && cancelTask.isCancel())
        return 0;

      Dimension d = ncd.findDimension(aggregationOuter.dimName); // long name of dimension
      if (d != null)
        ncoord = d.getLength();
      else
        throw new IllegalArgumentException("Dimension not found= " + aggregationOuter.dimName);
    }
  }
  return ncoord;
}
 
Example 2
Source File: H5headerNew.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private String addDimension(Group.Builder parent, H5Group h5group, String name, int length, boolean isUnlimited) {
  int pos = name.lastIndexOf('/');
  String dimName = (pos >= 0) ? name.substring(pos + 1) : name;

  Dimension d = h5group.dimMap.get(dimName); // first look in current group
  if (d == null) { // create if not found
    d = Dimension.builder().setName(name).setIsUnlimited(isUnlimited).setLength(length).build();
    h5group.dimMap.put(dimName, d);
    h5group.dimList.add(d);
    parent.addDimension(d);
    if (debugDimensionScales) {
      log.debug("addDimension name=" + name + " dim= " + d + " to group " + parent.shortName);
    }

  } else { // check has correct length
    if (d.getLength() != length)
      throw new IllegalStateException(
          "addDimension: DimScale has different length than dimension it references dimScale=" + dimName);
  }

  return d.getShortName();
}
 
Example 3
Source File: AggregationOuterDimension.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * Get number of coordinates in this Dataset.
 * If not already set, open the file and get it from the aggregation dimension.
 *
 * @param cancelTask allow cancellation
 * @return number of coordinates in this Dataset.
 * @throws java.io.IOException if io error
 */
public int getNcoords(CancelTask cancelTask) throws IOException {
  if (ncoord <= 0) {
    try (NetcdfFile ncd = acquireFile(cancelTask)) {
      if ((cancelTask != null) && cancelTask.isCancel())
        return 0;

      Dimension d = ncd.findDimension(dimName); // long name of dimension
      if (d != null)
        ncoord = d.getLength();
      else
        throw new IllegalArgumentException("Dimension not found= " + dimName);
    }
  }
  return ncoord;
}
 
Example 4
Source File: WRFConvention.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
@Nullable
private CoordinateAxis.Builder makeLonCoordAxis(String axisName, Dimension dim) {
  if (dim == null)
    return null;
  double dx = 4 * findAttributeDouble("DX");
  int nx = dim.getLength();
  double startx = centerX - dx * (nx - 1) / 2;

  CoordinateAxis.Builder v = CoordinateAxis1D.builder().setName(axisName).setDataType(DataType.DOUBLE)
      .setDimensionsByName(dim.getShortName()).setUnits("degrees_east").setDesc("synthesized longitude coordinate");
  v.setAutoGen(startx, dx);
  v.setAxisType(AxisType.Lon);
  v.addAttribute(new Attribute(_Coordinate.AxisType, "Lon"));
  if (!axisName.equals(dim.getShortName()))
    v.addAttribute(new Attribute(_Coordinate.AliasForDimension, dim.getShortName()));

  return v;
}
 
Example 5
Source File: WRFConvention.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
@Nullable
private CoordinateAxis.Builder makeLatCoordAxis(String axisName, Dimension dim) {
  if (dim == null)
    return null;
  double dy = findAttributeDouble("DY");
  int ny = dim.getLength();
  double starty = centerY - dy * (ny - 1) / 2;

  CoordinateAxis.Builder v = CoordinateAxis1D.builder().setName(axisName).setDataType(DataType.DOUBLE)
      .setDimensionsByName(dim.getShortName()).setUnits("degrees_north").setDesc("synthesized latitude coordinate");
  v.setAutoGen(starty, dy);
  v.setAxisType(AxisType.Lat);
  v.addAttribute(new Attribute(_Coordinate.AxisType, "Lat"));
  if (!axisName.equals(dim.getShortName()))
    v.addAttribute(new Attribute(_Coordinate.AliasForDimension, dim.getShortName()));

  return v;
}
 
Example 6
Source File: WRFConvention.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
@Nullable
private CoordinateAxis.Builder makeXCoordAxis(String axisName, String dimName) {
  Optional<Dimension> dimOpt = rootGroup.findDimension(dimName);
  if (!dimOpt.isPresent()) {
    return null;
  }
  Dimension dim = dimOpt.get();
  double dx = findAttributeDouble("DX") / 1000.0; // km ya just gotta know
  int nx = dim.getLength();
  double startx = centerX - dx * (nx - 1) / 2; // ya just gotta know

  CoordinateAxis.Builder v = CoordinateAxis1D.builder().setName(axisName).setDataType(DataType.DOUBLE)
      .setParentGroupBuilder(rootGroup).setDimensionsByName(dim.getShortName()).setUnits("km")
      .setDesc("synthesized GeoX coordinate from DX attribute");
  v.setAutoGen(startx, dx);
  v.setAxisType(AxisType.GeoX);
  v.addAttribute(new Attribute(_Coordinate.AxisType, "GeoX"));
  if (!axisName.equals(dim.getShortName()))
    v.addAttribute(new Attribute(_Coordinate.AliasForDimension, dim.getShortName()));

  if (gridE)
    v.addAttribute(new Attribute(_Coordinate.Stagger, CDM.ARAKAWA_E));
  return v;
}
 
Example 7
Source File: CDMUtil.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Test a List<Range> against the CDM variable's dimensions
 * to see if the range list is whole
 * wrt the dimensions
 *
 * @param rangelist the set of ucar.ma2.Range
 * @param var the cdm var
 * @result true if rangelist is whole wrt slices; false otherwise.
 */
public static boolean isWhole(List<Range> rangelist, Variable var) throws dap4.core.util.DapException {
  List<Dimension> dimset = var.getDimensions();
  if (rangelist.size() != dimset.size())
    return false;
  for (int i = 0; i < rangelist.size(); i++) {
    Range r = rangelist.get(i);
    Dimension dim = dimset.get(i);
    if (r.stride() != 1 || r.first() != 0 || r.length() != dim.getLength())
      return false;
  }
  return true;
}
 
Example 8
Source File: DtCoverageAdapter.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private static CoverageCoordAxis makeCoordAxisFromDimension(Dimension dim) {
  CoverageCoordAxisBuilder builder = new CoverageCoordAxisBuilder();
  builder.name = dim.getFullName();
  builder.dataType = DataType.INT;
  builder.axisType = AxisType.Dimension;
  builder.dependenceType = CoverageCoordAxis.DependenceType.dimension;
  builder.spacing = CoverageCoordAxis.Spacing.regularPoint;
  builder.ncoords = dim.getLength();
  builder.startValue = 0;
  builder.endValue = dim.getLength() - 1;
  builder.resolution = 1;

  return new CoverageCoordAxis1D(builder);
}
 
Example 9
Source File: Nc4ChunkingDefault.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
protected int[] convertUnlimitedShape(List<Dimension> dims) {
  int[] result = new int[dims.size()];
  int count = 0;
  for (Dimension d : dims) {
    result[count++] = (d.isUnlimited()) ? 1 : d.getLength();
  }
  return result;
}
 
Example 10
Source File: GribCoordsMatchGbx.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private boolean read(GridDatatype gdt) throws IOException {
  // if (!gdt.getName().startsWith("Total_pre")) return true;
  if (showMissing)
    logger.debug("grid {}", gdt.getName());
  countReadsForVariable = 0;
  gdc = gdt.getCoordinateSystem();
  grid = gdt;
  dtCoords = new SubsetParams();
  Dimension rtDim = gdt.getRunTimeDimension();
  Dimension tDim = gdt.getTimeDimension();
  Dimension zDim = gdt.getZDimension();

  try {
    // loop over runtime
    if (rtDim != null) {
      CoordinateAxis1DTime rtcoord = gdc.getRunTimeAxis();

      for (int rt = 0; rt < rtDim.getLength(); rt++) {
        dtCoords.setRunTime(rtcoord.getCalendarDate(rt));
        readTime(gdt, rt, tDim, zDim);
      }

    } else {
      readTime(gdt, -1, tDim, zDim);
    }
    timeCoord2DBoundsArray = null;

  } catch (AssertionError e) {
    e.printStackTrace();
    return false;

  } catch (Throwable t) {
    t.printStackTrace();
    return false;
  }

  return true;
}
 
Example 11
Source File: TestGribCollectionMissing.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public static Count read(GridDatatype gdt) throws IOException {
  Dimension rtDim = gdt.getRunTimeDimension();
  Dimension tDim = gdt.getTimeDimension();
  Dimension zDim = gdt.getZDimension();

  Count count = new Count();
  if (rtDim != null) {
    for (int rt = 0; rt < rtDim.getLength(); rt++)
      read(gdt, count, rt, tDim, zDim);
  } else {
    read(gdt, count, -1, tDim, zDim);
  }
  return count;
}
 
Example 12
Source File: M3IOConvention.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private void makeZCoordAxis(String dimName, String levelsName, String unitName) {
  Dimension dimz = rootGroup.findDimension(dimName).get();
  int nz = dimz.getLength();
  ArrayDouble.D1 dataLev = new ArrayDouble.D1(nz);
  ArrayDouble.D1 dataLayers = new ArrayDouble.D1(nz + 1);

  // layer values are a numeric global attribute array !!
  Attribute layers = rootGroup.getAttributeContainer().findAttribute(levelsName);
  for (int i = 0; i <= nz; i++)
    dataLayers.set(i, layers.getNumericValue(i).doubleValue());

  for (int i = 0; i < nz; i++) {
    double midpoint = (dataLayers.get(i) + dataLayers.get(i + 1)) / 2;
    dataLev.set(i, midpoint);
  }

  CoordinateAxis.Builder v = CoordinateAxis1D.builder().setName("level").setDataType(DataType.DOUBLE)
      .setParentGroupBuilder(rootGroup).setDimensionsByName(dimName).setUnits(unitName)
      .setDesc("synthesized coordinate from " + levelsName + " global attributes");
  v.setCachedData(dataLev, true);
  v.addAttribute(new Attribute("positive", "down"));
  v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.GeoZ.toString()));

  // layer edges
  String edge_name = "layer";
  Dimension lay_edge = new Dimension(edge_name, nz + 1);
  rootGroup.addDimension(lay_edge);
  CoordinateAxis.Builder vedge = CoordinateAxis1D.builder().setName(edge_name).setDataType(DataType.DOUBLE)
      .setParentGroupBuilder(rootGroup).setDimensionsByName(edge_name).setUnits(unitName)
      .setDesc("synthesized coordinate from " + levelsName + " global attributes");
  vedge.setCachedData(dataLayers, true);
  v.setBoundary(edge_name);

  datasetBuilder.replaceCoordinateAxis(rootGroup, v);
  datasetBuilder.replaceCoordinateAxis(rootGroup, vedge);
}
 
Example 13
Source File: NetcdfDataObject.java    From OpenDA with GNU Lesser General Public License v3.0 4 votes vote down vote up
/**
 * Writes all data for the given exchangeItems to the given netcdfFile.
 * Only executed when this.lazyWriting = true
    *
 * @param netcdfFileWriter
 * @param exchangeItems to write.
 */
//TODO remove. This is only used for SWAN state files (see SwanStateNetcdfFileTest.testSwanNetcdfStateFile_1). AK
private void writeData(NetcdfFileWriter netcdfFileWriter, List<IExchangeItem> exchangeItems) {
	for (IExchangeItem exchangeItem : exchangeItems){
		if (exchangeItem.getGeometryInfo() == null){
			//TODO Julius: please remove this hack for SWAN state files. AK
               //TODO: replace this SWAN specific implementation with the above generic ones.
			String exchangeItemId = exchangeItem.getId();
			//TODO: add netcdf writers for various data type / exchangeitems.
			//For SWAN state file, only wave_spectrum is modified and rewritten.
			if (exchangeItemId.equalsIgnoreCase("wave_spectrum")){
				double[] dblValues = exchangeItem.getValuesAsDoubles();
				int my=31;
				int mx=61;
				int wave_frequency=25;
				int wave_direction=18;
				// get dimensions:
				// TODO: in the future, dimensions should be available in the exchangeItem as part of meta data
				// This will avoid having to read the netcdf file for obtaining the dimensions.
				List<Dimension> dimensions = netcdfFileWriter.getNetcdfFile().getDimensions();
				int nDim = dimensions.size();
				for (Dimension dimension : dimensions) {
					if ("my".equalsIgnoreCase(dimension.getShortName())) {
						my = dimension.getLength();
					} else if ("mx".equalsIgnoreCase(dimension.getShortName())) {
						mx = dimension.getLength();
					} else if ("wave_frequency".equalsIgnoreCase(dimension.getShortName())) {
						wave_frequency = dimension.getLength();
					} else if ("wave_direction".equalsIgnoreCase(dimension.getShortName())) {
						wave_direction = dimension.getLength();
					} else {
						continue;
					}
				}
				ArrayDouble.D4 values = new ArrayDouble.D4(my,mx,wave_frequency,wave_direction);
				int iVal = 0;
				for (int iy=0; iy<my; iy++){
					for (int ix=0; ix<mx; ix++){
						for (int iwf=0; iwf<wave_frequency; iwf++){
							for (int iwd=0; iwd<wave_direction; iwd++){
								values.set(iy,ix,iwf,iwd,dblValues[iVal]);
								iVal++;
							}
						}
					}
				}
				try {
					Variable myVar = netcdfFileWriter.findVariable("wave_spectrum");
					netcdfFileWriter.write(myVar,values);
				} catch (IOException | InvalidRangeException e) {
					e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
				}
			}
		}
	}
}
 
Example 14
Source File: H5headerNew.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
private void findDimensionScales2D(H5Group h5group, DataObjectFacade facade) {
  int[] lens = facade.dobj.mds.dimLength;
  if (lens.length > 2) {
    log.warn("DIMENSION_LIST: dimension scale > 2 = {}", facade.getName());
    return;
  }

  // first dimension is itself
  String name = facade.getName();
  int pos = name.lastIndexOf('/');
  String dimName = (pos >= 0) ? name.substring(pos + 1) : name;

  StringBuilder sbuff = new StringBuilder();
  sbuff.append(dimName);
  sbuff.append(" ");

  // second dimension is really an anonymous dimension, ironically now we go through amazing hoops to keep it shared
  // 1. use dimids if they exist
  // 2. if length matches and unique, use it
  // 3. if no length matches or multiple matches, then use anonymous

  int want_len = lens[1]; // second dimension
  Dimension match = null;
  boolean unique = true;
  for (Dimension d : h5group.dimList) {
    if (d.getLength() == want_len) {
      if (match == null)
        match = d;
      else
        unique = false;
    }
  }
  if (match != null && unique) {
    sbuff.append(match.getShortName()); // 2. if length matches and unique, use it

  } else {
    if (match == null) { // 3. if no length matches or multiple matches, then use anonymous
      log.warn("DIMENSION_LIST: dimension scale {} has second dimension {} but no match", facade.getName(), want_len);
      sbuff.append(want_len);
    } else {
      log.warn("DIMENSION_LIST: dimension scale {} has second dimension {} but multiple matches", facade.getName(),
          want_len);
      sbuff.append(want_len);
    }
  }

  facade.dimList = sbuff.toString();
}
 
Example 15
Source File: AWIPSConvention.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
private CoordinateAxis.Builder makeTimeCoordAxis() {
  VariableDS.Builder timeVar = (VariableDS.Builder) rootGroup.findVariableLocal("valtimeMINUSreftime")
      .orElseThrow(() -> new RuntimeException("must have varible 'valtimeMINUSreftime'"));

  Dimension recordDim =
      rootGroup.findDimension("record").orElseThrow(() -> new RuntimeException("must have dimension 'record'"));

  Array vals;
  try {
    vals = timeVar.orgVar.read();
  } catch (IOException ioe) {
    return null;
  }

  // it seems that the record dimension does not always match valtimeMINUSreftime dimension!!
  // HAHAHAHAHAHAHAHA !
  int recLen = recordDim.getLength();
  int valLen = (int) vals.getSize();
  if (recLen != valLen) {
    try {
      vals = vals.sectionNoReduce(new int[] {0}, new int[] {recordDim.getLength()}, null);
      parseInfo.format(" corrected the TimeCoordAxis length%n");
    } catch (InvalidRangeException e) {
      parseInfo.format("makeTimeCoordAxis InvalidRangeException%n");
    }
  }

  // create the units out of the filename if possible
  String units = makeTimeUnitFromFilename(datasetBuilder.location);
  if (units == null) // ok that didnt work, try something else
    return makeTimeCoordAxisFromReference(vals);

  // create the coord axis
  String name = "timeCoord";
  String desc = "synthesized time coordinate from valtimeMINUSreftime and filename YYYYMMDD_HHMM";
  CoordinateAxis1D.Builder timeCoord =
      CoordinateAxis1D.builder().setName(name).setDataType(DataType.INT).setParentGroupBuilder(rootGroup)
          .setDimensionsByName("record").setUnits(units).setDesc(desc).setCachedData(vals, true);

  parseInfo.format("Created Time Coordinate Axis = %s%n", name);
  return timeCoord;
}
 
Example 16
Source File: N3headerWriter.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
private void writeVars(List<Variable> vars, boolean largeFile, Formatter fout) throws IOException {
  int n = vars.size();
  if (n == 0) {
    raf.writeInt(0);
    raf.writeInt(0);
  } else {
    raf.writeInt(MAGIC_VAR);
    raf.writeInt(n);
  }

  for (Variable var : vars) {
    writeString(var.getShortName());

    // dimensions
    long vsize = var.getDataType().getSize(); // works for all netcdf-3 data types
    List<Dimension> dims = var.getDimensions();
    raf.writeInt(dims.size());
    for (Dimension dim : dims) {
      int dimIndex = findDimensionIndex(ncfile, dim);
      raf.writeInt(dimIndex);

      if (!dim.isUnlimited())
        vsize *= dim.getLength();
    }
    long unpaddedVsize = vsize;
    vsize += padding(vsize);

    // variable attributes
    long varAttsPos = raf.getFilePointer();
    writeAtts(var.attributes(), fout);

    // data type, variable size, beginning file position
    DataType dtype = var.getDataType();
    int type = getType(dtype);
    raf.writeInt(type);

    int vsizeWrite = (vsize < MAX_UNSIGNED_INT) ? (int) vsize : -1;
    raf.writeInt(vsizeWrite);
    long pos = raf.getFilePointer();
    if (largeFile)
      raf.writeLong(0); // come back to this later
    else
      raf.writeInt(0); // come back to this later

    // From nc3 file format specification
    // (https://www.unidata.ucar.edu/software/netcdf/docs/netcdf.html#NetCDF-Classic-Format):
    // Note on padding: In the special case of only a single record variable of character,
    // byte, or short type, no padding is used between data values.
    // 2/15/2011: we will continue to write the (incorrect) padded vsize into the header, but we will use the unpadded
    // size to read/write
    if (uvars.size() == 1 && uvars.get(0) == var) {
      if ((dtype == DataType.CHAR) || (dtype == DataType.BYTE) || (dtype == DataType.SHORT)) {
        vsize = unpaddedVsize;
      }
    }
    var.setSPobject(new N3headerNew.Vinfo(var.getShortName(), vsize, pos, var.isUnlimited(), varAttsPos));
  }
}
 
Example 17
Source File: IFPSConvention.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
private void createTimeCoordinate(NetcdfDataset ds, Variable ncVar) {
  // Time coordinate is stored in the attribute validTimes
  // One caveat is that the times have two bounds an upper and a lower

  // get the times values
  Attribute timesAtt = ncVar.findAttribute("validTimes");
  if (timesAtt == null)
    return;
  Array timesArray = timesAtt.getValues();

  // get every other one LOOK this is awkward
  try {
    int n = (int) timesArray.getSize();
    List<Range> list = new ArrayList<>();
    list.add(new Range(0, n - 1, 2));
    timesArray = timesArray.section(list);
  } catch (InvalidRangeException e) {
    throw new IllegalStateException(e);
  }

  // make sure it matches the dimension
  DataType dtype = DataType.getType(timesArray);
  int nTimesAtt = (int) timesArray.getSize();

  // create a special dimension and coordinate variable
  Dimension dimTime = ncVar.getDimension(0);
  int nTimesDim = dimTime.getLength();
  if (nTimesDim != nTimesAtt) {
    parseInfo.format(" **error ntimes in attribute (%d) doesnt match dimension length (%d) for variable %s%n",
        nTimesAtt, nTimesDim, ncVar.getFullName());
    return;
  }

  // add the dimension
  String dimName = ncVar.getFullName() + "_timeCoord";
  Dimension newDim = new Dimension(dimName, nTimesDim);
  ds.addDimension(null, newDim);

  // add the coordinate variable
  String units = "seconds since 1970-1-1 00:00:00";
  String desc = "time coordinate for " + ncVar.getFullName();

  CoordinateAxis1D timeCoord = new CoordinateAxis1D(ds, null, dimName, dtype, dimName, units, desc);
  timeCoord.setCachedData(timesArray, true);
  timeCoord.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Time.toString()));
  ds.addCoordinateAxis(timeCoord);

  parseInfo.format(" added coordinate variable %s%n", dimName);

  // now make the original variable use the new dimension
  List<Dimension> dimsList = new ArrayList(ncVar.getDimensions());
  dimsList.set(0, newDim);
  ncVar.setDimensions(dimsList);

  // better to explicitly set the coordinate system
  ncVar.addAttribute(new Attribute(_Coordinate.Axes, dimName + " yCoord xCoord"));

  // fix the attributes
  Attribute att = ncVar.findAttribute("fillValue");
  if (att != null)
    ncVar.addAttribute(new Attribute(CDM.FILL_VALUE, att.getNumericValue()));
  att = ncVar.findAttribute("descriptiveName");
  if (null != att)
    ncVar.addAttribute(new Attribute(CDM.LONG_NAME, att.getStringValue()));

  // ncVar.enhance();
}
 
Example 18
Source File: NetcdfD3dMapDataObject.java    From OpenDA with GNU Lesser General Public License v3.0 4 votes vote down vote up
private void readNetCdfVariables() {

		for (Variable variable : this.netcdfFile.getVariables()) {

			if (Arrays.asList(keyVariables).contains(variable.getShortName())) {

				Variable timeVariable = NetcdfUtils.findTimeVariableForVariable(variable, this.netcdfFile);
				if (timeVariable == null) {
					throw new RuntimeException("NetcdfD3dMapDataObject: no time axis for " + variable.getShortName() + ", file: " + netcdfFile.getLocation());
				}
				this.timeDimensionIndex = variable.findDimensionIndex(timeVariable.getShortName());
				timeDependentVars.put(variable.getShortName(), variable);

				// if this is the first time dependent variable: read the times
				if (timesInNetcdfFile == null) {
					ucar.ma2.Array timesArray;
					try {
						timesArray = timeVariable.read();
					} catch (IOException e) {
						throw new RuntimeException("NetcdfD3dMapDataObject could not read time variable " + timeVariable.getShortName() +
								"from netcdf file " + netcdfFile.getLocation());
					}
					timesInNetcdfFile = (double[]) timesArray.get1DJavaArray(double.class);
				}

				// get the number of spatial dimensions
				// one of the dimensions was for time
				List<Dimension> dimensions = variable.getDimensions();
				int nonTimeDimensions = dimensions.size() - 1;
				if (nonTimeDimensions != 4 && variable.getShortName().equalsIgnoreCase("R1")) {
					throw new RuntimeException("NetcdfD3dMapDataObject: #dims for R1 should be four, file: " + netcdfFile.getLocation());
				}

				int layerCount = 0;
				for (int i = 0; i < dimensions.size(); i++) {
					Dimension dimension = dimensions.get(i);
					if (variable.getShortName().equalsIgnoreCase("R1")){
						if (dimension.getShortName().equalsIgnoreCase("LSTSCI")) {
							lstsciDimensionIndex = i;
							if (dimension.getLength() != 1) {
								throw new RuntimeException("NetcdfD3dMapDataObject: #R1 != 1 is not supported (temp. or salinity), file: "
									+ netcdfFile.getLocation());
							}
						}
					}
					if (!variable.getShortName().equalsIgnoreCase("S1")) {
						if (dimension.getShortName().equalsIgnoreCase("KMAXOUT_RESTR")) {
							if (variable.getShortName().equalsIgnoreCase("R1")) {
								kmaxOutRestrDimensionIndex = i;
							} else if (variable.getShortName().equalsIgnoreCase("U1") || variable.getShortName().equalsIgnoreCase("V1")) {
								kmaxOutRestrDimensionIndexVelocity = i;
							}
							if (dimension.getLength() < 0) {
								throw new RuntimeException("NetcdfD3dMapDataObject: could not read number of layers, file: "
									+ netcdfFile.getLocation());
							}
							layerCount = dimension.getLength();
						}
					}

				}

				if (lstsciDimensionIndex == 0 || kmaxOutRestrDimensionIndex == 0 || kmaxOutRestrDimensionIndexVelocity == 0) {
					throw new RuntimeException("NetcdfD3dMapDataObject: dims not available, file: "
						+ netcdfFile.getLocation());
				}

				ITimeInfo timeInfo = NetcdfUtils.createTimeInfo(variable, this.netcdfFile, timeInfoCache);
				// for memory reasons, for the time being we only keep the last time step in the exchange time
				// so adjust the time info
				double[] times = timeInfo.getTimes();
				timeInfo = new TimeInfo(new double[]{times[times.length-1]});

				// Extracting geometry information only once
				if (this.xCoords == null | this.yCoords == null | this.zCoords == null) {
					Variable variableX = this.netcdfFile.findVariable("XZ");
					Variable variableY = this.netcdfFile.findVariable("YZ");
					Variable variableZ = this.netcdfFile.findVariable("ZK_LYR");

					int[] originXY = createOrigin(variableX);
					int[] sizeArrayXY = variableX.getShape();
					int[] originZ = createOrigin(variableZ);
					int[] sizeArrayZ = variableZ.getShape();

					this.xCoords = NetcdfUtils.readSelectedData(variableX, originXY, sizeArrayXY, -1);
					this.yCoords = NetcdfUtils.readSelectedData(variableY, originXY, sizeArrayXY, -1);
					this.zCoords = NetcdfUtils.readSelectedData(variableZ, originZ, sizeArrayZ, -1);
				}

				IGeometryInfo geometryInfo;
				if (variable.getShortName().equalsIgnoreCase("S1")) {
					geometryInfo = new NetcdfD3dMapExchangeItemGeometryInfo(this.xCoords, this.yCoords, null);
				} else {
					geometryInfo = new NetcdfD3dMapExchangeItemGeometryInfo(this.xCoords, this.yCoords, this.zCoords);
				}
				IExchangeItem exchangeItem = new NetcdfD3dMapExchangeItem(variable.getShortName(), this, timeInfo, geometryInfo);
				this.exchangeItems.put(exchangeItem.getId(), exchangeItem);

			}
		}
	}
 
Example 19
Source File: GridWrapper.java    From sis with Apache License 2.0 4 votes vote down vote up
/**
 * Returns all axes of the netCDF coordinate system, together with the grid dimension to which the axis
 * is associated.
 *
 * <p>In this method, the words "domain" and "range" are used in the netCDF sense: they are the input
 * (domain) and output (range) of the function that convert grid indices to geodetic coordinates.</p>
 *
 * <p>The domain of all axes (or the {@linkplain CoordinateSystem#getDomain() coordinate system domain})
 * is often the same than the domain of the variable, but not necessarily.
 * In particular, the relationship is not straightforward when the coordinate system contains instances
 * of {@link CoordinateAxis2D}.</p>
 *
 * @param  decoder  the decoder of the netCDF file from which to create axes.
 * @return the CRS axes, in "natural" order (reverse of netCDF order).
 * @throws IOException if an I/O operation was necessary but failed.
 * @throws DataStoreException if a logical error occurred.
 * @throws ArithmeticException if the size of an axis exceeds {@link Integer#MAX_VALUE}, or other overflow occurs.
 */
@Override
protected Axis[] createAxes(final Decoder decoder) throws IOException, DataStoreException {
    final List<CoordinateAxis> range = netcdfCS.getCoordinateAxes();
    /*
     * In this method, 'sourceDim' and 'targetDim' are relative to "grid to CRS" conversion.
     * So 'sourceDim' is the grid (domain) dimension and 'targetDim' is the CRS (range) dimension.
     */
    int targetDim = range.size();
    final Axis[] axes = new Axis[targetDim];
    while (--targetDim >= 0) {
        final CoordinateAxis axis = range.get(targetDim);
        /*
         * The AttributeNames are for ISO 19115 metadata. They are not used for locating grid cells
         * on Earth, but we nevertheless get them now for making MetadataReader work easier.
         */
        char abbreviation = 0;
        final AxisType type = axis.getAxisType();
        if (type != null) switch (type) {
            case GeoX:            abbreviation = netcdfCS.isGeoXY() ? 'E' : 'x'; break;
            case GeoY:            abbreviation = netcdfCS.isGeoXY() ? 'N' : 'y'; break;
            case GeoZ:            abbreviation = netcdfCS.isGeoXY() ? 'H' : 'z'; break;
            case Lon:             abbreviation = 'λ'; break;
            case Lat:             abbreviation = 'φ'; break;
            case Pressure:        // Fallthrough: consider as Height
            case Height:          abbreviation = 'H'; break;
            case RunTime:         // Fallthrough: consider as Time
            case Time:            abbreviation = 't'; break;
            case RadialAzimuth:   abbreviation = 'θ'; break;    // Spherical longitude
            case RadialElevation: abbreviation = 'Ω'; break;    // Spherical latitude
            case RadialDistance:  abbreviation = 'r'; break;    // Geocentric radius
        }
        /*
         * Get the grid dimensions (part of the "domain" in UCAR terminology) used for computing
         * the coordinate values along the current axis. There is exactly 1 such grid dimension in
         * straightforward netCDF files. However some more complex files may have 2 dimensions.
         */
        int i = 0;
        final List<Dimension> axisDomain = axis.getDimensions();
        final int[] indices = new int[axisDomain.size()];
        final int[] sizes   = new int[indices.length];
        for (final Dimension dimension : axisDomain) {
            final int sourceDim = domain.lastIndexOf(dimension);
            if (sourceDim >= 0) {
                indices[i] = sourceDim;
                sizes[i++] = dimension.getLength();
            }
            /*
             * If the axis dimension has not been found in the coordinate system (sourceDim < 0),
             * then there is maybe a problem with the netCDF file. However for the purpose of this
             * package, we can proceed as if the dimension does not exist ('i' not incremented).
             */
        }
        axes[targetDim] = new Axis(abbreviation, axis.getPositive(),
                ArraysExt.resize(indices, i), ArraysExt.resize(sizes, i),
                ((DecoderWrapper) decoder).getWrapperFor(axis));
    }
    /*
     * We want axes in "natural" order. But the netCDF UCAR library sometime provides axes already
     * in that order and sometime in reverse order (netCDF order). I'm not aware of a reliable way
     * to determine whether axis order provided by UCAR library needs to be reverted since I don't
     * know what determines that order (the file format? the presence of "coordinates" attribute?).
     * For now we compare axis order with dimension order, and if the axis contains all dimensions
     * in the same order we presume that this is the "netCDF" order (as opposed to a "coordinates"
     * attribute value order).
     */
    for (int i = Math.min(domain.size(), range.size()); --i >= 0;) {
        final List<Dimension> dimensions = range.get(i).getDimensions();
        if (dimensions.size() != 1 || !dimensions.get(0).equals(domain.get(i))) {
            return axes;
        }
    }
    ArraysExt.reverse(axes);
    return axes;
}
 
Example 20
Source File: WriterCFPointAbstract.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 3 votes vote down vote up
/**
 * Returns a name for {@code dim} that is suitable for a shared dimension. If the dimension is anonymous, meaning
 * that its name is {@code null}, we return a default name: {@code "len" + dim.getLength()}. Otherwise, we return the
 * dimension's existing name.
 *
 * @param dim a dimension.
 * @return a name that is suitable for a shared dimension, i.e. not {@code null}.
 */
private String getSharedDimName(Dimension dim) {
  if (dim.getShortName() == null) { // Dim is anonymous.
    return "len" + dim.getLength();
  } else {
    return dim.getShortName();
  }
}