Ejemplo n.º 1
0
        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));
        }