Java Code Examples for ucar.nc2.Variable#getRank()

The following examples show how to use ucar.nc2.Variable#getRank() . 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: UnidataStationObsMultidimDataset.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private Array readData(Variable v, int stationIndex, int obsIndex) throws IOException {
  int[] shape = v.getShape();
  int[] origin = new int[v.getRank()];
  origin[0] = stationIndex;
  origin[1] = obsIndex;
  shape[0] = 1;
  shape[1] = 1;

  Array data = null;
  try {
    data = v.read(origin, shape);
  } catch (InvalidRangeException e) {
    throw new IllegalStateException(e.getMessage());
  }
  return data;
}
 
Example 2
Source File: WRFEta.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * Extract an Array (with rank reduced by one) from the Variable
 * for the given time index.
 *
 * @param v variable to extract from
 * @param timeIndex time index
 * @return Array of data
 * @throws IOException problem getting Array
 */
private Array getTimeSlice(Variable v, int timeIndex) throws IOException {
  // ADD: this would make a good utility method
  // ADD: use Array.slice?
  int[] shape = v.getShape();
  int[] origin = new int[v.getRank()];

  if (getTimeDimension() != null) {
    int dimIndex = v.findDimensionIndex(getTimeDimension().getShortName());
    if (dimIndex >= 0) {
      shape[dimIndex] = 1;
      origin[dimIndex] = timeIndex;
    }
  }

  try {
    return v.read(origin, shape).reduce();
  } catch (InvalidRangeException e) {
    throw new IOException(e);
  }
}
 
Example 3
Source File: NetcdfFormatWriter.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * Write String data to a CHAR variable.
 *
 * @param v variable to write to
 * @param origin offset to start writing, ignore the strlen dimension.
 * @param values write this array; must be ArrayObject of String
 * @throws IOException if I/O error
 * @throws InvalidRangeException if values Array has illegal shape
 */
public void writeStringDataToChar(Variable v, int[] origin, Array values) throws IOException, InvalidRangeException {
  if (values.getElementType() != String.class)
    throw new IllegalArgumentException("values must be an ArrayObject of String ");

  if (v.getDataType() != DataType.CHAR)
    throw new IllegalArgumentException("variable " + v.getFullName() + " is not type CHAR");

  int rank = v.getRank();
  int strlen = v.getShape(rank - 1);

  // turn it into an ArrayChar
  ArrayChar cvalues = ArrayChar.makeFromStringArray((ArrayObject) values, strlen);

  int[] corigin = new int[rank];
  System.arraycopy(origin, 0, corigin, 0, rank - 1);

  write(v, corigin, cvalues);
}
 
Example 4
Source File: WRFConvention.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private VariableDS.Builder<?> removeConstantTimeDim(Variable.Builder<?> vb) {
  VariableDS.Builder<?> vds = (VariableDS.Builder<?>) vb;
  Variable v = vds.orgVar;
  int[] shape = v.getShape();
  if (v.getRank() == 3 && shape[0] == 1) { // remove time dependencies - TODO MAJOR KLUDGE
    Variable view;
    try {
      view = v.slice(0, 0);
    } catch (InvalidRangeException e) {
      parseInfo.format("Cant remove first dimension in variable %s", v);
      return vds;
    }
    // TODO test that this works
    VariableDS.Builder<?> vbnew = VariableDS.builder().copyFrom(view);
    rootGroup.replaceVariable(vbnew);
    return vbnew;
  }
  return vds;
}
 
Example 5
Source File: NsslRadialAdapter.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
protected void addRadialVariable(NetcdfDataset nds, Variable var) {
  RadialVariable rsvar = null;
  int rnk = var.getRank();

  setIsVolume(nds);

  if (isVolume && rnk == 3) {
    rsvar = makeRadialVariable(nds, var);
  } else if (!isVolume && rnk == 2) {
    rsvar = makeRadialVariable(nds, var);
  }

  if (rsvar != null)
    dataVariables.add(rsvar);
}
 
