protected NetCdfVariable(NetCDFDataSet dataSet, int varid, string name, string[] dims, bool assignID) : base(dataSet, name, dims, assignID) { this.initializing = true; this.varid = varid; int res; // SByte can map to NC_BYTE or NC_CHAR if (typeof(DataType) == typeof(byte)) { res = NetCDF.nc_inq_vartype(dataSet.NcId, varid, out var nativeType); NetCDFDataSet.HandleResult(res); isNcChar = NcType.NC_CHAR == nativeType; } UpdateDimIds(); // Reading attributes int nattrs; res = NetCDF.nc_inq_varnatts(dataSet.NcId, varid, out nattrs); AttributeTypeMap atm = new AttributeTypeMap(dataSet.NcId, varid); NetCDFDataSet.HandleResult(res); for (int i = 0; i < nattrs; i++) { // Name string aname; res = NetCDF.nc_inq_attname(dataSet.NcId, varid, i, out aname); NetCDFDataSet.HandleResult(res); // Skip out internal attribute if (aname == AttributeTypeMap.AttributeName || aname == AttributeTypeMap.AttributeVarSpecialType) { continue; } if (aname == AttributeTypeMap.AttributeVarActualShape) { isPresentedAttrActualShape = true; continue; } // Type object value = dataSet.ReadNetCdfAttribute(varid, aname, atm); if (aname == Metadata.KeyForMissingValue && typeof(DateTime) == typeof(DataType)) { if (value is string) { value = DateTime.Parse((string)value); } } Metadata[aname] = value; } Initialize(); initializing = false; }
/// <summary> /// /// </summary> /// <returns></returns> protected override int[] ReadShape() { if (initializing) { return(null); } int res; IntPtr len; int[] shape = new int[dimids.Length]; for (int i = 0; i < dimids.Length; i++) { res = NetCDF.nc_inq_dimlen(NcId, dimids[i], out len); NetCDFDataSet.HandleResult(res); shape[i] = (int)len; } if (isPresentedAttrActualShape) { // Actual shape of the variable is in the special attribute // for the NetCDF doesn't support variables like A[0,10] NetCDFDataSet nc = ((NetCDFDataSet)DataSet); NcType type; res = NetCDF.nc_inq_atttype(nc.NcId, varid, AttributeTypeMap.AttributeVarActualShape, out type); if (res == (int)ResultCode.NC_NOERR) { if (type != NcType.NC_INT) { throw new NetCDFException("Reserved attribute " + AttributeTypeMap.AttributeVarActualShape + " has wrong type"); } AttributeTypeMap atm = new AttributeTypeMap(nc.NcId, varid); atm[AttributeTypeMap.AttributeVarActualShape] = typeof(int[]); shape = (int[])nc.ReadNetCdfAttribute(varid, AttributeTypeMap.AttributeVarActualShape, atm); if (shape.Length != Rank) { throw new NetCDFException("Value of reserved attribute " + AttributeTypeMap.AttributeVarActualShape + " has wrong length"); } } else if (res != (int)ResultCode.NC_ENOTATT) { NetCDFDataSet.HandleResult(res); } } return(shape); }
/// <summary> /// /// </summary> /// <param name="proposedChanges"></param> internal protected override void OnPrecommit(Variable.Changes proposedChanges) { NetCDF.nc_enddef(NcId); base.OnPrecommit(proposedChanges); if (((NetCDFDataSet)DataSet).Initializing) { return; } NetCDF.nc_redef(NcId); NetCDFDataSet dataSet = (NetCDFDataSet)this.DataSet; AttributeTypeMap atm = new AttributeTypeMap(dataSet.NcId, varid); /* Updating attributes in the netCDF file */ foreach (var item in proposedChanges.MetadataChanges) { dataSet.WriteNetCdfAttribute(varid, item.Key, item.Value, atm); } // NetCDF doesn't supports storing of arrays of kind A[x:0, y:10] // so we keep this actual shape in the reserved attribute. if (Rank > 1) { int min, max; GetMinMax(proposedChanges.Shape, out min, out max); if (min == 0 && max > 0) { dataSet.WriteNetCdfAttribute(varid, AttributeTypeMap.AttributeVarActualShape, proposedChanges.Shape, atm); isPresentedAttrActualShape = true; } else if (isPresentedAttrActualShape) { NetCDF.nc_del_att(NcId, varid, AttributeTypeMap.AttributeVarActualShape); isPresentedAttrActualShape = false; } } atm.Store(); /* Saving attached coordinate systems as "coordinates" attributes. * Common netCDF model supports for only one such attribute, * so all others CS except first are not compatible with that model. * Their attribute names are "coordinates2","coordinates3" etc. * Names of coordinate systems are provided with corresponed * attributes "coordinatesName","coordinates2Name",... */ if (proposedChanges.CoordinateSystems != null) { int n = proposedChanges.InitialSchema.CoordinateSystems.Length; foreach (var cs in proposedChanges.CoordinateSystems) { if (Array.Exists(proposedChanges.InitialSchema.CoordinateSystems, css => css == cs.Name)) { continue; } // This CS has been added. string name = "coordinates"; if (n > 0) { name += n.ToString(); } n++; StringBuilder sb = new StringBuilder(); bool first = true; foreach (Variable axis in cs.Axes) { if (!first) { sb.Append(' '); } else { first = false; } sb.Append(axis.Name); } dataSet.WriteNetCdfAttribute(varid, name, sb.ToString(), null); dataSet.WriteNetCdfAttribute(varid, name + "Name", cs.Name, null); } } }