cdm/src/main/java/ucar/nc2/dataset/conv/CF1Convention.java
protected AxisType getAxisType(NetcdfDataset ncDataset, VariableEnhanced v) {

     // standard names for unitless vertical coords
    String sname = ncDataset.findAttValueIgnoreCase((Variable) v, CF.STANDARD_NAME, null);
    if (sname != null) {
      sname = sname.trim();

      for (String vertical_coord : vertical_coords)
        if (sname.equalsIgnoreCase(vertical_coord))
          return AxisType.GeoZ;
    }

    // COARDS - check units
    AxisType at = super.getAxisType(ncDataset, v);
    if (at != null) return at;

    // standard names for X, Y : bug in CDO putting wrong standard name, so check units first (!)
    if (sname != null) {
      if (sname.equalsIgnoreCase(CF.ENSEMBLE))
        return AxisType.Ensemble;

      if (sname.equalsIgnoreCase(CF.LATITUDE))
        return AxisType.Lat;

      if (sname.equalsIgnoreCase(CF.LONGITUDE))
        return AxisType.Lon;

      if (sname.equalsIgnoreCase(CF.PROJECTION_X_COORDINATE) || sname.equalsIgnoreCase(CF.GRID_LONGITUDE) || sname.equalsIgnoreCase("rotated_longitude"))
        return AxisType.GeoX;

      if (sname.equalsIgnoreCase(CF.PROJECTION_Y_COORDINATE) || sname.equalsIgnoreCase(CF.GRID_LATITUDE) || sname.equalsIgnoreCase("rotated_latitude"))
        return AxisType.GeoY;

      if (sname.equalsIgnoreCase(CF.TIME_REFERENCE))
        return AxisType.RunTime;

      if (sname.equalsIgnoreCase(CF.TIME_OFFSET))
        return AxisType.TimeOffset;
    }

    // check axis attribute - only for X, Y, Z
    String axis = ncDataset.findAttValueIgnoreCase((Variable) v, CF.AXIS, null);
    if (axis != null) {
      axis = axis.trim();
      String unit = v.getUnitsString();

      if (axis.equalsIgnoreCase("X")) {
        if (SimpleUnit.isCompatible("m", unit))
          return AxisType.GeoX;

      } else if (axis.equalsIgnoreCase("Y")) {
        if (SimpleUnit.isCompatible("m", unit))
          return AxisType.GeoY;

      } else if (axis.equalsIgnoreCase("Z")) {
        if (unit == null) return AxisType.GeoZ;
        if (SimpleUnit.isCompatible("m", unit))
          return AxisType.Height;
        else if (SimpleUnit.isCompatible("mbar", unit))
          return AxisType.Pressure;
        else
          return AxisType.GeoZ;
      }
    }

    if (avhrr_oiv2) {
      if (v.getShortName().equals("zlev"))
        return AxisType.Height;
    }

    try {
      String units = v.getUnitsString();
      CalendarDateUnit cd = CalendarDateUnit.of(null, units);
      if (cd != null) return AxisType.Time;
    } catch (Throwable t) {
      // ignore
    }

    return null;
  }
protected AxisType getAxisType(NetcdfDataset ncDataset, VariableEnhanced v) {

     // standard names for unitless vertical coords
    String sname = ncDataset.findAttValueIgnoreCase((Variable) v, CF.STANDARD_NAME, null);
    if (sname != null) {
      sname = sname.trim();

      for (String vertical_coord : vertical_coords)
        if (sname.equalsIgnoreCase(vertical_coord))
          return AxisType.GeoZ;
    }

    // COARDS - check units
    AxisType at = super.getAxisType(ncDataset, v);
    if (at != null) return at;

    // standard names for X, Y : bug in CDO putting wrong standard name, so check units first (!)
    if (sname != null) {
      if (sname.equalsIgnoreCase(CF.ENSEMBLE))
        return AxisType.Ensemble;

      if (sname.equalsIgnoreCase(CF.LATITUDE))
        return AxisType.Lat;

      if (sname.equalsIgnoreCase(CF.LONGITUDE))
        return AxisType.Lon;

      if (sname.equalsIgnoreCase(CF.PROJECTION_X_COORDINATE) || sname.equalsIgnoreCase(CF.GRID_LONGITUDE) || sname.equalsIgnoreCase("rotated_longitude"))
        return AxisType.GeoX;

      if (sname.equalsIgnoreCase(CF.PROJECTION_Y_COORDINATE) || sname.equalsIgnoreCase(CF.GRID_LATITUDE) || sname.equalsIgnoreCase("rotated_latitude"))
        return AxisType.GeoY;

      if (sname.equalsIgnoreCase(CF.TIME_REFERENCE))
        return AxisType.RunTime;

      if (sname.equalsIgnoreCase(CF.TIME_OFFSET))
        return AxisType.TimeOffset;
    }

    // check axis attribute - only for X, Y, Z
    String axis = ncDataset.findAttValueIgnoreCase((Variable) v, CF.AXIS, null);
    if (axis != null) {
      axis = axis.trim();
      String unit = v.getUnitsString();

      if (axis.equalsIgnoreCase("X")) {
        if (SimpleUnit.isCompatible("m", unit))
          return AxisType.GeoX;

      } else if (axis.equalsIgnoreCase("Y")) {
        if (SimpleUnit.isCompatible("m", unit))
          return AxisType.GeoY;

      } else if (axis.equalsIgnoreCase("Z")) {
        if (unit == null) return AxisType.GeoZ;
        if (SimpleUnit.isCompatible("m", unit))
          return AxisType.Height;
        else if (SimpleUnit.isCompatible("mbar", unit))
          return AxisType.Pressure;
        else
          return AxisType.GeoZ;
      }
    }

    if (avhrr_oiv2) {
      if (v.getShortName().equals("zlev"))
        return AxisType.Height;
    }

    try {
      String units = v.getUnitsString();
      CalendarDateUnit cd = CalendarDateUnit.of(null, units);
      if (cd != null) return AxisType.Time;
    } catch (Throwable t) {
      // ignore
    }

    return null;
  }
Augment COARDS axis type identification with Standard names (including dimensionless vertical coordinates) and  CF.AXIS attributes