Example 6
Source File: Evaluator.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Find structure variable of rank 2 with the 2 given dimensions
 * (or) Find structure variable of rank 1 with the 1 given dimension
 * 
 * @param ds in this dataset
 * @param dim0 first dimension
 * @param dim1 second dimension (ok to be null)
 * @return structure variable or null
 */
public static Structure findStructureWithDimensions(NetcdfDataset ds, Dimension dim0, Dimension dim1) {
  for (Variable v : ds.getVariables()) {
    if (!(v instanceof Structure))
      continue;

    if (dim1 != null && v.getRank() == 2 && v.getDimension(0).equals(dim0) && v.getDimension(1).equals(dim1))
      return (Structure) v;

    if (dim1 == null && v.getRank() == 1 && v.getDimension(0).equals(dim0))
      return (Structure) v;
  }
  return null;
}
 
Example 7
Source File: FslWindProfiler.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private void makeMultidimInner(NetcdfDataset ds, TableConfig parentTable, TableConfig childTable, String outerDin,
    String innerDim) {
  Dimension parentDim = ds.findDimension(outerDin);
  Dimension childDim = ds.findDimension(innerDim);

  // divide up the variables between the parent and the child
  List<String> obsVars;
  List<Variable> vars = ds.getVariables();
  List<String> parentVars = new ArrayList<>(vars.size());
  obsVars = new ArrayList<>(vars.size());
  for (Variable orgV : vars) {
    if (orgV instanceof Structure)
      continue;

    Dimension dim0 = orgV.getDimension(0);
    if ((dim0 != null) && dim0.equals(parentDim)) {
      if ((orgV.getRank() == 1) || ((orgV.getRank() == 2) && orgV.getDataType() == DataType.CHAR)) {
        parentVars.add(orgV.getShortName());
      } else {
        Dimension dim1 = orgV.getDimension(1);
        if ((dim1 != null) && dim1.equals(childDim))
          obsVars.add(orgV.getShortName());
      }
    }
  }
  parentTable.vars = parentVars;
  childTable.vars = obsVars;
}
 
Example 8
Source File: Nc4ChunkingStrategyGrib.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private int[] computeChunkingGrib(Variable v) {
  int n = v.getRank();
  int[] result = new int[n];
  if (n < 2) {
    result[0] = 1; // Unlimited variable with rank 1

  } else {
    for (int i = 0; i < n; i++)
      result[i] = (i < n - 2) ? 1 : v.getDimension(i).getLength();
  }
  return result;
}
 
Example 9
Source File: Nc4ChunkingStrategyGrib.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
@Override
public boolean isChunked(Variable v) {
  if (v.isUnlimited())
    return true;
  // if (getChunkAttribute(v) != null) return true;

  int n = v.getRank();
  return n >= 2 && v.getSize() * v.getElementSize() > getMinVariableSize();
}
 
Example 10
Source File: IFPSConvention.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public void augmentDataset(NetcdfDataset ds, CancelTask cancelTask) throws IOException {
  if (null != ds.findVariable("xCoord"))
    return; // check if its already been done - aggregating enhanced datasets.

  parseInfo.format("IFPS augmentDataset %n");

  // Figure out projection info. Assume the same for all variables
  VariableDS lonVar = (VariableDS) ds.findVariable("longitude");
  lonVar.setUnitsString(CDM.LON_UNITS);
  lonVar.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lon.toString()));
  VariableDS latVar = (VariableDS) ds.findVariable("latitude");
  latVar.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lat.toString()));
  latVar.setUnitsString(CDM.LAT_UNITS);

  projVar = latVar;
  String projName = ds.findAttValueIgnoreCase(projVar, "projectionType", null);
  if ("LAMBERT_CONFORMAL".equals(projName)) {
    Projection proj = makeLCProjection(ds);
    makeXYcoords(ds, proj, latVar, lonVar);
  }

  // figure out the time coordinate for each data variable
  // LOOK : always seperate; could try to discover if they are the same
  List<Variable> vars = ds.getVariables();
  for (Variable ncvar : vars) {
    // variables that are used but not displayable or have no data have DIM_0, also don't want history, since those
    // are just how the person edited the grids
    if ((!ncvar.getDimension(0).getShortName().equals("DIM_0")) && !ncvar.getShortName().endsWith("History")
        && (ncvar.getRank() > 2) && !ncvar.getShortName().startsWith("Tool")) {
      createTimeCoordinate(ds, ncvar);
    } else if (ncvar.getShortName().equals("Topo")) {
      // Deal with Topography variable
      ncvar.addAttribute(new Attribute(CDM.LONG_NAME, "Topography"));
      ncvar.addAttribute(new Attribute(CDM.UNITS, "ft"));
    }
  }

  ds.finish();
}
 
