internal static NetCdfVariable <DataType> Create(NetCDFDataSet dataSet, string name, string[] dims) { if (dims == null) // scalar variable { dims = new string[0]; } int res; /* Getting exsting dims and creating new */ int[] dimids = new int[dims.Length]; for (int i = 0; i < dims.Length; i++) { int id; res = NetCDF.nc_inq_dimid(dataSet.NcId, dims[i], out id); if (res == (int)ResultCode.NC_NOERR) { dimids[i] = id; } else if (res == (int)ResultCode.NC_EBADDIM) { // Creating new dimension res = NetCDF.nc_def_dim(dataSet.NcId, dims[i], new IntPtr(NcConst.NC_UNLIMITED), out id); NetCDFDataSet.HandleResult(res); dimids[i] = id; } else { NetCDFDataSet.HandleResult(res); } } /* Creating variable */ int varid; string nc_name = GetNetCDFName(name); if (nc_name != name) { Debug.WriteLineIf(NetCDFDataSet.TraceNetCDFDataSet.TraceVerbose, "NetCDF: name has illegal chars; internal variable name is " + nc_name); } res = NetCDF.nc_def_var(dataSet.NcId, nc_name, NetCDF.GetNcType(typeof(DataType)), dimids, out varid); for (int count = 1; res == (int)ResultCode.NC_ENAMEINUSE;) { // Keep trying to create variable with different names res = NetCDF.nc_def_var(dataSet.NcId, String.Format("{0}_{1}", nc_name, count++), NetCDF.GetNcType(typeof(DataType)), dimids, out varid); } NetCDFDataSet.HandleResult(res); // Non scalar variables can be compressed. // It is regulated by the uri parameter "deflate". if (dims.Length > 0) { if (dataSet.Deflate == DeflateLevel.Off) { res = NetCDF.nc_def_var_deflate(dataSet.NcId, varid, 0, 0, 0); } else { res = NetCDF.nc_def_var_deflate(dataSet.NcId, varid, 0, 1, (int)dataSet.Deflate); } NetCDFDataSet.HandleResult(res); } if (dims.Length > 0) // non-scalar variable { IntPtr[] chunksizes = null; if (dataSet.ChunkSizes != null && dataSet.ChunkSizes.Length == dims.Length) { if (dataSet.ChunkSizes.All(sz => sz >= 1)) { chunksizes = dataSet.ChunkSizes.Select(sz => new IntPtr(sz)).ToArray(); } else { throw new NotSupportedException("Chunk size cannot be less than 1"); } } if (chunksizes == null) // then use default chunk sizes { chunksizes = new IntPtr[dims.Length]; int chunk = ChunkSizeSelector.GetChunkSize(typeof(DataType), dims.Length); #if DEBUG if (NetCDFDataSet.TraceNetCDFDataSet.TraceInfo) { StringBuilder sbChunk = new StringBuilder(); sbChunk.Append("NetCDF: Chunk sizes for rank ").Append(dims.Length).Append(": "); for (int i = 0; i < dims.Length; i++) { sbChunk.Append(chunk).Append(","); } Debug.WriteLineIf(NetCDFDataSet.TraceNetCDFDataSet.TraceInfo, sbChunk.ToString()); } #endif for (int i = 0; i < dims.Length; i++) { chunksizes[i] = new IntPtr(chunk); } } res = NetCDF.nc_def_var_chunking(dataSet.NcId, varid, 0, chunksizes); NetCDFDataSet.HandleResult(res); } if (typeof(DataType) == typeof(DateTime)) { NetCDFDataSet.NcPutAttText(dataSet.NcId, varid, "Units", NetCDFDataSet.dateTimeUnits); } else if (typeof(DataType) == typeof(bool)) { NetCDFDataSet.NcPutAttText(dataSet.NcId, varid, AttributeTypeMap.AttributeVarSpecialType, typeof(bool).ToString()); } return(new NetCdfVariable <DataType>(dataSet, varid, name, dims)); }
internal static NetCdfVariable <DataType> Create(NetCDFDataSet dataSet, string name, string[] dims) { if (dims == null) // scalar variable { dims = new string[0]; } int res; /* Getting exsting dims and creating new */ int[] dimids = new int[dims.Length]; for (int i = 0; i < dims.Length; i++) { int id; res = NetCDF.nc_inq_dimid(dataSet.NcId, dims[i], out id); if (res == (int)NetCDF.ResultCode.NC_NOERR) { dimids[i] = id; } else if (res == (int)NetCDF.ResultCode.NC_EBADDIM) { // Creating new dimension res = NetCDF.nc_def_dim(dataSet.NcId, dims[i], new IntPtr(NetCDF.NC_UNLIMITED), out id); NetCDFDataSet.HandleResult(res); dimids[i] = id; } else { NetCDFDataSet.HandleResult(res); } } /* Creating variable */ int varid; string nc_name = GetNetCDFName(name); if (nc_name != name) { Debug.WriteLineIf(NetCDFDataSet.TraceNetCDFDataSet.TraceVerbose, "NetCDF: name has illegal chars; internal variable name is " + nc_name); } res = NetCDF.nc_def_var(dataSet.NcId, nc_name, NetCDF.GetNcType(typeof(DataType)), dimids.Length, dimids, out varid); for (int count = 1; res == (int)NetCDF.ResultCode.NC_ENAMEINUSE;) { // Keep trying to create variable with different names res = NetCDF.nc_def_var(dataSet.NcId, String.Format("{0}_{1}", nc_name, count++), NetCDF.GetNcType(typeof(DataType)), dimids.Length, dimids, out varid); } NetCDFDataSet.HandleResult(res); // Non scalar variables can be compressed. // It is regulated by the uri parameter "deflate". if (dims.Length > 0) { if (dataSet.Deflate == DeflateLevel.Off) { res = NetCDF.nc_def_var_deflate(dataSet.NcId, varid, 0, 0, 0); } else { res = NetCDF.nc_def_var_deflate(dataSet.NcId, varid, 0, 1, (int)dataSet.Deflate); } NetCDFDataSet.HandleResult(res); } if (dims.Length > 0) { IntPtr[] chunksizes = new IntPtr[dims.Length]; //int chunk = Math.Min(1000, 100000 / Pow10(dims.Length - 1)); int chunk; switch (dims.Length) { case 1: chunk = 1000000; break; case 2: chunk = 1000; break; case 3: chunk = 100; break; default: chunk = 10; break; } if (dims.Length >= 6) { chunk = 5; } else if (dims.Length >= 9) // found experimentally { chunk = 1; } //StringBuilder sbChunk = new StringBuilder(); //sbChunk.Append("Chunk sizes for rank ").Append(dims.Length).Append(": "); for (int i = 0; i < dims.Length; i++) { //sbChunk.Append(chunk).Append(","); chunksizes[i] = new IntPtr(chunk); // TODO: need for an algorithm of chunk size selection } //Debug.WriteLine(sbChunk.ToString()); res = NetCDF.nc_def_var_chunking(dataSet.NcId, varid, 0, chunksizes); NetCDFDataSet.HandleResult(res); } if (typeof(DataType) == typeof(DateTime)) { NetCDFDataSet.NcPutAttText(dataSet.NcId, varid, "Units", NetCDFDataSet.dateTimeUnits); } else if (typeof(DataType) == typeof(bool)) { NetCDFDataSet.NcPutAttText(dataSet.NcId, varid, AttributeTypeMap.AttributeVarSpecialType, typeof(bool).ToString()); } return(new NetCdfVariable <DataType>(dataSet, varid, name, dims)); }