cdm/src/main/java/ucar/nc2/ft/point/standard/plug/CFpointObs.java
protected boolean identifyRaggeds(NetcdfDataset ds, EncodingInfo info, Dimension instanceDim, Dimension sampleDim, Formatter errlog) {

    // check for contiguous
    Evaluator.VarAtt varatt = Evaluator.findVariableWithAttribute(ds, CF.SAMPLE_DIMENSION);   // CF 1.6
    if (varatt == null) varatt = Evaluator.findVariableWithAttribute(ds, CF.RAGGED_ROWSIZE);  // backwards compatibility
    if (varatt != null) {
      Variable ragged_rowSize = varatt.var;
      String sampleDimName = varatt.att.getStringValue();

      if (sampleDim != null && !sampleDimName.equals(sampleDim.getShortName())) {
        errlog.format("CFpointObs: Contiguous ragged array representation: row_size variable has sample dimension %s must be %s%n", sampleDimName, sampleDim.getShortName());
        return false;
      }

      if (sampleDim == null) {
        sampleDim = ds.findDimension(sampleDimName);
        if (sampleDim == null) {
          errlog.format("CFpointObs: Contiguous ragged array representation: row_size variable has invalid sample dimension %s%n", sampleDimName);
          return false;
        }
      }

      Dimension rrDim;
      if (ragged_rowSize.getRank() > 0)
        rrDim = ragged_rowSize.getDimension(0); // nobs(station)
      else if (ragged_rowSize.getParentStructure() != null) {
        Structure parent = ragged_rowSize.getParentStructure(); // if ragged_rowSize is a structure member, use dimension of parent structure
        rrDim = parent.getDimension(0);
      } else {
        errlog.format("CFpointObs: Contiguous ragged array representation: row_size variable (%s) must have rank 1%n", ragged_rowSize);
        return false;
      }

      if (instanceDim != null && instanceDim != rrDim) {
          errlog.format("CFpointObs: Contiguous ragged array representation: row_size variable has invalid instance dimension %s must be %s%n", rrDim, instanceDim);
          return false;
      }
      instanceDim = rrDim;

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

      info.set(Encoding.raggedContiguous, instanceDim, sampleDim);
      info.ragged_rowSize = ragged_rowSize;
      info.parentStruct = ragged_rowSize.getParentStructure();
      return true;
    }  // rowsize was found

    varatt = Evaluator.findVariableWithAttribute(ds, CF.INSTANCE_DIMENSION);                       // CF 1.6
    if (varatt == null) varatt = Evaluator.findVariableWithAttribute(ds, CF.RAGGED_PARENTINDEX);   // backwards compatibility
    if (varatt != null) {
      Variable ragged_parentIndex = varatt.var;
      String instanceDimName = varatt.att.getStringValue();

      if (instanceDim != null && !instanceDimName.equals(instanceDim.getShortName())) {
        errlog.format("CFpointObs: Indexed ragged array representation: parent_index variable has instance dimension %s must be %s%n", instanceDimName, instanceDim.getShortName());
        return false;
      }

      if (instanceDim == null) {
        instanceDim = ds.findDimension(instanceDimName);
        if (instanceDim == null) {
          errlog.format("CFpointObs: Indexed ragged array representation: parent_index variable has invalid instance dimension %s%n", 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;
      }

      // allow netcdf-4 structures, eg kunicki
      if (ragged_parentIndex.isMemberOfStructure()) {
        Structure s = ragged_parentIndex.getParentStructure();
        if (s.getRank() == 0 || !s.getDimension(0).equals(sampleDim)) {
          errlog.format("CFpointObs: Indexed ragged array representation (structure): parent_index variable must be of form Struct { %s }(%s) %n", ragged_parentIndex.getFullName(), sampleDim.getShortName());
          return false;
        }

      } else {
        if (ragged_parentIndex.getRank() != 1 || !ragged_parentIndex.getDimension(0).equals(sampleDim)) {
          errlog.format("CFpointObs: Indexed ragged array representation: parent_index variable must be of form %s(%s) %n", ragged_parentIndex.getFullName(), sampleDim.getShortName());
          return false;
        }
      }
      info.set(Encoding.raggedIndex, instanceDim, sampleDim);
      info.ragged_parentIndex = ragged_parentIndex;
      info.childStruct = ragged_parentIndex.getParentStructure();
      return true;
    } // parent index was found

    /* kunicki 10/21/2011
    Variable ragged_parentIndex = Evaluator.getVariableWithAttributeValue(ds, CF.RAGGED_PARENTINDEX, parentDim.getShortName());
    if ((ragged_parentIndex == null) ||
            (!ragged_parentIndex.isMemberOfStructure() && (ragged_parentIndex.getRank() == 0 || ragged_parentIndex.getDimension(0).getShortName() != childDim.getShortName()) ||
                    (ragged_parentIndex.isMemberOfStructure() && (ragged_parentIndex.getParentStructure().getRank() == 0 || ragged_parentIndex.getParentStructure().getDimension(0).getShortName() != childDim.getShortName())))
            ) {
      // if ((null == ragged_parentIndex) || (ragged_parentIndex.getRank() == 0) || (ragged_parentIndex.getDimension(0).getShortName() != childDim.getShortName())) {
      errlog.format("there must be a ragged_parent_index variable with outer dimension that matches obs dimension %s%n", childDim.getShortName());
      return null;
    }  */

    return false;
  }
protected boolean identifyRaggeds(NetcdfDataset ds, EncodingInfo info, Dimension instanceDim, Dimension sampleDim, Formatter errlog) {

    // check for contiguous
    Evaluator.VarAtt varatt = Evaluator.findVariableWithAttribute(ds, CF.SAMPLE_DIMENSION);   // CF 1.6
    if (varatt == null) varatt = Evaluator.findVariableWithAttribute(ds, CF.RAGGED_ROWSIZE);  // backwards compatibility
    if (varatt != null) {
      Variable ragged_rowSize = varatt.var;
      String sampleDimName = varatt.att.getStringValue();

      if (sampleDim != null && !sampleDimName.equals(sampleDim.getShortName())) {
        errlog.format("CFpointObs: Contiguous ragged array representation: row_size variable has sample dimension %s must be %s%n", sampleDimName, sampleDim.getShortName());
        return false;
      }

      if (sampleDim == null) {
        sampleDim = ds.findDimension(sampleDimName);
        if (sampleDim == null) {
          errlog.format("CFpointObs: Contiguous ragged array representation: row_size variable has invalid sample dimension %s%n", sampleDimName);
          return false;
        }
      }

      Dimension rrDim;
      if (ragged_rowSize.getRank() > 0)
        rrDim = ragged_rowSize.getDimension(0); // nobs(station)
      else if (ragged_rowSize.getParentStructure() != null) {
        Structure parent = ragged_rowSize.getParentStructure(); // if ragged_rowSize is a structure member, use dimension of parent structure
        rrDim = parent.getDimension(0);
      } else {
        errlog.format("CFpointObs: Contiguous ragged array representation: row_size variable (%s) must have rank 1%n", ragged_rowSize);
        return false;
      }

      if (instanceDim != null && instanceDim != rrDim) {
          errlog.format("CFpointObs: Contiguous ragged array representation: row_size variable has invalid instance dimension %s must be %s%n", rrDim, instanceDim);
          return false;
      }
      instanceDim = rrDim;

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

      info.set(Encoding.raggedContiguous, instanceDim, sampleDim);
      info.ragged_rowSize = ragged_rowSize;
      info.parentStruct = ragged_rowSize.getParentStructure();
      return true;
    }  // rowsize was found

    varatt = Evaluator.findVariableWithAttribute(ds, CF.INSTANCE_DIMENSION);                       // CF 1.6
    if (varatt == null) varatt = Evaluator.findVariableWithAttribute(ds, CF.RAGGED_PARENTINDEX);   // backwards compatibility
    if (varatt != null) {
      Variable ragged_parentIndex = varatt.var;
      String instanceDimName = varatt.att.getStringValue();

      if (instanceDim != null && !instanceDimName.equals(instanceDim.getShortName())) {
        errlog.format("CFpointObs: Indexed ragged array representation: parent_index variable has instance dimension %s must be %s%n", instanceDimName, instanceDim.getShortName());
        return false;
      }

      if (instanceDim == null) {
        instanceDim = ds.findDimension(instanceDimName);
        if (instanceDim == null) {
          errlog.format("CFpointObs: Indexed ragged array representation: parent_index variable has invalid instance dimension %s%n", 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;
      }

      // allow netcdf-4 structures, eg kunicki
      if (ragged_parentIndex.isMemberOfStructure()) {
        Structure s = ragged_parentIndex.getParentStructure();
        if (s.getRank() == 0 || !s.getDimension(0).equals(sampleDim)) {
          errlog.format("CFpointObs: Indexed ragged array representation (structure): parent_index variable must be of form Struct { %s }(%s) %n", ragged_parentIndex.getFullName(), sampleDim.getShortName());
          return false;
        }

      } else {
        if (ragged_parentIndex.getRank() != 1 || !ragged_parentIndex.getDimension(0).equals(sampleDim)) {
          errlog.format("CFpointObs: Indexed ragged array representation: parent_index variable must be of form %s(%s) %n", ragged_parentIndex.getFullName(), sampleDim.getShortName());
          return false;
        }
      }
      info.set(Encoding.raggedIndex, instanceDim, sampleDim);
      info.ragged_parentIndex = ragged_parentIndex;
      info.childStruct = ragged_parentIndex.getParentStructure();
      return true;
    } // parent index was found

    /* kunicki 10/21/2011
    Variable ragged_parentIndex = Evaluator.getVariableWithAttributeValue(ds, CF.RAGGED_PARENTINDEX, parentDim.getShortName());
    if ((ragged_parentIndex == null) ||
            (!ragged_parentIndex.isMemberOfStructure() && (ragged_parentIndex.getRank() == 0 || ragged_parentIndex.getDimension(0).getShortName() != childDim.getShortName()) ||
                    (ragged_parentIndex.isMemberOfStructure() && (ragged_parentIndex.getParentStructure().getRank() == 0 || ragged_parentIndex.getParentStructure().getDimension(0).getShortName() != childDim.getShortName())))
            ) {
      // if ((null == ragged_parentIndex) || (ragged_parentIndex.getRank() == 0) || (ragged_parentIndex.getDimension(0).getShortName() != childDim.getShortName())) {
      errlog.format("there must be a ragged_parent_index variable with outer dimension that matches obs dimension %s%n", childDim.getShortName());
      return null;
    }  */

    return false;
  }
Identify ragged array representations for single nests (station, profile, trajectory)

@param ds          in this dataset
@param info        put info here
@param instanceDim the instance dimension, null if not known yet
@param sampleDim   the sample dimension, null if not known yet
@param errlog      error go here
@return true if ragged array representations is found; side effect: set (info.ragged_rowSize, info.parentStruct) or (info.ragged_parentIndex, info.childStruct)