Example 11
Source File: Nc4ChunkingStrategy.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
protected int[] computeChunkingFromAttribute(Variable v) {
  Attribute att = getChunkAttribute(v); // use CHUNK_SIZES attribute if it exists
  if (att != null) {
    int[] result = new int[v.getRank()];
    for (int i = 0; i < v.getRank(); i++)
      result[i] = att.getNumericValue(i).intValue();
    return result;
  }

  return null;
}
 
Example 12
Source File: FslRaob.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private void makeMultidimInner(NetcdfDataset ds, TableConfig parentTable, TableConfig childTable, String outerDin,
    String innerDim) {
  Dimension parentDim = ds.findDimension(outerDin);
  Dimension childDim = ds.findDimension(innerDim);

  // divide up the variables between the parent and the child
  List<String> obsVars;
  List<Variable> vars = ds.getVariables();
  List<String> parentVars = new ArrayList<>(vars.size());
  obsVars = new ArrayList<>(vars.size());
  for (Variable orgV : vars) {
    if (orgV instanceof Structure)
      continue;

    Dimension dim0 = orgV.getDimension(0);
    if ((dim0 != null) && dim0.equals(parentDim)) {
      if ((orgV.getRank() == 1) || ((orgV.getRank() == 2) && orgV.getDataType() == DataType.CHAR)) {
        parentVars.add(orgV.getShortName());
      } else {
        Dimension dim1 = orgV.getDimension(1);
        if ((dim1 != null) && dim1.equals(childDim))
          obsVars.add(orgV.getShortName());
      }
    }
  }
  parentTable.vars = parentVars;
  childTable.vars = obsVars;
}
 
Example 13
Source File: Dorade2RadialAdapter.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private Dorade2Variable(NetcdfDataset nds, Variable v0) {
  super(v0.getShortName(), v0);
  sweeps = new ArrayList<>();

  int[] shape = v0.getShape();
  int count = v0.getRank() - 1;

  int ngates = shape[count];
  count--;
  int nrays = shape[count];

  sweeps.add(new Dorade2Sweep(v0, 0, nrays, ngates));
}
 
Example 14
Source File: PointConfigXML.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private void makeMultidimInner(NetcdfDataset ds, TableConfig parentTable, TableConfig childTable) {
  Dimension parentDim = ds.findDimension(parentTable.dimName);
  Dimension childDim = ds.findDimension(childTable.innerName);

  // divide up the variables between the parent and the child
  List<String> obsVars;
  List<Variable> vars = ds.getVariables();
  List<String> parentVars = new ArrayList<>(vars.size());
  obsVars = new ArrayList<>(vars.size());
  for (Variable orgV : vars) {
    if (orgV instanceof Structure)
      continue;

    Dimension dim0 = orgV.getDimension(0);
    if ((dim0 != null) && dim0.equals(parentDim)) {
      if ((orgV.getRank() == 1) || ((orgV.getRank() == 2) && orgV.getDataType() == DataType.CHAR)) {
        parentVars.add(orgV.getShortName());
      } else {
        Dimension dim1 = orgV.getDimension(1);
        if ((dim1 != null) && dim1.equals(childDim))
          obsVars.add(orgV.getShortName());
      }
    }
  }
  parentTable.vars = parentVars;
  childTable.vars = obsVars;
}
 
Example 15
Source File: NidsRadialAdapter.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private Nids2Variable(NetcdfDataset nds, Variable v0) {
  super(v0.getShortName(), v0);
  sweeps = new ArrayList<>();

  int[] shape = v0.getShape();
  int count = v0.getRank() - 1;

  int ngates = shape[count];
  count--;
  int nrays = shape[count];
  count--;

  sweeps.add(new Nids2Sweep(nds, v0, 0, nrays, ngates));
}
 
Example 16
Source File: NidsRadialAdapter.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
protected void addRadialVariable(NetcdfDataset nds, Variable var) {
  RadialVariable rsvar = null;
  int rnk = var.getRank();

  if (!var.getShortName().endsWith("RAW") && rnk == 2) {
    rsvar = new Nids2Variable(nds, var);
  }

  if (rsvar != null)
    dataVariables.add(rsvar);
}
 
Example 17
Source File: UnidataStationObsMultidimDataset.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private Array readStationVariable(Variable svar) throws IOException {
  if (svar.getRank() == 1)
    return svar.read();
  if (svar.getRank() == 2) {
    int[] shape = svar.getShape();
    shape[1] = 1;
    try {
      return svar.read(new int[2], shape).reduce(1);
    } catch (InvalidRangeException e) {
      throw new IllegalStateException(e.getMessage());
    }
  }
  throw new IllegalStateException("Station variables must have rank 1 or 2");
}
 
Example 18
Source File: TestWriteRecord.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
@Test
public void testNC3WriteWithRecord() throws IOException, InvalidRangeException {
  String filename = tempFolder.newFile().getAbsolutePath();

  NetcdfFormatWriter.Builder writerb = NetcdfFormatWriter.createNewNetcdf3(filename).setFill(false);
  writerb.addUnlimitedDimension("time");
  Dimension latDim = writerb.addDimension("lat", 64);
  Dimension lonDim = writerb.addDimension("lon", 128);

  // define Variables

  // double T(time, lat, lon) ;
  // T:long_name="surface temperature" ;
  // T:units = "degC" ;
  writerb.addVariable("T", DataType.DOUBLE, "time lat lon")
      .addAttribute(new Attribute(CDM.LONG_NAME, "surface temperature")).addAttribute(new Attribute("units", "degC"));

  // float lat(lat) ;
  // lat:units = "degrees_north" ;
  writerb.addVariable("lat", DataType.FLOAT, "lat").addAttribute(new Attribute("units", "degrees_north"));

  // float lon(lon) ;
  // lon:units = "degrees_east" ;
  writerb.addVariable("lon", DataType.FLOAT, "lon").addAttribute(new Attribute("units", "degrees_east"));

  // int time(time) ;
  // time:units = "hours" ;
  writerb.addVariable("time", DataType.INT, "time").addAttribute(new Attribute("units", "hours"));

  // :title = "Example Data" ;
  writerb.addAttribute(new Attribute("title", "Example Data"));

  try (NetcdfFormatWriter writer = writerb.build()) {
    // now write one record at a time
    Variable v = writer.findVariable("T");
    Assert.assertNotNull(v);
    ArrayDouble data = new ArrayDouble.D3(1, latDim.getLength(), lonDim.getLength());
    ArrayInt timeData = new ArrayInt.D1(1, false);
    int[] origin = new int[v.getRank()];
    int[] timeOrigin = new int[1];

    for (int time = 0; time < 100; time++) {
      // fill the data array
      Index ima = data.getIndex();
      for (int j = 0; j < latDim.getLength(); j++) {
        for (int k = 0; k < lonDim.getLength(); k++) {
          data.setDouble(ima.set(0, j, k), (double) time * j * k);
        }
      }
      timeData.setInt(timeData.getIndex(), time);

      // write to file
      origin[0] = time;
      timeOrigin[0] = time;
      writer.write("T", origin, data);
      writer.write("time", timeOrigin, timeData);
    }
  }
}
 
Example 19
Source File: CFpointObs.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Identify ragged array representations for double nests (timeSeries profile, timeSeries trajectory)
 * <p/>
 * This uses the contiguous ragged array representation for each profile (9.5.43.3), and the indexed ragged array
 * representation to organise the profiles into time series (9.3.54). The canonical use case is when writing real-time
 * data streams that contain profiles from many stations, arriving randomly, with the data for each entire profile
 * written all at once.
 *
 * @param ds in this dataset
 * @param info put info here
 * @param errlog error go here
 * @return EncodingInfo if ragged array representations is found
 */
protected boolean identifyDoubleRaggeds(NetcdfDataset ds, EncodingInfo info, Formatter errlog) {
  // the timeseries are stored as ragged index
  Evaluator.VarAtt varatt = Evaluator.findVariableWithAttribute(ds, CF.INSTANCE_DIMENSION);
  if (varatt == null)
    varatt = Evaluator.findVariableWithAttribute(ds, CF.RAGGED_PARENTINDEX);
  if (varatt == null)
    return false;

  Variable ragged_parentIndex = varatt.var;
  String instanceDimName = varatt.att.getStringValue();
  Dimension stationDim = ds.findDimension(instanceDimName);

  if (stationDim == null) {
    errlog.format(
        "CFpointObs: Indexed ragged array representation: parent_index variable has illegal value for %s = %s%n",
        CF.INSTANCE_DIMENSION, instanceDimName);
    return false;
  }

  if (ragged_parentIndex.getDataType() != DataType.INT) {
    errlog.format("CFpointObs: Indexed ragged array representation: parent_index variable must be of type integer%n");
    return false;
  }

  if (ragged_parentIndex.getRank() != 1 && info.childStruct == null) {
    errlog.format("CFpointObs: Indexed ragged array representation: parent_index variable %s must be 1D %n",
        ragged_parentIndex);
    return false;
  }
  Dimension profileDim = (info.childDim != null) ? info.childDim : ragged_parentIndex.getDimension(0);

  // onto the profiles, stored contiguously
  varatt = Evaluator.findVariableWithAttribute(ds, CF.SAMPLE_DIMENSION);
  if (varatt == null)
    varatt = Evaluator.findVariableWithAttribute(ds, CF.RAGGED_ROWSIZE);
  if (varatt == null)
    return false;

  Variable ragged_rowSize = varatt.var;
  String obsDimName = varatt.att.getStringValue();
  Dimension obsDim = ds.findDimension(obsDimName);

  if (obsDimName == null) {
    errlog.format(
        "CFpointObs: Contiguous ragged array representation: parent_index variable has illegal value for %s = %s%n",
        CF.SAMPLE_DIMENSION, obsDimName);
    return false;
  }

  if (!obsDimName.equals(info.grandChildDim.getShortName())) {
    errlog.format(
        "CFpointObs: Contiguous ragged array representation: row_size variable has obs dimension %s must be %s%n",
        obsDimName, info.childDim);
    return false;
  }

  if (ragged_rowSize.getDataType() != DataType.INT) {
    errlog.format("CFpointObs: Contiguous ragged array representation: row_size variable must be of type integer%n");
    return false;
  }

  if (info.childDim == null) { // nc4 ext
    Dimension profileDim2 = ragged_rowSize.getDimension(0);
    if (profileDim2 != profileDim) {
      errlog.format("CFpointObs: Double ragged array representation dimensions do not agree: %s != %s%n",
          profileDim2.getShortName(), profileDim.getShortName());
      return false;
    }
  }

  info.set(Encoding.raggedIndex, stationDim, profileDim, obsDim);
  info.ragged_parentIndex = ragged_parentIndex;
  info.ragged_rowSize = ragged_rowSize;
  return true;
}
 
Example 20
Source File: UnidataStationObsMultidimDataset.java    From netcdf-java with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
public UnidataStationObsMultidimDataset(NetcdfDataset ds) throws IOException {
  super(ds);

  stationDim = UnidataObsDatasetHelper.findDimension(ds, "station");
  obsDim = UnidataObsDatasetHelper.findDimension(ds, "observation");
  if (obsDim == null)
    obsDim = ds.getUnlimitedDimension();
  if (obsDim == null)
    throw new IllegalStateException("must specify the observation dimension or use unlimited dimension");

  // coordinate variables
  latVar = UnidataObsDatasetHelper.getCoordinate(ds, AxisType.Lat);
  lonVar = UnidataObsDatasetHelper.getCoordinate(ds, AxisType.Lon);
  altVar = UnidataObsDatasetHelper.getCoordinate(ds, AxisType.Height);
  timeVar = UnidataObsDatasetHelper.getCoordinate(ds, AxisType.Time);
  timeNominalVar = UnidataObsDatasetHelper.findVariable(ds, "time_nominal");

  if (latVar == null)
    throw new IllegalStateException("Missing latitude variable");
  if (lonVar == null)
    throw new IllegalStateException("Missing longitude coordinate variable");
  if (timeVar == null)
    throw new IllegalStateException("Missing time coordinate variable");

  if (!latVar.getDimension(0).equals(stationDim))
    throw new IllegalStateException("latitude variable must use the station dimension");
  if (!lonVar.getDimension(0).equals(stationDim))
    throw new IllegalStateException("longitude variable must use the station dimension");
  if (!timeVar.getDimension(0).equals(stationDim))
    throw new IllegalStateException("time variable must use the station dimension");
  if ((altVar != null) && !altVar.getDimension(0).equals(stationDim))
    throw new IllegalStateException("altitude variable must use the station dimension");
  if ((timeNominalVar != null) && !timeNominalVar.getDimension(0).equals(stationDim))
    throw new IllegalStateException("timeNominal variable must use the station dimension");

  // station variables
  stationIdVar = UnidataObsDatasetHelper.findVariable(ds, "station_id");
  stationDescVar = UnidataObsDatasetHelper.findVariable(ds, "station_description");
  numStationsVar = UnidataObsDatasetHelper.findVariable(ds, "number_stations");

  if (stationIdVar == null)
    throw new IllegalStateException("Missing station id variable");
  if (!stationIdVar.getDimension(0).equals(stationDim))
    throw new IllegalStateException("stationId variable must use the station dimension");

  if ((stationDescVar != null) && !stationDescVar.getDimension(0).equals(stationDim))
    throw new IllegalStateException("stationDesc variable must use the station dimension");

  // create member variables
  structureMembers = new StructureMembers("UnidataStationObsMultidimDataset_obsStructure");
  for (Variable v : netcdfDataset.getVariables()) {
    if (v.getRank() < 2)
      continue;
    if (v.getDimension(0).equals(this.stationDim) && v.getDimension(1).equals(this.obsDim)) {
      dataVariables.add(v);
      int[] shape = v.getShape();
      shape[0] = 1;
      shape[1] = 1;
      structureMembers.addMember(v.getShortName(), v.getDescription(), v.getUnitsString(), v.getDataType(), shape);
    }
  }

  readStations(); // LOOK try to defer this

  // get min, max date
  startDate = UnidataObsDatasetHelper.getStartDate(ds);
  endDate = UnidataObsDatasetHelper.getEndDate(ds);
  boundingBox = UnidataObsDatasetHelper.getBoundingBox(ds);
  if (null == boundingBox)
    setBoundingBox();

  setTimeUnits();

  title = ds.findAttValueIgnoreCase(null, "title", "");
  desc = ds.findAttValueIgnoreCase(null, "description", "");
}